Commit e59cd10a authored by John Levon's avatar John Levon Committed by Jim Harris
Browse files

lib/accel: lazily initialize accel_sw completion poller



Now isal and accel are required to build SPDK, interrupt mode is broken:
accel_comp_poll() is not interrupt-mode-friendly. As a partial
workaround, only initialize the poller if work is actually submitted to
accel_sw.

Signed-off-by: default avatarJohn Levon <john.levon@nutanix.com>
Change-Id: I9b31a1c4ae6c4cfa62c4cbecbd1fadb1ccba8c6f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22299


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
parent 8f15778f
Loading
Loading
Loading
Loading
+32 −25
Original line number Diff line number Diff line
@@ -54,8 +54,7 @@ static int sw_accel_crypto_key_init(struct spdk_accel_crypto_key *key);
static bool sw_accel_crypto_supports_tweak_mode(enum spdk_accel_crypto_tweak_mode tweak_mode);
static bool sw_accel_crypto_supports_cipher(enum spdk_accel_cipher cipher, size_t key_size);

/* Post SW completions to a list and complete in a poller as we don't want to
 * complete them on the caller's stack as they'll likely submit another. */
/* Post SW completions to a list; processed by ->completion_poller. */
inline static void
_add_to_comp_list(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task, int status)
{
@@ -475,6 +474,28 @@ _sw_accel_dif_generate_copy(struct sw_accel_io_channel *sw_ch, struct spdk_accel
				      accel_task->dif.ctx);
}

static int
accel_comp_poll(void *arg)
{
	struct sw_accel_io_channel	*sw_ch = arg;
	STAILQ_HEAD(, spdk_accel_task)	tasks_to_complete;
	struct spdk_accel_task		*accel_task;

	if (STAILQ_EMPTY(&sw_ch->tasks_to_complete)) {
		return SPDK_POLLER_IDLE;
	}

	STAILQ_INIT(&tasks_to_complete);
	STAILQ_SWAP(&tasks_to_complete, &sw_ch->tasks_to_complete, spdk_accel_task);

	while ((accel_task = STAILQ_FIRST(&tasks_to_complete))) {
		STAILQ_REMOVE_HEAD(&tasks_to_complete, link);
		spdk_accel_task_complete(accel_task, accel_task->status);
	}

	return SPDK_POLLER_BUSY;
}

static int
sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_task)
{
@@ -482,6 +503,14 @@ sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_
	struct spdk_accel_task *tmp;
	int rc = 0;

	/*
	 * Lazily initialize our completion poller. We don't want to complete
	 * them inline as they'll likely submit another.
	 */
	if (spdk_unlikely(sw_ch->completion_poller == NULL)) {
		sw_ch->completion_poller = SPDK_POLLER_REGISTER(accel_comp_poll, sw_ch, 0);
	}

	do {
		switch (accel_task->op_code) {
		case SPDK_ACCEL_OPC_COPY:
@@ -549,35 +578,13 @@ sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_
	return 0;
}

static int
accel_comp_poll(void *arg)
{
	struct sw_accel_io_channel	*sw_ch = arg;
	STAILQ_HEAD(, spdk_accel_task)	tasks_to_complete;
	struct spdk_accel_task		*accel_task;

	if (STAILQ_EMPTY(&sw_ch->tasks_to_complete)) {
		return SPDK_POLLER_IDLE;
	}

	STAILQ_INIT(&tasks_to_complete);
	STAILQ_SWAP(&tasks_to_complete, &sw_ch->tasks_to_complete, spdk_accel_task);

	while ((accel_task = STAILQ_FIRST(&tasks_to_complete))) {
		STAILQ_REMOVE_HEAD(&tasks_to_complete, link);
		spdk_accel_task_complete(accel_task, accel_task->status);
	}

	return SPDK_POLLER_BUSY;
}

static int
sw_accel_create_cb(void *io_device, void *ctx_buf)
{
	struct sw_accel_io_channel *sw_ch = ctx_buf;

	STAILQ_INIT(&sw_ch->tasks_to_complete);
	sw_ch->completion_poller = SPDK_POLLER_REGISTER(accel_comp_poll, sw_ch, 0);
	sw_ch->completion_poller = NULL;

#ifdef SPDK_CONFIG_ISAL
	isal_deflate_init(&sw_ch->stream);
+2 −0
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ test_setup(void)
	}
	g_sw_ch = (struct sw_accel_io_channel *)((char *)g_module_ch + sizeof(
				struct spdk_io_channel));
	/* Prevent lazy initialization of poller. */
	g_sw_ch->completion_poller = (void *)0xdeadbeef;
	STAILQ_INIT(&g_sw_ch->tasks_to_complete);
	g_module_if.supports_opcode = _supports_opcode;
	return 0;