Example #1
0
File: zvol.c Project: alek-p/zfs
void
zvol_remove_minors(spa_t *spa, const char *name, boolean_t async)
{
	zvol_task_t *task;
	taskqid_t id;

	task = zvol_task_alloc(ZVOL_ASYNC_REMOVE_MINORS, name, NULL, ~0ULL);
	if (task == NULL)
		return;

	id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP);
	if ((async == B_FALSE) && (id != 0))
		taskq_wait_id(spa->spa_zvol_taskq, id);
}
Example #2
0
static int
splat_taskq_test7_impl(struct file *file, void *arg, boolean_t prealloc)
{
	taskq_t *tq;
	taskq_ent_t tqe;
	splat_taskq_arg_t tq_arg;

	splat_vprint(file, 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,
	                       50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
		splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
		             "Taskq '%s' create failed\n",
		             SPLAT_TASKQ_TEST7_NAME);
		return -EINVAL;
	}

	tq_arg.depth = 0;
	tq_arg.flag  = 0;
	tq_arg.id    = 0;
	tq_arg.file  = file;
	tq_arg.name  = SPLAT_TASKQ_TEST7_NAME;
	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);

	if (tq_arg.flag == 0) {
		splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
		             "Taskq '%s' waiting\n", tq_arg.name);
		taskq_wait_id(tq, SPLAT_TASKQ_DEPTH_MAX);
	}

	splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
	              "Taskq '%s' destroying\n", tq_arg.name);
	taskq_destroy(tq);

	return tq_arg.depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL;
}
Example #3
0
static int
splat_rwlock_test4_type(taskq_t *tq, rw_priv_t *rwp, int expected_rc,
			krw_t holder_type, krw_t try_type)
{
	int id, rc = 0;

	/* Schedule a task function which will try and acquire the rwlock
	 * using type try_type while the rwlock is being held as holder_type.
	 * The result must match expected_rc for the test to pass */
	rwp->rw_rc = -EINVAL;
	rwp->rw_type = try_type;

	if (holder_type == RW_WRITER || holder_type == RW_READER)
		rw_enter(&rwp->rw_rwlock, holder_type);

	id = taskq_dispatch(tq, splat_rwlock_test4_func, rwp, TQ_SLEEP);
	if (id == 0) {
		splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME, "%s",
			     "taskq_dispatch() failed\n");
		rc = -EINVAL;
		goto out;
	}

	taskq_wait_id(tq, id);

	if (rwp->rw_rc != expected_rc)
		rc = -EINVAL;

	splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME,
		     "%srw_tryenter(%s) returned %d (expected %d) when %s\n",
		     rc ? "Fail " : "", splat_rwlock_test4_name(try_type),
		     rwp->rw_rc, expected_rc,
		     splat_rwlock_test4_name(holder_type));
out:
	if (holder_type == RW_WRITER || holder_type == RW_READER)
		rw_exit(&rwp->rw_rwlock);

	return rc;
}
Example #4
0
static int
splat_taskq_test6_impl(struct file *file, void *arg, boolean_t prealloc)
{
	taskq_t *tq;
	taskqid_t id;
	splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX];
	splat_taskq_arg_t tq_arg;
	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;
	uint_t tflags;

	splat_vprint(file, 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,
		               50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
		splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
		             "Taskq '%s' create failed\n",
		             SPLAT_TASKQ_TEST6_NAME);
		return -EINVAL;
	}

	tq_arg.flag = 0;
	memset(&tq_arg.order, 0, sizeof(int) * SPLAT_TASKQ_ORDER_MAX);
	spin_lock_init(&tq_arg.lock);
	tq_arg.file = file;
	tq_arg.name = SPLAT_TASKQ_TEST6_NAME;

	for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
		taskq_init_ent(&tqes[i]);

		tq_id[i].id = i + 1;
		tq_id[i].arg = &tq_arg;
		tflags = TQ_SLEEP;
		if (i > 4)
			tflags |= TQ_FRONT;

		if (prealloc) {
			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,
			        "Taskq '%s' function '%s' dispatch failed\n",
				tq_arg.name, sym2str(splat_taskq_test6_func));
				rc = -EINVAL;
				goto out;
		}

		if (tq_id[i].id != id) {
			splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
			        "Taskq '%s' expected taskqid %d got %d\n",
				tq_arg.name, (int)tq_id[i].id, (int)id);
				rc = -EINVAL;
				goto out;
		}
		/* Sleep to let tasks 1-3 start executing. */
		if ( i == 2 )
			msleep(100);
	}

	splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, "Taskq '%s' "
		     "waiting for taskqid %d completion\n", tq_arg.name,
		     SPLAT_TASKQ_ORDER_MAX);
	taskq_wait_id(tq, SPLAT_TASKQ_ORDER_MAX);
	rc = splat_taskq_test_order(&tq_arg, order);

