Exercise new taskq interface in splat-taskq tests

The splat-taskq test functions were slightly modified to exercise
the new taskq interface in addition to the old interface.  If the
old interface passes each of its tests, the new interface is
exercised.  Both sub tests (old interface and new interface) must
pass for each test as a whole to pass.

Signed-off-by: Prakash Surya <surya1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #65
This commit is contained in:
Prakash Surya 2011-12-06 10:11:36 -08:00 committed by Brian Behlendorf
parent 44217f7aad
commit 699d5ee8a9

View File

@ -67,6 +67,7 @@ typedef struct splat_taskq_arg {
int order[SPLAT_TASKQ_ORDER_MAX]; int order[SPLAT_TASKQ_ORDER_MAX];
unsigned int depth; unsigned int depth;
taskq_t *tq; taskq_t *tq;
taskq_ent_t *tqe;
spinlock_t lock; spinlock_t lock;
struct file *file; struct file *file;
const char *name; const char *name;
@ -94,14 +95,19 @@ splat_taskq_test13_func(void *arg)
} }
static int static int
splat_taskq_test1(struct file *file, void *arg) splat_taskq_test1_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
taskq_t *tq; taskq_t *tq;
taskqid_t id; taskqid_t id;
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
taskq_ent_t tqe;
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' creating\n", taskq_init_ent(&tqe);
SPLAT_TASKQ_TEST1_NAME);
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' creating (%s dispatch)\n",
SPLAT_TASKQ_TEST1_NAME,
prealloc ? "prealloc" : "dynamic");
if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, maxclsyspri, if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, maxclsyspri,
50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
@ -118,11 +124,19 @@ 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_test13_func)); tq_arg.name, sym2str(splat_taskq_test13_func));
if ((id = taskq_dispatch(tq, splat_taskq_test13_func, if (prealloc) {
&tq_arg, TQ_SLEEP)) == 0) { taskq_dispatch_ent(tq, splat_taskq_test13_func,
&tq_arg, TQ_SLEEP, &tqe);
id = tqe.tqent_id;
} else {
id = taskq_dispatch(tq, splat_taskq_test13_func,
&tq_arg, TQ_SLEEP);
}
if (id == 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_test13_func)); tq_arg.name, sym2str(splat_taskq_test13_func));
taskq_destroy(tq); taskq_destroy(tq);
return -EINVAL; return -EINVAL;
} }
@ -132,11 +146,26 @@ splat_taskq_test1(struct file *file, void *arg)
taskq_wait(tq); taskq_wait(tq);
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' destroying\n", splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' destroying\n",
tq_arg.name); tq_arg.name);
taskq_destroy(tq); taskq_destroy(tq);
return (tq_arg.flag) ? 0 : -EINVAL; return (tq_arg.flag) ? 0 : -EINVAL;
} }
static int
splat_taskq_test1(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test1_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test1_impl(file, arg, B_TRUE);
return rc;
}
/* /*
* Create multiple taskq's, each with multiple tasks, wait until * Create multiple taskq's, each with multiple tasks, wait until
* all tasks complete, ensure all tasks ran properly and in the * all tasks complete, ensure all tasks ran properly and in the
@ -175,16 +204,34 @@ splat_taskq_test2_func2(void *arg)
#define TEST2_THREADS_PER_TASKQ 1 #define TEST2_THREADS_PER_TASKQ 1
static int static int
splat_taskq_test2(struct file *file, void *arg) { splat_taskq_test2_impl(struct file *file, void *arg, boolean_t prealloc) {
taskq_t *tq[TEST2_TASKQS] = { NULL }; taskq_t *tq[TEST2_TASKQS] = { NULL };
taskqid_t id; taskqid_t id;
splat_taskq_arg_t tq_args[TEST2_TASKQS]; splat_taskq_arg_t tq_args[TEST2_TASKQS];
taskq_ent_t *func1_tqes = NULL;
taskq_ent_t *func2_tqes = NULL;
int i, rc = 0; int i, rc = 0;
for (i = 0; i < TEST2_TASKQS; i++) { func1_tqes = kmalloc(sizeof(*func1_tqes) * TEST2_TASKQS, GFP_KERNEL);
if (func1_tqes == NULL) {
rc = -ENOMEM;
goto out;
}
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq '%s/%d' " func2_tqes = kmalloc(sizeof(*func2_tqes) * TEST2_TASKQS, GFP_KERNEL);
"creating\n", SPLAT_TASKQ_TEST2_NAME, i); if (func2_tqes == NULL) {
rc = -ENOMEM;
goto out;
}
for (i = 0; i < TEST2_TASKQS; i++) {
taskq_init_ent(&func1_tqes[i]);
taskq_init_ent(&func2_tqes[i]);
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' creating (%s dispatch)\n",
SPLAT_TASKQ_TEST2_NAME, i,
prealloc ? "prealloc" : "dynamic");
if ((tq[i] = taskq_create(SPLAT_TASKQ_TEST2_NAME, if ((tq[i] = taskq_create(SPLAT_TASKQ_TEST2_NAME,
TEST2_THREADS_PER_TASKQ, TEST2_THREADS_PER_TASKQ,
maxclsyspri, 50, INT_MAX, maxclsyspri, 50, INT_MAX,
@ -205,9 +252,16 @@ splat_taskq_test2(struct file *file, void *arg) {
"Taskq '%s/%d' function '%s' dispatching\n", "Taskq '%s/%d' function '%s' dispatching\n",
tq_args[i].name, tq_args[i].id, tq_args[i].name, tq_args[i].id,
sym2str(splat_taskq_test2_func1)); sym2str(splat_taskq_test2_func1));
if ((id = taskq_dispatch( if (prealloc) {
tq[i], splat_taskq_test2_func1, taskq_dispatch_ent(tq[i], splat_taskq_test2_func1,
&tq_args[i], TQ_SLEEP)) == 0) { &tq_args[i], TQ_SLEEP, &func1_tqes[i]);
id = func1_tqes[i].tqent_id;
} else {
id = taskq_dispatch(tq[i], splat_taskq_test2_func1,
&tq_args[i], TQ_SLEEP);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatch " "Taskq '%s/%d' function '%s' dispatch "
"failed\n", tq_args[i].name, tq_args[i].id, "failed\n", tq_args[i].name, tq_args[i].id,
@ -220,13 +274,20 @@ splat_taskq_test2(struct file *file, void *arg) {
"Taskq '%s/%d' function '%s' dispatching\n", "Taskq '%s/%d' function '%s' dispatching\n",
tq_args[i].name, tq_args[i].id, tq_args[i].name, tq_args[i].id,
sym2str(splat_taskq_test2_func2)); sym2str(splat_taskq_test2_func2));
if ((id = taskq_dispatch( if (prealloc) {
tq[i], splat_taskq_test2_func2, taskq_dispatch_ent(tq[i], splat_taskq_test2_func2,
&tq_args[i], TQ_SLEEP)) == 0) { &tq_args[i], TQ_SLEEP, &func2_tqes[i]);
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, id = func2_tqes[i].tqent_id;
"Taskq '%s/%d' function '%s' dispatch failed\n", } else {
tq_args[i].name, tq_args[i].id, id = taskq_dispatch(tq[i], splat_taskq_test2_func2,
sym2str(splat_taskq_test2_func2)); &tq_args[i], TQ_SLEEP);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq "
"'%s/%d' function '%s' dispatch failed\n",
tq_args[i].name, tq_args[i].id,
sym2str(splat_taskq_test2_func2));
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@ -243,6 +304,7 @@ splat_taskq_test2(struct file *file, void *arg) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d; destroying\n", "Taskq '%s/%d; destroying\n",
tq_args[i].name, tq_args[i].id); tq_args[i].name, tq_args[i].id);
taskq_destroy(tq[i]); taskq_destroy(tq[i]);
if (!rc && tq_args[i].flag != ((i * 2) + 1)) { if (!rc && tq_args[i].flag != ((i * 2) + 1)) {
@ -261,6 +323,25 @@ splat_taskq_test2(struct file *file, void *arg) {
} }
} }
} }
out:
if (func1_tqes)
kfree(func1_tqes);
if (func2_tqes)
kfree(func2_tqes);
return rc;
}
static int
splat_taskq_test2(struct file *file, void *arg) {
int rc;
rc = splat_taskq_test2_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test2_impl(file, arg, B_TRUE);
return rc; return rc;
} }
@ -270,10 +351,13 @@ splat_taskq_test2(struct file *file, void *arg) {
* completes, ensure task ran properly. * completes, ensure task ran properly.
*/ */
static int static int
splat_taskq_test3(struct file *file, void *arg) splat_taskq_test3_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
taskqid_t id; taskqid_t id;
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
taskq_ent_t tqe;
taskq_init_ent(&tqe);
tq_arg.flag = 0; tq_arg.flag = 0;
tq_arg.id = 0; tq_arg.id = 0;
@ -281,10 +365,19 @@ splat_taskq_test3(struct file *file, void *arg)
tq_arg.name = SPLAT_TASKQ_TEST3_NAME; tq_arg.name = SPLAT_TASKQ_TEST3_NAME;
splat_vprint(file, SPLAT_TASKQ_TEST3_NAME, splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
"Taskq '%s' function '%s' dispatching\n", "Taskq '%s' function '%s' %s dispatch\n",
tq_arg.name, sym2str(splat_taskq_test13_func)); tq_arg.name, sym2str(splat_taskq_test13_func),
if ((id = taskq_dispatch(system_taskq, splat_taskq_test13_func, prealloc ? "prealloc" : "dynamic");
&tq_arg, TQ_SLEEP)) == 0) { if (prealloc) {
taskq_dispatch_ent(system_taskq, splat_taskq_test13_func,
&tq_arg, TQ_SLEEP, &tqe);
id = tqe.tqent_id;
} else {
id = taskq_dispatch(system_taskq, splat_taskq_test13_func,
&tq_arg, TQ_SLEEP);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST3_NAME, splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test13_func)); tq_arg.name, sym2str(splat_taskq_test13_func));
@ -298,6 +391,20 @@ splat_taskq_test3(struct file *file, void *arg)
return (tq_arg.flag) ? 0 : -EINVAL; return (tq_arg.flag) ? 0 : -EINVAL;
} }
static int
splat_taskq_test3(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test3_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test3_impl(file, arg, B_TRUE);
return rc;
}
/* /*
* Create a taskq and dispatch a large number of tasks to the queue. * Create a taskq and dispatch a large number of tasks to the queue.
* Then use taskq_wait() to block until all the tasks complete, then * Then use taskq_wait() to block until all the tasks complete, then
@ -319,21 +426,30 @@ splat_taskq_test4_func(void *arg)
static int static int
splat_taskq_test4_common(struct file *file, void *arg, int minalloc, splat_taskq_test4_common(struct file *file, void *arg, int minalloc,
int maxalloc, int nr_tasks) int maxalloc, int nr_tasks, boolean_t prealloc)
{ {
taskq_t *tq; taskq_t *tq;
taskqid_t id;
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
taskq_ent_t *tqes;
int i, j, rc = 0; int i, j, rc = 0;
splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, "Taskq '%s' creating " tqes = kmalloc(sizeof(*tqes) * nr_tasks, GFP_KERNEL);
"(%d/%d/%d)\n", SPLAT_TASKQ_TEST4_NAME, minalloc, maxalloc, if (tqes == NULL)
nr_tasks); return -ENOMEM;
splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
"Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n",
SPLAT_TASKQ_TEST4_NAME,
prealloc ? "prealloc" : "dynamic",
minalloc, maxalloc, nr_tasks);
if ((tq = taskq_create(SPLAT_TASKQ_TEST4_NAME, 1, maxclsyspri, if ((tq = taskq_create(SPLAT_TASKQ_TEST4_NAME, 1, maxclsyspri,
minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) { minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
"Taskq '%s' create failed\n", "Taskq '%s' create failed\n",
SPLAT_TASKQ_TEST4_NAME); SPLAT_TASKQ_TEST4_NAME);
return -EINVAL; rc = -EINVAL;
goto out_free;
} }
tq_arg.file = file; tq_arg.file = file;
@ -346,8 +462,18 @@ splat_taskq_test4_common(struct file *file, void *arg, int minalloc,
tq_arg.name, sym2str(splat_taskq_test4_func), i); tq_arg.name, sym2str(splat_taskq_test4_func), i);
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
if ((taskq_dispatch(tq, splat_taskq_test4_func, taskq_init_ent(&tqes[j]);
&tq_arg, TQ_SLEEP)) == 0) {
if (prealloc) {
taskq_dispatch_ent(tq, splat_taskq_test4_func,
&tq_arg, TQ_SLEEP, &tqes[j]);
id = tqes[j].tqent_id;
} else {
id = taskq_dispatch(tq, splat_taskq_test4_func,
&tq_arg, TQ_SLEEP);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
"Taskq '%s' function '%s' dispatch " "Taskq '%s' function '%s' dispatch "
"%d failed\n", tq_arg.name, "%d failed\n", tq_arg.name,
@ -374,18 +500,36 @@ out:
tq_arg.name); tq_arg.name);
taskq_destroy(tq); taskq_destroy(tq);
out_free:
kfree(tqes);
return rc; return rc;
} }
static int splat_taskq_test4(struct file *file, void *arg) static int
splat_taskq_test4_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
int rc; int rc;
rc = splat_taskq_test4_common(file, arg, 50, INT_MAX, 1024); rc = splat_taskq_test4_common(file, arg, 50, INT_MAX, 1024, prealloc);
if (rc) if (rc)
return rc; return rc;
rc = splat_taskq_test4_common(file, arg, 1, 1, 32); rc = splat_taskq_test4_common(file, arg, 1, 1, 32, prealloc);
return rc;
}
static int
splat_taskq_test4(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test4_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test4_impl(file, arg, B_TRUE);
return rc; return rc;
} }
@ -498,7 +642,7 @@ splat_taskq_test_order(splat_taskq_arg_t *tq_arg, int *order)
} }
static int static int
splat_taskq_test5(struct file *file, void *arg) splat_taskq_test5_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
taskq_t *tq; taskq_t *tq;
taskqid_t id; taskqid_t id;
@ -506,10 +650,13 @@ splat_taskq_test5(struct file *file, void *arg)
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
int order1[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,0,0,0 }; int order1[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,0,0,0 };
int order2[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,8,6,7 }; int order2[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,8,6,7 };
taskq_ent_t tqes[SPLAT_TASKQ_ORDER_MAX];
int i, rc = 0; int i, rc = 0;
splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' creating\n", splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
SPLAT_TASKQ_TEST5_NAME); "Taskq '%s' creating (%s dispatch)\n",
SPLAT_TASKQ_TEST5_NAME,
prealloc ? "prealloc" : "dynamic");
if ((tq = taskq_create(SPLAT_TASKQ_TEST5_NAME, 3, maxclsyspri, if ((tq = taskq_create(SPLAT_TASKQ_TEST5_NAME, 3, maxclsyspri,
50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
@ -525,11 +672,21 @@ splat_taskq_test5(struct file *file, void *arg)
tq_arg.name = SPLAT_TASKQ_TEST5_NAME; tq_arg.name = SPLAT_TASKQ_TEST5_NAME;
for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) { for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
taskq_init_ent(&tqes[i]);
tq_id[i].id = i + 1; tq_id[i].id = i + 1;
tq_id[i].arg = &tq_arg; tq_id[i].arg = &tq_arg;
if ((id = taskq_dispatch(tq, splat_taskq_test5_func, if (prealloc) {
&tq_id[i], TQ_SLEEP)) == 0) { taskq_dispatch_ent(tq, splat_taskq_test5_func,
&tq_id[i], TQ_SLEEP, &tqes[i]);
id = tqes[i].tqent_id;
} else {
id = taskq_dispatch(tq, splat_taskq_test5_func,
&tq_id[i], TQ_SLEEP);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test5_func)); tq_arg.name, sym2str(splat_taskq_test5_func));
@ -565,6 +722,20 @@ out:
return rc; return rc;
} }
static int
splat_taskq_test5(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test5_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test5_impl(file, arg, B_TRUE);
return rc;
}
/* /*
* Create a single task queue with three threads. Dispatch 8 tasks, * Create a single task queue with three threads. Dispatch 8 tasks,
* setting TQ_FRONT on only the last three. Sleep after * setting TQ_FRONT on only the last three. Sleep after
@ -624,18 +795,21 @@ splat_taskq_test6_func(void *arg)
} }
static int static int
splat_taskq_test6(struct file *file, void *arg) splat_taskq_test6_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
taskq_t *tq; taskq_t *tq;
taskqid_t id; taskqid_t id;
splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX]; splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX];
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
int order[SPLAT_TASKQ_ORDER_MAX] = { 1,2,3,6,7,8,4,5 }; int order[SPLAT_TASKQ_ORDER_MAX] = { 1,2,3,6,7,8,4,5 };
taskq_ent_t tqes[SPLAT_TASKQ_ORDER_MAX];
int i, rc = 0; int i, rc = 0;
uint_t tflags; uint_t tflags;
splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, "Taskq '%s' creating\n", splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
SPLAT_TASKQ_TEST6_NAME); "Taskq '%s' creating (%s dispatch)\n",
SPLAT_TASKQ_TEST6_NAME,
prealloc ? "prealloc" : "dynamic");
if ((tq = taskq_create(SPLAT_TASKQ_TEST6_NAME, 3, maxclsyspri, if ((tq = taskq_create(SPLAT_TASKQ_TEST6_NAME, 3, maxclsyspri,
50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
@ -651,14 +825,24 @@ splat_taskq_test6(struct file *file, void *arg)
tq_arg.name = SPLAT_TASKQ_TEST6_NAME; tq_arg.name = SPLAT_TASKQ_TEST6_NAME;
for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) { for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
taskq_init_ent(&tqes[i]);
tq_id[i].id = i + 1; tq_id[i].id = i + 1;
tq_id[i].arg = &tq_arg; tq_id[i].arg = &tq_arg;
tflags = TQ_SLEEP; tflags = TQ_SLEEP;
if (i > 4) if (i > 4)
tflags |= TQ_FRONT; tflags |= TQ_FRONT;
if ((id = taskq_dispatch(tq, splat_taskq_test6_func, if (prealloc) {
&tq_id[i], tflags)) == 0) { taskq_dispatch_ent(tq, splat_taskq_test6_func,
&tq_id[i], tflags, &tqes[i]);
id = tqes[i].tqent_id;
} else {
id = taskq_dispatch(tq, splat_taskq_test6_func,
&tq_id[i], tflags);
}
if (id == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
"Taskq '%s' function '%s' dispatch failed\n", "Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(splat_taskq_test6_func)); tq_arg.name, sym2str(splat_taskq_test6_func));
@ -692,6 +876,20 @@ out:
return rc; return rc;
} }
static int
splat_taskq_test6(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test6_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test6_impl(file, arg, B_TRUE);
return rc;
}
static void static void
splat_taskq_test7_func(void *arg) splat_taskq_test7_func(void *arg)
{ {
@ -710,8 +908,17 @@ splat_taskq_test7_func(void *arg)
tq_arg->name, sym2str(splat_taskq_test7_func), tq_arg->name, sym2str(splat_taskq_test7_func),
tq_arg->depth); tq_arg->depth);
if ((id = taskq_dispatch(tq_arg->tq, splat_taskq_test7_func, if (tq_arg->tqe) {
tq_arg, TQ_SLEEP)) == 0) { VERIFY(taskq_empty_ent(tq_arg->tqe));
taskq_dispatch_ent(tq_arg->tq, splat_taskq_test7_func,
tq_arg, TQ_SLEEP, tq_arg->tqe);
id = tq_arg->tqe->tqent_id;
} else {
id = taskq_dispatch(tq_arg->tq, splat_taskq_test7_func,
tq_arg, TQ_SLEEP);
}
if (id == 0) {
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME, splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME,
"Taskq '%s' function '%s' dispatch failed " "Taskq '%s' function '%s' dispatch failed "
"(depth = %u)\n", tq_arg->name, "(depth = %u)\n", tq_arg->name,
@ -722,13 +929,16 @@ splat_taskq_test7_func(void *arg)
} }
static int static int
splat_taskq_test7(struct file *file, void *arg) splat_taskq_test7_impl(struct file *file, void *arg, boolean_t prealloc)
{ {
taskq_t *tq; taskq_t *tq;
taskq_ent_t tqe;
splat_taskq_arg_t tq_arg; splat_taskq_arg_t tq_arg;
splat_vprint(file, SPLAT_TASKQ_TEST7_NAME, splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
"Taskq '%s' creating\n", SPLAT_TASKQ_TEST7_NAME); "Taskq '%s' creating (%s dispatch)\n",
SPLAT_TASKQ_TEST7_NAME,
prealloc ? "prealloc" : "dynamic");
if ((tq = taskq_create(SPLAT_TASKQ_TEST7_NAME, 1, maxclsyspri, if ((tq = taskq_create(SPLAT_TASKQ_TEST7_NAME, 1, maxclsyspri,
50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST7_NAME, splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
@ -744,6 +954,13 @@ splat_taskq_test7(struct file *file, void *arg)
tq_arg.name = SPLAT_TASKQ_TEST7_NAME; tq_arg.name = SPLAT_TASKQ_TEST7_NAME;
tq_arg.tq = tq; tq_arg.tq = tq;
if (prealloc) {
taskq_init_ent(&tqe);
tq_arg.tqe = &tqe;
} else {
tq_arg.tqe = NULL;
}
splat_taskq_test7_func(&tq_arg); splat_taskq_test7_func(&tq_arg);
if (tq_arg.flag == 0) { if (tq_arg.flag == 0) {
@ -759,6 +976,20 @@ splat_taskq_test7(struct file *file, void *arg)
return tq_arg.depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL; return tq_arg.depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL;
} }
static int
splat_taskq_test7(struct file *file, void *arg)
{
int rc;
rc = splat_taskq_test7_impl(file, arg, B_FALSE);
if (rc)
return rc;
rc = splat_taskq_test7_impl(file, arg, B_TRUE);
return rc;
}
splat_subsystem_t * splat_subsystem_t *
splat_taskq_init(void) splat_taskq_init(void)
{ {