]> git.proxmox.com Git - mirror_spl.git/commitdiff
Add system taskq support
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 5 Jan 2009 23:08:03 +0000 (15:08 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 5 Jan 2009 23:08:03 +0000 (15:08 -0800)
include/sys/taskq.h
modules/spl/spl-generic.c
modules/spl/spl-taskq.c
modules/splat/splat-taskq.c

index 7a0be048cacae04a3f6a64534a600c2b3d457213..0e78ea1233eb869904f52e83519ed6e07ff14c9c 100644 (file)
@@ -81,12 +81,18 @@ typedef struct taskq {
        wait_queue_head_t       tq_wait_waitq; /* wait waitq */
 } taskq_t;
 
+/* Global system-wide dynamic task queue available for all consumers */
+extern taskq_t *system_taskq;
+
 extern taskqid_t __taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
 extern taskq_t *__taskq_create(const char *, int, pri_t, int, int, uint_t);
 extern void __taskq_destroy(taskq_t *);
 extern void __taskq_wait(taskq_t *);
 extern int __taskq_member(taskq_t *, void *);
 
+int spl_taskq_init(void);
+void spl_taskq_fini(void);
+
 #define taskq_member(tq, t)                __taskq_member(tq, t)
 #define taskq_wait_id(tq, id)              __taskq_wait_id(tq, id)
 #define taskq_wait(tq)                     __taskq_wait(tq)
index 58b5951700516e747636f1bb64d9b3ebb10c37cc..d361bff92b099cf7c4dee8a8e83d3a7d8a2ee942 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/vnode.h>
 #include <sys/kmem.h>
 #include <sys/mutex.h>
+#include <sys/taskq.h>
 #include <sys/debug.h>
 #include <sys/proc.h>
 #include <sys/kstat.h>
@@ -225,26 +226,31 @@ static int __init spl_init(void)
        if ((rc = spl_mutex_init()))
                GOTO(out2 , rc);
 
-       if ((rc = vn_init()))
+       if ((rc = spl_taskq_init()))
                GOTO(out3, rc);
 
-       if ((rc = proc_init()))
+       if ((rc = vn_init()))
                GOTO(out4, rc);
 
-       if ((rc = kstat_init()))
+       if ((rc = proc_init()))
                GOTO(out5, rc);
 
+       if ((rc = kstat_init()))
+               GOTO(out6, rc);
+
        if ((rc = set_hostid()))
-               GOTO(out6, rc = -EADDRNOTAVAIL);
+               GOTO(out7, rc = -EADDRNOTAVAIL);
 
        printk("SPL: Loaded Solaris Porting Layer v%s\n", VERSION);
        RETURN(rc);
-out6:
+out7:
        kstat_fini();
-out5:
+out6:
        proc_fini();
-out4:
+out5:
        vn_fini();
+out4:
+       spl_taskq_fini();
 out3:
        spl_mutex_fini();
 out2:
@@ -265,6 +271,7 @@ static void spl_fini(void)
        kstat_fini();
        proc_fini();
        vn_fini();
+       spl_taskq_fini();
        spl_mutex_fini();
        spl_kmem_fini();
        debug_fini();
index 3c7f43cda592ca4d7a4e4135aec4b4146618ca96..dc6959db555f2e03724b3feac060517cc853f2bc 100644 (file)
 
 #define DEBUG_SUBSYSTEM S_TASKQ
 
+/* Global system-wide dynamic task queue available for all consumers */
+taskq_t *system_taskq;
+EXPORT_SYMBOL(system_taskq);
+
 typedef struct spl_task {
         spinlock_t              t_lock;
         struct list_head        t_list;
@@ -464,3 +468,24 @@ __taskq_destroy(taskq_t *tq)
        EXIT;
 }
 EXPORT_SYMBOL(__taskq_destroy);
+
+int
+spl_taskq_init(void)
+{
+        ENTRY;
+
+        system_taskq = taskq_create("system_taskq", 64, minclsyspri, 4, 512,
+                                    TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
+       if (system_taskq == NULL)
+               RETURN(1);
+
+        RETURN(0);
+}
+
+void
+spl_taskq_fini(void)
+{
+        ENTRY;
+       taskq_destroy(system_taskq);
+        EXIT;
+}
index 4d349f0712f22d9d89453cc3c03a616ba1256eeb..3cc09bcb97d35bb01bc9cbc60a8c1e14f8fee721 100644 (file)
 #define SPLAT_TASKQ_TEST2_NAME         "multiple"
 #define SPLAT_TASKQ_TEST2_DESC         "Multiple task queues, multiple tasks"
 
+#define SPLAT_TASKQ_TEST3_ID            0x0203
+#define SPLAT_TASKQ_TEST3_NAME         "system"
+#define SPLAT_TASKQ_TEST3_DESC         "System task queue, multiple tasks"
+
 typedef struct splat_taskq_arg {
        int flag;
        int id;
@@ -49,14 +53,14 @@ typedef struct splat_taskq_arg {
  * task completes, ensure task ran properly, cleanup taskq,
  */
 static void
-splat_taskq_test1_func(void *arg)
+splat_taskq_test13_func(void *arg)
 {
        splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
 
        ASSERT(tq_arg);
        splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST1_NAME,
                   "Taskq '%s' function '%s' setting flag\n",
-                  tq_arg->name, sym2str(splat_taskq_test1_func));
+                  tq_arg->name, sym2str(splat_taskq_test13_func));
        tq_arg->flag = 1;
 }
 
@@ -84,12 +88,12 @@ splat_taskq_test1(struct file *file, void *arg)
 
        splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
                   "Taskq '%s' function '%s' dispatching\n",
-                  tq_arg.name, sym2str(splat_taskq_test1_func));
-       if ((id = taskq_dispatch(tq, splat_taskq_test1_func,
+                  tq_arg.name, sym2str(splat_taskq_test13_func));
+       if ((id = taskq_dispatch(tq, splat_taskq_test13_func,
                                 &tq_arg, TQ_SLEEP)) == 0) {
                splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
                           "Taskq '%s' function '%s' dispatch failed\n",
-                          tq_arg.name, sym2str(splat_taskq_test1_func));
+                          tq_arg.name, sym2str(splat_taskq_test13_func));
                taskq_destroy(tq);
                return -EINVAL;
        }
@@ -230,6 +234,38 @@ splat_taskq_test2(struct file *file, void *arg) {
        return rc;
 }
 
+/* Validation Test 3 - Use the global system task queue with a single
+ * task, * wait until task completes, ensure task ran properly.
+ */
+static int
+splat_taskq_test3(struct file *file, void *arg)
+{
+       taskqid_t id;
+       splat_taskq_arg_t tq_arg;
+
+       tq_arg.flag = 0;
+       tq_arg.id   = 0;
+       tq_arg.file = file;
+       tq_arg.name = SPLAT_TASKQ_TEST3_NAME;
+
+       splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
+                  "Taskq '%s' function '%s' dispatching\n",
+                  tq_arg.name, sym2str(splat_taskq_test13_func));
+       if ((id = taskq_dispatch(system_taskq, splat_taskq_test13_func,
+                                &tq_arg, TQ_SLEEP)) == 0) {
+               splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
+                          "Taskq '%s' function '%s' dispatch failed\n",
+                          tq_arg.name, sym2str(splat_taskq_test13_func));
+               return -EINVAL;
+       }
+
+       splat_vprint(file, SPLAT_TASKQ_TEST3_NAME, "Taskq '%s' waiting\n",
+                  tq_arg.name);
+       taskq_wait(system_taskq);
+
+       return (tq_arg.flag) ? 0 : -EINVAL;
+}
+
 splat_subsystem_t *
 splat_taskq_init(void)
 {
@@ -251,6 +287,8 @@ splat_taskq_init(void)
                      SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
        SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
                      SPLAT_TASKQ_TEST2_ID, splat_taskq_test2);
+       SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST3_NAME, SPLAT_TASKQ_TEST3_DESC,
+                     SPLAT_TASKQ_TEST3_ID, splat_taskq_test3);
 
         return sub;
 }
@@ -259,6 +297,7 @@ void
 splat_taskq_fini(splat_subsystem_t *sub)
 {
         ASSERT(sub);
+       SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST3_ID);
        SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST2_ID);
        SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID);