mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 11:40:25 +03:00
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:
parent
44217f7aad
commit
699d5ee8a9
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user