test/bdev: Use thread library in bdevio

No longer use the event system.

Change-Id: Ib75d17e481f3421859142a4cee4b5881570e8582
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468388
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Ben Walker 2019-09-13 15:30:47 -07:00
parent 7f9c41bee0
commit f23e89c58e

View File

@ -52,10 +52,11 @@
pthread_mutex_t g_test_mutex; pthread_mutex_t g_test_mutex;
pthread_cond_t g_test_cond; pthread_cond_t g_test_cond;
static uint32_t g_lcore_id_init; static struct spdk_thread *g_thread_init;
static uint32_t g_lcore_id_ut; static struct spdk_thread *g_thread_ut;
static uint32_t g_lcore_id_io; static struct spdk_thread *g_thread_io;
static bool g_wait_for_tests = false; static bool g_wait_for_tests = false;
static int g_num_failures = 0;
struct io_target { struct io_target {
struct spdk_bdev *bdev; 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 rpc_perform_tests_cb(unsigned num_failures, struct spdk_jsonrpc_request *request);
static void 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); 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_cond_wait(&g_test_cond, &g_test_mutex);
pthread_mutex_unlock(&g_test_mutex); pthread_mutex_unlock(&g_test_mutex);
} }
@ -98,9 +96,9 @@ wake_ut_thread(void)
} }
static 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); target->ch = spdk_bdev_get_io_channel(target->bdev_desc);
assert(target->ch); assert(target->ch);
@ -134,7 +132,7 @@ bdevio_construct_target(struct spdk_bdev *bdev)
target->bdev = bdev; target->bdev = bdev;
target->next = g_io_targets; target->next = g_io_targets;
execute_spdk_function(__get_io_channel, target, NULL); execute_spdk_function(__get_io_channel, target);
g_io_targets = target; g_io_targets = target;
return 0; return 0;
@ -167,9 +165,9 @@ bdevio_construct_targets(void)
} }
static 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); spdk_put_io_channel(target->ch);
wake_ut_thread(); wake_ut_thread();
@ -182,7 +180,7 @@ bdevio_cleanup_targets(void)
target = g_io_targets; target = g_io_targets;
while (target != NULL) { while (target != NULL) {
execute_spdk_function(__put_io_channel, target, NULL); execute_spdk_function(__put_io_channel, target);
spdk_bdev_close(target->bdev_desc); spdk_bdev_close(target->bdev_desc);
g_io_targets = target->next; g_io_targets = target->next;
free(target); free(target);
@ -208,9 +206,9 @@ quick_test_complete(struct spdk_bdev_io *bdev_io, bool success, void *arg)
} }
static void 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; struct io_target *target = req->target;
int rc; int rc;
@ -229,9 +227,9 @@ __blockdev_write(void *arg1, void *arg2)
} }
static void 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; struct io_target *target = req->target;
int rc; int rc;
@ -283,7 +281,7 @@ blockdev_write(struct io_target *target, char *tx_buf,
g_completion_success = false; g_completion_success = false;
execute_spdk_function(__blockdev_write, &req, NULL); execute_spdk_function(__blockdev_write, &req);
} }
static void static void
@ -299,13 +297,13 @@ blockdev_write_zeroes(struct io_target *target, char *tx_buf,
g_completion_success = false; g_completion_success = false;
execute_spdk_function(__blockdev_write_zeroes, &req, NULL); execute_spdk_function(__blockdev_write_zeroes, &req);
} }
static void 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; struct io_target *target = req->target;
int rc; int rc;
@ -338,7 +336,7 @@ blockdev_read(struct io_target *target, char *rx_buf,
g_completion_success = false; g_completion_success = false;
execute_spdk_function(__blockdev_read, &req, NULL); execute_spdk_function(__blockdev_read, &req);
} }
static int static int
@ -801,9 +799,9 @@ blockdev_overlapped_write_read_8k(void)
} }
static 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; struct io_target *target = req->target;
int rc; int rc;
@ -825,7 +823,7 @@ blockdev_test_reset(void)
g_completion_success = false; 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 /* Workaround: NVMe-oF target doesn't support reset yet - so for now
* don't fail the test if it's an NVMe bdev. * 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 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; struct io_target *target = pt_req->target;
int rc; int rc;
@ -896,7 +894,7 @@ blockdev_test_nvme_passthru_rw(void)
pt_req.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC; pt_req.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
pt_req.sc = SPDK_NVME_SC_INVALID_FIELD; 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.sct == SPDK_NVME_SCT_GENERIC);
CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS); 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.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
pt_req.sc = SPDK_NVME_SC_INVALID_FIELD; 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.sct == SPDK_NVME_SCT_GENERIC);
CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS); 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.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC;
pt_req.sc = SPDK_NVME_SC_SUCCESS; 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.sct == SPDK_NVME_SCT_GENERIC);
CU_ASSERT(pt_req.sc == SPDK_NVME_SC_INVALID_OPCODE); CU_ASSERT(pt_req.sc == SPDK_NVME_SC_INVALID_OPCODE);
} }
static void 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; struct io_target *target = pt_req->target;
int rc; int rc;
@ -977,16 +975,18 @@ blockdev_test_nvme_admin_passthru(void)
pt_req.sct = SPDK_NVME_SCT_GENERIC; pt_req.sct = SPDK_NVME_SCT_GENERIC;
pt_req.sc = SPDK_NVME_SC_SUCCESS; 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.sct == SPDK_NVME_SCT_GENERIC);
CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS); CU_ASSERT(pt_req.sc == SPDK_NVME_SC_SUCCESS);
} }
static void static void
__stop_init_thread(void *arg1, void *arg2) __stop_init_thread(void *arg)
{ {
unsigned num_failures = (unsigned)(uintptr_t)arg1; unsigned num_failures = g_num_failures;
struct spdk_jsonrpc_request *request = arg2; struct spdk_jsonrpc_request *request = arg;
g_num_failures = 0;
bdevio_cleanup_targets(); bdevio_cleanup_targets();
if (g_wait_for_tests) { if (g_wait_for_tests) {
@ -1000,11 +1000,9 @@ __stop_init_thread(void *arg1, void *arg2)
static void static void
stop_init_thread(unsigned num_failures, struct spdk_jsonrpc_request *request) 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, spdk_thread_send_msg(g_thread_init, __stop_init_thread, request);
(void *)(uintptr_t)num_failures, request);
spdk_event_call(event);
} }
static int static int
@ -1086,9 +1084,9 @@ __setup_ut_on_single_target(struct io_target *target)
} }
static void 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; int rc = 0;
struct io_target *target; struct io_target *target;
unsigned num_failures; unsigned num_failures;
@ -1116,37 +1114,81 @@ __run_ut_thread(void *arg1, void *arg2)
stop_init_thread(num_failures, request); 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 static void
test_main(void *arg1) 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_mutex_init(&g_test_mutex, NULL);
pthread_cond_init(&g_test_cond, NULL); pthread_cond_init(&g_test_cond, NULL);
g_lcore_id_init = spdk_env_get_first_core(); tmpmask = spdk_cpuset_alloc();
g_lcore_id_ut = spdk_env_get_next_core(g_lcore_id_init); if (tmpmask == NULL) {
g_lcore_id_io = spdk_env_get_next_core(g_lcore_id_ut);
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");
spdk_app_stop(-1); spdk_app_stop(-1);
return;
} }
appmask = spdk_app_get_core_mask();
if (spdk_cpuset_count(appmask) < 3) {
spdk_cpuset_free(tmpmask);
spdk_app_stop(-1);
return;
}
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;
}
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;
}
spdk_cpuset_free(tmpmask);
if (g_wait_for_tests) { if (g_wait_for_tests) {
/* Do not perform any tests until RPC is received */ /* Do not perform any tests until RPC is received */
return; return;
} }
if (bdevio_construct_targets() < 0) { spdk_thread_send_msg(g_thread_init, __construct_targets, NULL);
spdk_app_stop(-1);
return;
}
event = spdk_event_allocate(g_lcore_id_ut, __run_ut_thread, NULL, NULL);
spdk_event_call(event);
} }
static void static void
@ -1201,7 +1243,6 @@ static void
rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{ {
struct rpc_perform_tests req = {NULL}; struct rpc_perform_tests req = {NULL};
struct spdk_event *event;
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
int rc; int rc;
@ -1242,8 +1283,7 @@ rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_v
} }
free_rpc_perform_tests(&req); free_rpc_perform_tests(&req);
event = spdk_event_allocate(g_lcore_id_ut, __run_ut_thread, NULL, request); spdk_thread_send_msg(g_thread_ut, __run_ut_thread, request);
spdk_event_call(event);
return; return;