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 */
|
wait_queue_head_t tq_wait_waitq; /* wait waitq */
|
||||||
} taskq_t;
|
} 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 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 taskq_t *__taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||||
extern void __taskq_destroy(taskq_t *);
|
extern void __taskq_destroy(taskq_t *);
|
||||||
extern void __taskq_wait(taskq_t *);
|
extern void __taskq_wait(taskq_t *);
|
||||||
extern int __taskq_member(taskq_t *, void *);
|
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_member(tq, t) __taskq_member(tq, t)
|
||||||
#define taskq_wait_id(tq, id) __taskq_wait_id(tq, id)
|
#define taskq_wait_id(tq, id) __taskq_wait_id(tq, id)
|
||||||
#define taskq_wait(tq) __taskq_wait(tq)
|
#define taskq_wait(tq) __taskq_wait(tq)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/taskq.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/kstat.h>
|
#include <sys/kstat.h>
|
||||||
|
@ -225,26 +226,31 @@ static int __init spl_init(void)
|
||||||
if ((rc = spl_mutex_init()))
|
if ((rc = spl_mutex_init()))
|
||||||
GOTO(out2 , rc);
|
GOTO(out2 , rc);
|
||||||
|
|
||||||
if ((rc = vn_init()))
|
if ((rc = spl_taskq_init()))
|
||||||
GOTO(out3, rc);
|
GOTO(out3, rc);
|
||||||
|
|
||||||
if ((rc = proc_init()))
|
if ((rc = vn_init()))
|
||||||
GOTO(out4, rc);
|
GOTO(out4, rc);
|
||||||
|
|
||||||
if ((rc = kstat_init()))
|
if ((rc = proc_init()))
|
||||||
GOTO(out5, rc);
|
GOTO(out5, rc);
|
||||||
|
|
||||||
|
if ((rc = kstat_init()))
|
||||||
|
GOTO(out6, rc);
|
||||||
|
|
||||||
if ((rc = set_hostid()))
|
if ((rc = set_hostid()))
|
||||||
GOTO(out6, rc = -EADDRNOTAVAIL);
|
GOTO(out7, rc = -EADDRNOTAVAIL);
|
||||||
|
|
||||||
printk("SPL: Loaded Solaris Porting Layer v%s\n", VERSION);
|
printk("SPL: Loaded Solaris Porting Layer v%s\n", VERSION);
|
||||||
RETURN(rc);
|
RETURN(rc);
|
||||||
out6:
|
out7:
|
||||||
kstat_fini();
|
kstat_fini();
|
||||||
out5:
|
out6:
|
||||||
proc_fini();
|
proc_fini();
|
||||||
out4:
|
out5:
|
||||||
vn_fini();
|
vn_fini();
|
||||||
|
out4:
|
||||||
|
spl_taskq_fini();
|
||||||
out3:
|
out3:
|
||||||
spl_mutex_fini();
|
spl_mutex_fini();
|
||||||
out2:
|
out2:
|
||||||
|
@ -265,6 +271,7 @@ static void spl_fini(void)
|
||||||
kstat_fini();
|
kstat_fini();
|
||||||
proc_fini();
|
proc_fini();
|
||||||
vn_fini();
|
vn_fini();
|
||||||
|
spl_taskq_fini();
|
||||||
spl_mutex_fini();
|
spl_mutex_fini();
|
||||||
spl_kmem_fini();
|
spl_kmem_fini();
|
||||||
debug_fini();
|
debug_fini();
|
||||||
|
|
|
@ -33,6 +33,10 @@
|
||||||
|
|
||||||
#define DEBUG_SUBSYSTEM S_TASKQ
|
#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 {
|
typedef struct spl_task {
|
||||||
spinlock_t t_lock;
|
spinlock_t t_lock;
|
||||||
struct list_head t_list;
|
struct list_head t_list;
|
||||||
|
@ -464,3 +468,24 @@ __taskq_destroy(taskq_t *tq)
|
||||||
EXIT;
|
EXIT;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__taskq_destroy);
|
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_NAME "multiple"
|
||||||
#define SPLAT_TASKQ_TEST2_DESC "Multiple task queues, multiple tasks"
|
#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 {
|
typedef struct splat_taskq_arg {
|
||||||
int flag;
|
int flag;
|
||||||
int id;
|
int id;
|
||||||
|
@ -49,14 +53,14 @@ typedef struct splat_taskq_arg {
|
||||||
* task completes, ensure task ran properly, cleanup taskq,
|
* task completes, ensure task ran properly, cleanup taskq,
|
||||||
*/
|
*/
|
||||||
static void
|
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;
|
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
|
||||||
|
|
||||||
ASSERT(tq_arg);
|
ASSERT(tq_arg);
|
||||||
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST1_NAME,
|
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST1_NAME,
|
||||||
"Taskq '%s' function '%s' setting flag\n",
|
"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;
|
tq_arg->flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +88,12 @@ splat_taskq_test1(struct file *file, void *arg)
|
||||||
|
|
||||||
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
|
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
|
||||||
"Taskq '%s' function '%s' dispatching\n",
|
"Taskq '%s' function '%s' dispatching\n",
|
||||||
tq_arg.name, sym2str(splat_taskq_test1_func));
|
tq_arg.name, sym2str(splat_taskq_test13_func));
|
||||||
if ((id = taskq_dispatch(tq, splat_taskq_test1_func,
|
if ((id = taskq_dispatch(tq, splat_taskq_test13_func,
|
||||||
&tq_arg, TQ_SLEEP)) == 0) {
|
&tq_arg, TQ_SLEEP)) == 0) {
|
||||||
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
|
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
|
||||||
"Taskq '%s' function '%s' dispatch failed\n",
|
"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);
|
taskq_destroy(tq);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +234,38 @@ splat_taskq_test2(struct file *file, void *arg) {
|
||||||
return rc;
|
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_subsystem_t *
|
||||||
splat_taskq_init(void)
|
splat_taskq_init(void)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +287,8 @@ splat_taskq_init(void)
|
||||||
SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
|
SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
|
||||||
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
|
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
|
||||||
SPLAT_TASKQ_TEST2_ID, splat_taskq_test2);
|
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;
|
return sub;
|
||||||
}
|
}
|
||||||
|
@ -259,6 +297,7 @@ void
|
||||||
splat_taskq_fini(splat_subsystem_t *sub)
|
splat_taskq_fini(splat_subsystem_t *sub)
|
||||||
{
|
{
|
||||||
ASSERT(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_TEST2_ID);
|
||||||
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID);
|
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue