Commit d780d235 authored by paul luse's avatar paul luse Committed by Jim Harris
Browse files

accel: add ISAL based compress/decompress to accel SW module



Note that without ISAL or IAA a call to compress/decompress
will fail.

Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: Id20a08f6e61b9a51fa4a1634a5314e6ca18fa504
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12310


Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 997433f9
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -38,6 +38,11 @@

#include "spdk/accel_engine.h"
#include "spdk/queue.h"
#include "spdk/config.h"

#ifdef SPDK_CONFIG_ISAL
#include "../isa-l/include/igzip_lib.h"
#endif

struct spdk_accel_task;

@@ -45,6 +50,11 @@ void spdk_accel_task_complete(struct spdk_accel_task *task, int status);

struct accel_io_channel {
	struct spdk_io_channel		*engine_ch[ACCEL_OPC_LAST];
	/* for ISAL */
#ifdef SPDK_CONFIG_ISAL
	struct isal_zstream		stream;
	struct inflate_state		state;
#endif
	void				*task_pool_base;
	TAILQ_HEAD(, spdk_accel_task)	task_pool;
};
+85 −18
Original line number Diff line number Diff line
@@ -491,6 +491,18 @@ accel_engine_create_cb(void *io_device, void *ctx_buf)
		return -ENOMEM;
	}

#ifdef SPDK_CONFIG_ISAL
	isal_deflate_stateless_init(&accel_ch->stream);
	accel_ch->stream.level = 1;
	accel_ch->stream.level_buf = calloc(1, ISAL_DEF_LVL1_DEFAULT);
	if (accel_ch->stream.level_buf == NULL) {
		SPDK_ERRLOG("Could not allocate isal internal buffer\n");
		goto err;
	}
	accel_ch->stream.level_buf_size = ISAL_DEF_LVL1_DEFAULT;
	isal_inflate_init(&accel_ch->state);
#endif

	TAILQ_INIT(&accel_ch->task_pool);
	task_mem = accel_ch->task_pool_base;
	for (i = 0 ; i < MAX_TASKS_PER_CHANNEL; i++) {
@@ -501,22 +513,24 @@ accel_engine_create_cb(void *io_device, void *ctx_buf)

	/* Assign engines and get IO channels for each */
	for (i = 0; i < ACCEL_OPC_LAST; i++) {
		/* TODO this check goes away once SW implementation of comp/decomp is implemented */
		if (g_engines_opc[i]) {
		accel_ch->engine_ch[i] = g_engines_opc[i]->get_io_channel();
		/* This can happen if idxd runs out of channels. */
		if (accel_ch->engine_ch[i] == NULL) {
				goto err;
			}
			goto err2;
		}
	}

	return 0;
err:
err2:
	for (j = 0; j < i; j++) {
		spdk_put_io_channel(accel_ch->engine_ch[j]);
	}
	return -EINVAL;
#ifdef SPDK_CONFIG_ISAL
	free(accel_ch->stream.level_buf);
err:
#endif
	free(accel_ch->task_pool_base);
	return -ENOMEM;
}

/* Framework level channel destroy callback. */
@@ -527,14 +541,14 @@ accel_engine_destroy_cb(void *io_device, void *ctx_buf)
	int i;

	for (i = 0; i < ACCEL_OPC_LAST; i++) {
		/* TODO this check goes away once SW implementation of comp/decomp is implemented,
		 * or it can be assert */
		if (accel_ch->engine_ch[i]) {
		assert(accel_ch->engine_ch[i] != NULL);
		spdk_put_io_channel(accel_ch->engine_ch[i]);
		accel_ch->engine_ch[i] = NULL;
	}
	}

#ifdef SPDK_CONFIG_ISAL
	free(accel_ch->stream.level_buf);
#endif
	free(accel_ch->task_pool_base);
}

@@ -577,9 +591,7 @@ spdk_accel_engine_initialize(void)
		}
	}
#ifdef DEBUG
	/* TODO change ACCEL_OPC_LAST to ACCEL_OPC_LAST once SW implmentation of
	 * compress/decomp is done */
	for (op = 0; op < ACCEL_OPC_COMPRESS; op++) {
	for (op = 0; op < ACCEL_OPC_LAST; op++) {
		assert(g_engines_opc[op] != NULL);
	}
#endif
@@ -667,6 +679,8 @@ sw_accel_supports_opcode(enum accel_opcode opc)
	case ACCEL_OPC_COMPARE:
	case ACCEL_OPC_CRC32C:
	case ACCEL_OPC_COPY_CRC32C:
	case ACCEL_OPC_COMPRESS:
	case ACCEL_OPC_DECOMPRESS:
		return true;
	default:
		return false;
@@ -770,6 +784,53 @@ _sw_accel_crc32cv(uint32_t *crc_dst, struct iovec *iov, uint32_t iovcnt, uint32_
	*crc_dst = spdk_crc32c_iov_update(iov, iovcnt, ~seed);
}

static int
_sw_accel_compress(struct spdk_accel_task *accel_task)
{
#ifdef SPDK_CONFIG_ISAL
	struct accel_io_channel *accel_ch = accel_task->accel_ch;

	accel_ch->stream.next_in = accel_task->src;
	accel_ch->stream.next_out = accel_task->dst;
	accel_ch->stream.avail_in = accel_task->nbytes;
	accel_ch->stream.avail_out = accel_task->nbytes_dst;

	isal_deflate_stateless(&accel_ch->stream);
	if (accel_task->output_size != NULL) {
		assert(accel_task->nbytes_dst > accel_ch->stream.avail_out);
		*accel_task->output_size = accel_task->nbytes_dst - accel_ch->stream.avail_out;
	}

	return 0;
#else
	SPDK_ERRLOG("ISAL option is required to use software compression.\n");
	return -EINVAL;
#endif
}

static int
_sw_accel_decompress(struct spdk_accel_task *accel_task)
{
#ifdef SPDK_CONFIG_ISAL
	struct accel_io_channel *accel_ch = accel_task->accel_ch;
	int rc;

	accel_ch->state.next_in = accel_task->src;
	accel_ch->state.avail_in = accel_task->nbytes;
	accel_ch->state.next_out = accel_task->dst;
	accel_ch->state.avail_out = accel_task->nbytes_dst;

	rc = isal_inflate_stateless(&accel_ch->state);
	if (rc) {
		SPDK_ERRLOG("isal_inflate_stateless retunred error %d.\n", rc);
	}
	return rc;
#else
	SPDK_ERRLOG("ISAL option is required to use software decompression.\n");
	return -EINVAL;
#endif
}

static int
sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_task)
{
@@ -820,6 +881,12 @@ sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_
				}
			}
			break;
		case ACCEL_OPC_COMPRESS:
			rc = _sw_accel_compress(accel_task);
			break;
		case ACCEL_OPC_DECOMPRESS:
			rc = _sw_accel_decompress(accel_task);
			break;
		default:
			assert(false);
			break;
+1 −0
Original line number Diff line number Diff line
@@ -14,3 +14,4 @@ run_test "accel_engine" $SPDK_EXAMPLE_DIR/accel_perf -t 1 -w copy_crc32c -y
run_test "accel_engine" $SPDK_EXAMPLE_DIR/accel_perf -t 1 -w copy_crc32c -y -C 2
run_test "accel_engine" $SPDK_EXAMPLE_DIR/accel_perf -t 1 -w dualcast -y
run_test "accel_engine" $SPDK_EXAMPLE_DIR/accel_perf -t 1 -w compare -y
run_test "accel_engine" $SPDK_EXAMPLE_DIR/accel_perf -t 1 -w compress -y