Commit f23e89c5 authored by Ben Walker's avatar Ben Walker
Browse files

test/bdev: Use thread library in bdevio



No longer use the event system.

Change-Id: Ib75d17e481f3421859142a4cee4b5881570e8582
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468388


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 7f9c41be
Loading
Loading
Loading
Loading
+99 −59
Original line number Diff line number Diff line
@@ -52,10 +52,11 @@
pthread_mutex_t g_test_mutex;
pthread_cond_t g_test_cond;

static uint32_t g_lcore_id_init;
static uint32_t g_lcore_id_ut;
static uint32_t g_lcore_id_io;
static struct spdk_thread *g_thread_init;
static struct spdk_thread *g_thread_ut;
static struct spdk_thread *g_thread_io;
static bool g_wait_for_tests = false;
static int g_num_failures = 0;

struct io_target {
	struct spdk_bdev	*bdev;
@@ -78,13 +79,10 @@ struct io_target *g_current_io_target = NULL;
static void rpc_perform_tests_cb(unsigned num_failures, struct spdk_jsonrpc_request *request);

static void
execute_spdk_function(spdk_event_fn fn, void *arg1, void *arg2)
execute_spdk_function(spdk_msg_fn fn, void *arg)
{
	struct spdk_event *event;

	event = spdk_event_allocate(g_lcore_id_io, fn, arg1, arg2);
	pthread_mutex_lock(&g_test_mutex);
	spdk_event_call(event);
	spdk_thread_send_msg(g_thread_io, fn, arg);
	pthread_cond_wait(&g_test_cond, &g_test_mutex);
	pthread_mutex_unlock(&g_test_mutex);
}
@@ -98,9 +96,9 @@ wake_ut_thread(void)
}

static void
__get_io_channel(void *arg1, void *arg2)
__get_io_channel(void *arg)
{
	struct io_target *target = arg1;
	struct io_target *target = arg;

	target->ch = spdk_bdev_get_io_channel(target->bdev_desc);
	assert(target->ch);
@@ -134,7 +132,7 @@ bdevio_construct_target(struct spdk_bdev *bdev)

	target->bdev = bdev;
	target->next = g_io_targets;
	execute_spdk_function(__get_io_channel, target, NULL);
	execute_spdk_function(__get_io_channel, target);
	g_io_targets = target;

	return 0;
@@ -167,9 +165,9 @@ bdevio_construct_targets(void)
}

static void
__put_io_channel(void *arg1, void *arg2)
__put_io_channel(void *arg)
{
	struct io_target *target = arg1;
	struct io_target *target = arg;

	spdk_put_io_channel(target->ch);
	wake_ut_thread();
@@ -182,7 +180,7 @@ bdevio_cleanup_targets(void)

	target = g_io_targets;
	while (target != NULL) {
		execute_spdk_function(__put_io_channel, target, NULL);
		execute_spdk_function(__put_io_channel, target);
		spdk_bdev_close(target->bdev_desc);
		g_io_targets = target->next;
		free(target);
@@ -208,9 +206,9 @@ quick_test_complete(struct spdk_bdev_io *bdev_io, bool success, void *arg)
}

static void
__blockdev_write(void *arg1, void *arg2)
__blockdev_write(void *arg)
{
	struct bdevio_request *req = arg1;
	struct bdevio_request *req = arg;
	struct io_target *target = req->target;
	int rc;

@@ -229,9 +227,9 @@ __blockdev_write(void *arg1, void *arg2)
}

static void
__blockdev_write_zeroes(void *arg1, void *arg2)
__blockdev_write_zeroes(void *arg)
{
	struct bdevio_request *req = arg1;
	struct bdevio_request *req = arg;
	struct io_target *target = req->target;
	int rc;

@@ -283,7 +281,7 @@ blockdev_write(struct io_target *target, char *tx_buf,

	g_completion_success = false;

	execute_spdk_function(__blockdev_write, &req, NULL);
	execute_spdk_function(__blockdev_write, &req);
}

static void
@@ -299,13 +297,13 @@ blockdev_write_zeroes(struct io_target *target, char *tx_buf,

	g_completion_success = false;

	execute_spdk_function(__blockdev_write_zeroes, &req, NULL);
	execute_spdk_function(__blockdev_write_zeroes, &req);
}

static void
__blockdev_read(void *arg1, void *arg2)
__blockdev_read(void *arg)
{
	struct bdevio_request *req = arg1;
	struct bdevio_request *req = arg;
	struct io_target *target = req->target;
	int rc;

@@ -338,7 +336,7 @@ blockdev_read(struct io_target *target, char *rx_buf,

	g_completion_success = false;

	execute_spdk_function(__blockdev_read, &req, NULL);
	execute_spdk_function(__blockdev_read, &req);
}

static int
@@ -801,9 +799,9 @@ blockdev_overlapped_write_read_8k(void)
}

static void
__blockdev_reset(void *arg1, void *arg2)
__blockdev_reset(void *arg)
{
	struct bdevio_request *req = arg1;
	struct bdevio_request *req = arg;
	struct io_target *target = req->target;
	int rc;

@@ -825,7 +823,7 @@ blockdev_test_reset(void)

	g_completion_success = false;

	execute_spdk_function(__blockdev_reset, &req, NULL);
	execute_spdk_function(__blockdev_reset, &req);

	/* Workaround: NVMe-oF target doesn't support reset yet - so for now
	 *  don't fail the test if it's an NVMe bdev.
@@ -855,9 +853,9 @@ nvme_pt_test_complete(struct spdk_bdev_io *bdev_io, bool success, void *arg)
}

static void
__blockdev_nvme_passthru(void *arg1, void *arg2)
__blockdev_nvme_passthru(void *arg)
{
	struct bdevio_passthrough_request *pt_req = arg1;
	struct bdevio_passthrough_request *pt_req = arg;
	struct io_target *target = pt_req->target;
	int rc;

@@ -896,7 +894,7 @@ blockdev_test_nvme_passthru_rw(void)

	pt_req.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
	pt_req.sc = SPDK_NVME_SC_INVALID_FIELD;
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req, NULL);
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req);
	CU_ASSERT(pt_req.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS);

@@ -906,7 +904,7 @@ blockdev_test_nvme_passthru_rw(void)

	pt_req.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
	pt_req.sc = SPDK_NVME_SC_INVALID_FIELD;
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req, NULL);
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req);
	CU_ASSERT(pt_req.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS);

@@ -934,15 +932,15 @@ blockdev_test_nvme_passthru_vendor_specific(void)

	pt_req.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
	pt_req.sc = SPDK_NVME_SC_SUCCESS;
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req, NULL);
	execute_spdk_function(__blockdev_nvme_passthru, &pt_req);
	CU_ASSERT(pt_req.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(pt_req.sc == SPDK_NVME_SC_INVALID_OPCODE);
}

static void
__blockdev_nvme_admin_passthru(void *arg1, void *arg2)
__blockdev_nvme_admin_passthru(void *arg)
{
	struct bdevio_passthrough_request *pt_req = arg1;
	struct bdevio_passthrough_request *pt_req = arg;
	struct io_target *target = pt_req->target;
	int rc;

@@ -977,16 +975,18 @@ blockdev_test_nvme_admin_passthru(void)

	pt_req.sct = SPDK_NVME_SCT_GENERIC;
	pt_req.sc = SPDK_NVME_SC_SUCCESS;
	execute_spdk_function(__blockdev_nvme_admin_passthru, &pt_req, NULL);
	execute_spdk_function(__blockdev_nvme_admin_passthru, &pt_req);
	CU_ASSERT(pt_req.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS);
}

static void
__stop_init_thread(void *arg1, void *arg2)
__stop_init_thread(void *arg)
{
	unsigned num_failures = (unsigned)(uintptr_t)arg1;
	struct spdk_jsonrpc_request *request = arg2;
	unsigned num_failures = g_num_failures;
	struct spdk_jsonrpc_request *request = arg;

	g_num_failures = 0;

	bdevio_cleanup_targets();
	if (g_wait_for_tests) {
@@ -1000,11 +1000,9 @@ __stop_init_thread(void *arg1, void *arg2)
static void
stop_init_thread(unsigned num_failures, struct spdk_jsonrpc_request *request)
{
	struct spdk_event *event;
	g_num_failures = num_failures;

	event = spdk_event_allocate(g_lcore_id_init, __stop_init_thread,
				    (void *)(uintptr_t)num_failures, request);
	spdk_event_call(event);
	spdk_thread_send_msg(g_thread_init, __stop_init_thread, request);
}

static int
@@ -1086,9 +1084,9 @@ __setup_ut_on_single_target(struct io_target *target)
}

static void
__run_ut_thread(void *arg1, void *arg2)
__run_ut_thread(void *arg)
{
	struct spdk_jsonrpc_request *request = arg2;
	struct spdk_jsonrpc_request *request = arg;
	int rc = 0;
	struct io_target *target;
	unsigned num_failures;
@@ -1116,37 +1114,81 @@ __run_ut_thread(void *arg1, void *arg2)
	stop_init_thread(num_failures, request);
}

static void
__construct_targets(void *arg)
{
	if (bdevio_construct_targets() < 0) {
		spdk_app_stop(-1);
		return;
	}

	spdk_thread_send_msg(g_thread_ut, __run_ut_thread, NULL);
}

static void
test_main(void *arg1)
{
	struct spdk_event *event;
	struct spdk_cpuset *tmpmask, *appmask;
	uint32_t cpu, init_cpu;

	pthread_mutex_init(&g_test_mutex, NULL);
	pthread_cond_init(&g_test_cond, NULL);

	g_lcore_id_init = spdk_env_get_first_core();
	g_lcore_id_ut = spdk_env_get_next_core(g_lcore_id_init);
	g_lcore_id_io = spdk_env_get_next_core(g_lcore_id_ut);
	tmpmask = spdk_cpuset_alloc();
	if (tmpmask == NULL) {
		spdk_app_stop(-1);
		return;
	}

	appmask = spdk_app_get_core_mask();

	if (g_lcore_id_init == SPDK_ENV_LCORE_ID_ANY ||
	    g_lcore_id_ut == SPDK_ENV_LCORE_ID_ANY ||
	    g_lcore_id_io == SPDK_ENV_LCORE_ID_ANY) {
		SPDK_ERRLOG("Could not reserve 3 separate threads.\n");
	if (spdk_cpuset_count(appmask) < 3) {
		spdk_cpuset_free(tmpmask);
		spdk_app_stop(-1);
		return;
	}

	if (g_wait_for_tests) {
		/* Do not perform any tests until RPC is received */
	init_cpu = spdk_env_get_current_core();
	g_thread_init = spdk_get_thread();

	for (cpu = 0; cpu < SPDK_ENV_LCORE_ID_ANY; cpu++) {
		if (cpu != init_cpu && spdk_cpuset_get_cpu(appmask, cpu)) {
			spdk_cpuset_zero(tmpmask);
			spdk_cpuset_set_cpu(tmpmask, cpu, true);
			g_thread_ut = spdk_thread_create("ut_thread", tmpmask);
			break;
		}
	}

	if (cpu == SPDK_ENV_LCORE_ID_ANY) {
		spdk_cpuset_free(tmpmask);
		spdk_app_stop(-1);
		return;
	}

	if (bdevio_construct_targets() < 0) {
	for (cpu++; cpu < SPDK_ENV_LCORE_ID_ANY; cpu++) {
		if (cpu != init_cpu && spdk_cpuset_get_cpu(appmask, cpu)) {
			spdk_cpuset_zero(tmpmask);
			spdk_cpuset_set_cpu(tmpmask, cpu, true);
			g_thread_io = spdk_thread_create("io_thread", tmpmask);
			break;
		}
	}

	if (cpu == SPDK_ENV_LCORE_ID_ANY) {
		spdk_cpuset_free(tmpmask);
		spdk_app_stop(-1);
		return;
	}

	event = spdk_event_allocate(g_lcore_id_ut, __run_ut_thread, NULL, NULL);
	spdk_event_call(event);
	spdk_cpuset_free(tmpmask);

	if (g_wait_for_tests) {
		/* Do not perform any tests until RPC is received */
		return;
	}

	spdk_thread_send_msg(g_thread_init, __construct_targets, NULL);
}

static void
@@ -1201,7 +1243,6 @@ static void
rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{
	struct rpc_perform_tests req = {NULL};
	struct spdk_event *event;
	struct spdk_bdev *bdev;
	int rc;

@@ -1242,8 +1283,7 @@ rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_v
	}
	free_rpc_perform_tests(&req);

	event = spdk_event_allocate(g_lcore_id_ut, __run_ut_thread, NULL, request);
	spdk_event_call(event);
	spdk_thread_send_msg(g_thread_ut, __run_ut_thread, request);

	return;