Add system taskq support
This commit is contained in:
parent
8a2b328b18
commit
e9cb2b4f64
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
#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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue