Commit 0f5a873e authored by wwlliangliang's avatar wwlliangliang Committed by Tomasz Zawadzki
Browse files

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: default avatarWenliang 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
parent 8dafa563
Loading
Loading
Loading
Loading
+18 −20
Original line number Diff line number Diff line
@@ -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;