out:
	splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
		     "Taskq '%s' destroying\n", tq_arg.name);
	taskq_destroy(tq);

	return rc;
}
Example #5
0
static int
splat_taskq_test5_impl(struct file *file, void *arg, boolean_t prealloc)
{
	taskq_t *tq;
	taskqid_t id;
	splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX];
	splat_taskq_arg_t tq_arg;
	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 };
	taskq_ent_t tqes[SPLAT_TASKQ_ORDER_MAX];
	int i, rc = 0;

	splat_vprint(file, 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,
		               50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
		splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
		             "Taskq '%s' create failed\n",
		             SPLAT_TASKQ_TEST5_NAME);
		return -EINVAL;
	}

	tq_arg.flag = 0;
	memset(&tq_arg.order, 0, sizeof(int) * SPLAT_TASKQ_ORDER_MAX);
	spin_lock_init(&tq_arg.lock);
	tq_arg.file = file;
	tq_arg.name = SPLAT_TASKQ_TEST5_NAME;

	for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
		taskq_init_ent(&tqes[i]);

		tq_id[i].id = i + 1;
		tq_id[i].arg = &tq_arg;

		if (prealloc) {
			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,
			        "Taskq '%s' function '%s' dispatch failed\n",
				tq_arg.name, sym2str(splat_taskq_test5_func));
				rc = -EINVAL;
				goto out;
		}

		if (tq_id[i].id != id) {
			splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
			        "Taskq '%s' expected taskqid %d got %d\n",
				tq_arg.name, (int)tq_id[i].id, (int)id);
				rc = -EINVAL;
				goto out;
		}
	}

	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' "
		     "waiting for taskqid %d completion\n", tq_arg.name, 3);
	taskq_wait_id(tq, 3);
	if ((rc = splat_taskq_test_order(&tq_arg, order1)))
		goto out;

	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' "
		     "waiting for taskqid %d completion\n", tq_arg.name, 8);
	taskq_wait_id(tq, 8);
	rc = splat_taskq_test_order(&tq_arg, order2);

out:
	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
		     "Taskq '%s' destroying\n", tq_arg.name);
	taskq_destroy(tq);

	return rc;
}
Example #6
0
static int
splat_mutex_test1(struct file *file, void *arg)
{
        mutex_priv_t *mp;
        taskq_t *tq;
        int id, rc = 0;

        mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL);
        if (mp == NULL)
                return -ENOMEM;

        tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, 1, defclsyspri,
                          50, INT_MAX, TASKQ_PREPOPULATE);
        if (tq == NULL) {
                rc = -ENOMEM;
                goto out2;
        }

        mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC;
        mp->mp_file = file;
        mutex_init(&mp->mp_mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
        mutex_enter(&mp->mp_mtx);

        /*
         * Schedule a task function which will try and acquire the mutex via
         * mutex_tryenter() while it's held.  This should fail and the task
         * function will indicate this status in the passed private data.
         */
        mp->mp_rc = -EINVAL;
        id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
        if (id == 0) {
                mutex_exit(&mp->mp_mtx);
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
                             "taskq_dispatch() failed\n");
                rc = -EINVAL;
                goto out;
        }

        taskq_wait_id(tq, id);
        mutex_exit(&mp->mp_mtx);

        /* Task function successfully acquired mutex, very bad! */
        if (mp->mp_rc != -EBUSY) {
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
                             "mutex_trylock() incorrectly succeeded when "
                             "the mutex was held, %d/%d\n", id, mp->mp_rc);
                rc = -EINVAL;
                goto out;
        } else {
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
                             "mutex_trylock() correctly failed when "
                             "the mutex was held\n");
        }

        /*
         * Schedule a task function which will try and acquire the mutex via
         * mutex_tryenter() while it is not held.  This should succeed and
         * can be verified by checking the private data.
         */
        mp->mp_rc = -EINVAL;
        id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
        if (id == 0) {
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
                             "taskq_dispatch() failed\n");
                rc = -EINVAL;
                goto out;
        }

        taskq_wait_id(tq, id);

        /* Task function failed to acquire mutex, very bad! */
        if (mp->mp_rc != 0) {
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
                             "mutex_trylock() incorrectly failed when "
                             "the mutex was not held, %d/%d\n", id, mp->mp_rc);
                rc = -EINVAL;
        } else {
                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
                             "mutex_trylock() correctly succeeded "
                             "when the mutex was not held\n");
        }
out:
        taskq_destroy(tq);
        mutex_destroy(&(mp->mp_mtx));
out2:
        kfree(mp);
        return rc;
}