From 0f5a873e6e3dc8eb4380aa3fff2fa7c457a7cd05 Mon Sep 17 00:00:00 2001 From: wwlliangliang Date: Fri, 26 Nov 2021 01:18:10 -0500 Subject: [PATCH] examples/accel/perf: fix partial-free error before _init_thread We encountered a coredump in running accel_perf with only one ioat/idxd device enabled: accel_perf: accel_engine.c:973: accel_engine_create_cb: Assertion `accel_ch->engine_ch != NULL' failed. Aborted (core dumped) In identify_accel_engine_usage, we try to get an accel channel, read capabilities of it, and free it. However, the hw destory_cb is not yet called before running _init_thread because the hw destroy_cb is delayed by accel_engine_destroy_cb, which is already a delayed event itself. So, we simply check the first available channel's capabilities in _init_thread to avoid such partial-free error. Signed-off-by: Wenliang Wang Change-Id: I96ae0408568ed6cd2cb9b74fde406a821943616e Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10426 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Paul Luse --- examples/accel/perf/accel_perf.c | 38 +++++++++++++++----------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/accel/perf/accel_perf.c b/examples/accel/perf/accel_perf.c index e635819b4a..bd54e51b2e 100644 --- a/examples/accel/perf/accel_perf.c +++ b/examples/accel/perf/accel_perf.c @@ -611,6 +611,19 @@ _worker_stop(void *arg) return SPDK_POLLER_BUSY; } +static inline void +identify_accel_engine_usage(struct spdk_io_channel *ch) +{ + uint64_t capabilities; + + assert(ch != NULL); + capabilities = spdk_accel_get_capabilities(ch); + if ((capabilities & g_workload_selection) != g_workload_selection) { + SPDK_WARNLOG("The selected workload is not natively supported by the current engine\n"); + SPDK_WARNLOG("The software engine will be used instead.\n\n"); + } +} + static void _init_thread(void *arg1) { @@ -632,12 +645,17 @@ _init_thread(void *arg1) worker->core = spdk_env_get_current_core(); worker->thread = spdk_get_thread(); pthread_mutex_lock(&g_workers_lock); + i = g_num_workers; g_num_workers++; worker->next = g_workers; g_workers = worker; pthread_mutex_unlock(&g_workers_lock); worker->ch = spdk_accel_engine_get_io_channel(); + if (i == 0) { + identify_accel_engine_usage(worker->ch); + } + TAILQ_INIT(&worker->tasks_pool); worker->task_base = calloc(num_tasks, sizeof(struct ap_task)); @@ -680,24 +698,6 @@ error: spdk_app_stop(-1); } -static inline void -identify_accel_engine_usage(void) -{ - struct spdk_io_channel *ch; - uint64_t capabilities; - - ch = spdk_accel_engine_get_io_channel(); - assert(ch != NULL); - - capabilities = spdk_accel_get_capabilities(ch); - if ((capabilities & g_workload_selection) != g_workload_selection) { - SPDK_WARNLOG("The selected workload is not natively supported by the current engine\n"); - SPDK_WARNLOG("The software engine will be used instead.\n\n"); - } - - spdk_put_io_channel(ch); -} - static void accel_perf_start(void *arg1) { @@ -708,8 +708,6 @@ accel_perf_start(void *arg1) struct spdk_thread *thread; struct display_info *display; - identify_accel_engine_usage(); - g_tsc_rate = spdk_get_ticks_hz(); g_tsc_end = spdk_get_ticks() + g_time_in_sec * g_tsc_rate;