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 <wangwenliang.1995@bytedance.com>
Change-Id: I96ae0408568ed6cd2cb9b74fde406a821943616e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10426
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
wwlliangliang 2021-11-26 01:18:10 -05:00 committed by Tomasz Zawadzki
parent 8dafa5632a
commit 0f5a873e6e

View File

@ -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;