Commit ca6d701a authored by Yankun Li's avatar Yankun Li Committed by Konrad Sztyber
Browse files

lib/accel: add the compression level support



Change-Id: I1c5d8953cee71865a764dde65a109e0715d54697
Signed-off-by: default avatarYankun Li <845245370@qq.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24685


Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 74af66b2
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ int spdk_accel_submit_decompress(struct spdk_io_channel *ch, struct iovec *dst_i
 * \param src_iovs The io vector array which stores the src data and len.
 * \param src_iovcnt The size of the src io vectors.
 * \param comp_algo The compression algorithm, enum spdk_accel_comp_algo value.
 * \param comp_level The compression algorithm level.
 * \param output_size The size of the compressed data (may be NULL if not desired)
 * \param cb_fn Callback function which will be called when the request is complete.
 * \param cb_arg Opaque value which will be passed back as the arg parameter in
@@ -329,8 +330,8 @@ int spdk_accel_submit_decompress(struct spdk_io_channel *ch, struct iovec *dst_i
 */
int spdk_accel_submit_compress_ext(struct spdk_io_channel *ch, void *dst, uint64_t nbytes,
				   struct iovec *src_iovs, size_t src_iovcnt,
				   enum spdk_accel_comp_algo comp_algo, uint32_t *output_size,
				   spdk_accel_completion_cb cb_fn, void *cb_arg);
				   enum spdk_accel_comp_algo comp_algo, uint32_t comp_level,
				   uint32_t *output_size, spdk_accel_completion_cb cb_fn, void *cb_arg);

/**
 * Build and submit a memory decompress request using the specified algorithm.
@@ -355,6 +356,18 @@ int spdk_accel_submit_decompress_ext(struct spdk_io_channel *ch, struct iovec *d
				     enum spdk_accel_comp_algo decomp_algo, uint32_t *output_size,
				     spdk_accel_completion_cb cb_fn, void *cb_arg);

/**
 * Gets the level range of the specified algorithm.
 *
 * \param comp_algo The compression algorithm.
 * \param min_level The lowest level supported by the compression algorithm.
 * \param max_level The highest level supported by the compression algorithm.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_accel_get_compress_level_range(enum spdk_accel_comp_algo comp_algo,
					uint32_t *min_level, uint32_t *max_level);

/**
 * Submit an xor request.
 *
+7 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ struct spdk_accel_task {
		} dif;
		struct {
			enum spdk_accel_comp_algo       algo; /* compresssion/decompression algorithm */
			uint32_t                        level; /* compression alogrithm level */
		} comp;
	};
	union {
@@ -239,6 +240,12 @@ struct spdk_accel_module_if {
	 */
	bool (*compress_supports_algo)(enum spdk_accel_comp_algo algo);

	/**
	 * Returns the lowest and highest levels of the specified algorithm.
	 */
	int (*get_compress_level_range)(enum spdk_accel_comp_algo algo,
					uint32_t *min_level, uint32_t *max_level);

	/**
	 * Returns memory domains supported by the module.  If NULL, the module does not support
	 * memory domains.  The `domains` array can be NULL, in which case this function only
+18 −3
Original line number Diff line number Diff line
@@ -665,6 +665,20 @@ spdk_accel_submit_copy_crc32cv(struct spdk_io_channel *ch, void *dst,
	return accel_submit_task(accel_ch, accel_task);
}

int
spdk_accel_get_compress_level_range(enum spdk_accel_comp_algo comp_algo,
				    uint32_t *min_level, uint32_t *max_level)
{
	struct spdk_accel_module_if *module = g_modules_opc[SPDK_ACCEL_OPC_COMPRESS].module;

	if (module->get_compress_level_range == NULL) {
		SPDK_ERRLOG("Module %s doesn't implement callback fn get_compress_level_range.\n", module->name);
		return -ENOTSUP;
	}

	return module->get_compress_level_range(comp_algo, min_level, max_level);
}

static int
_accel_check_comp_algo(enum spdk_accel_comp_algo comp_algo)
{
@@ -681,8 +695,8 @@ _accel_check_comp_algo(enum spdk_accel_comp_algo comp_algo)
int
spdk_accel_submit_compress_ext(struct spdk_io_channel *ch, void *dst, uint64_t nbytes,
			       struct iovec *src_iovs, size_t src_iovcnt,
			       enum spdk_accel_comp_algo comp_algo, uint32_t *output_size,
			       spdk_accel_completion_cb cb_fn, void *cb_arg)
			       enum spdk_accel_comp_algo comp_algo, uint32_t comp_level,
			       uint32_t *output_size, spdk_accel_completion_cb cb_fn, void *cb_arg)
{
	struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);
	struct spdk_accel_task *accel_task;
@@ -712,6 +726,7 @@ spdk_accel_submit_compress_ext(struct spdk_io_channel *ch, void *dst, uint64_t n
	accel_task->src_domain = NULL;
	accel_task->dst_domain = NULL;
	accel_task->comp.algo = comp_algo;
	accel_task->comp.level = comp_level;

	return accel_submit_task(accel_ch, accel_task);
}
@@ -756,7 +771,7 @@ spdk_accel_submit_compress(struct spdk_io_channel *ch, void *dst, uint64_t nbyte
			   spdk_accel_completion_cb cb_fn, void *cb_arg)
{
	return spdk_accel_submit_compress_ext(ch, dst, nbytes, src_iovs, src_iovcnt,
					      SPDK_ACCEL_COMP_ALGO_DEFLATE, output_size, cb_fn, cb_arg);
					      SPDK_ACCEL_COMP_ALGO_DEFLATE, 1, output_size, cb_fn, cb_arg);
}

int
+72 −11
Original line number Diff line number Diff line
@@ -30,11 +30,30 @@
/* Per the AES-XTS spec, the size of data unit cannot be bigger than 2^20 blocks, 128b each block */
#define ACCEL_AES_XTS_MAX_BLOCK_SIZE (1 << 24)

#ifdef SPDK_CONFIG_ISAL
#define COMP_DEFLATE_MIN_LEVEL ISAL_DEF_MIN_LEVEL
#define COMP_DEFLATE_MAX_LEVEL ISAL_DEF_MAX_LEVEL
#else
#define COMP_DEFLATE_MIN_LEVEL 0
#define COMP_DEFLATE_MAX_LEVEL 0
#endif

#define COMP_DEFLATE_LEVEL_NUM (COMP_DEFLATE_MAX_LEVEL + 1)

struct comp_deflate_level_buf {
	uint32_t size;
	uint8_t  *buf;
};

struct sw_accel_io_channel {
	/* for ISAL */
#ifdef SPDK_CONFIG_ISAL
	struct isal_zstream		stream;
	struct inflate_state		state;
	/* The array index corresponds to the algorithm level */
	struct comp_deflate_level_buf   deflate_level_bufs[COMP_DEFLATE_LEVEL_NUM];
	uint8_t                         level_buf_mem[ISAL_DEF_LVL0_DEFAULT + ISAL_DEF_LVL1_DEFAULT +
					      ISAL_DEF_LVL2_DEFAULT + ISAL_DEF_LVL3_DEFAULT];
#endif
	struct spdk_poller		*completion_poller;
	STAILQ_HEAD(, spdk_accel_task)	tasks_to_complete;
@@ -177,6 +196,11 @@ _sw_accel_compress_deflate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_
	uint32_t i, s = 0, d = 0;
	int rc = 0;

	if (accel_task->comp.level > COMP_DEFLATE_MAX_LEVEL) {
		SPDK_ERRLOG("isal_deflate doesn't support this algorithm level(%u)\n", accel_task->comp.level);
		return -EINVAL;
	}

	remaining = 0;
	for (i = 0; i < accel_task->s.iovcnt; ++i) {
		remaining += accel_task->s.iovs[i].iov_len;
@@ -188,6 +212,9 @@ _sw_accel_compress_deflate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_
	sw_ch->stream.avail_out = diov[d].iov_len;
	sw_ch->stream.next_in = siov[s].iov_base;
	sw_ch->stream.avail_in = siov[s].iov_len;
	sw_ch->stream.level = accel_task->comp.level;
	sw_ch->stream.level_buf = sw_ch->deflate_level_bufs[accel_task->comp.level].buf;
	sw_ch->stream.level_buf_size = sw_ch->deflate_level_bufs[accel_task->comp.level].size;

	do {
		/* if isal has exhausted the current dst iovec, move to the next
@@ -657,20 +684,38 @@ static int
sw_accel_create_cb(void *io_device, void *ctx_buf)
{
	struct sw_accel_io_channel *sw_ch = ctx_buf;
#ifdef SPDK_CONFIG_ISAL
	struct comp_deflate_level_buf *deflate_level_bufs;
#endif
	int i;

	STAILQ_INIT(&sw_ch->tasks_to_complete);
	sw_ch->completion_poller = NULL;

#ifdef SPDK_CONFIG_ISAL
	sw_ch->deflate_level_bufs[0].buf = sw_ch->level_buf_mem;
	deflate_level_bufs = sw_ch->deflate_level_bufs;
	deflate_level_bufs[0].size = ISAL_DEF_LVL0_DEFAULT;
	for (i = 1; i < COMP_DEFLATE_LEVEL_NUM; i++) {
		deflate_level_bufs[i].buf = deflate_level_bufs[i - 1].buf +
					    deflate_level_bufs[i - 1].size;
		switch (i) {
		case 1:
			deflate_level_bufs[i].size = ISAL_DEF_LVL1_DEFAULT;
			break;
		case 2:
			deflate_level_bufs[i].size = ISAL_DEF_LVL2_DEFAULT;
			break;
		case 3:
			deflate_level_bufs[i].size = ISAL_DEF_LVL3_DEFAULT;
			break;
		default:
			assert(false);
		}
	}

	isal_deflate_init(&sw_ch->stream);
	sw_ch->stream.flush = NO_FLUSH;
	sw_ch->stream.level = 1;
	sw_ch->stream.level_buf = calloc(1, ISAL_DEF_LVL1_DEFAULT);
	if (sw_ch->stream.level_buf == NULL) {
		SPDK_ERRLOG("Could not allocate isal internal buffer\n");
		return -ENOMEM;
	}
	sw_ch->stream.level_buf_size = ISAL_DEF_LVL1_DEFAULT;
	isal_inflate_init(&sw_ch->state);
#endif

@@ -682,10 +727,6 @@ sw_accel_destroy_cb(void *io_device, void *ctx_buf)
{
	struct sw_accel_io_channel *sw_ch = ctx_buf;

#ifdef SPDK_CONFIG_ISAL
	free(sw_ch->stream.level_buf);
#endif

	spdk_poller_unregister(&sw_ch->completion_poller);
}

@@ -794,6 +835,25 @@ sw_accel_compress_supports_algo(enum spdk_accel_comp_algo algo)
	return false;
}

static int
sw_accel_get_compress_level_range(enum spdk_accel_comp_algo algo,
				  uint32_t *min_level, uint32_t *max_level)
{
	switch (algo) {
	case SPDK_ACCEL_COMP_ALGO_DEFLATE:
#ifdef SPDK_CONFIG_ISAL
		*min_level = COMP_DEFLATE_MIN_LEVEL;
		*max_level = COMP_DEFLATE_MAX_LEVEL;
		return 0;
#else
		SPDK_ERRLOG("ISAL option is required to use software compression.\n");
		return -EINVAL;
#endif
	default:
		return -EINVAL;
	}
}

static int
sw_accel_get_operation_info(enum spdk_accel_opcode opcode,
			    const struct spdk_accel_operation_exec_ctx *ctx,
@@ -819,6 +879,7 @@ static struct spdk_accel_module_if g_sw_module = {
	.crypto_supports_tweak_mode	= sw_accel_crypto_supports_tweak_mode,
	.crypto_supports_cipher		= sw_accel_crypto_supports_cipher,
	.compress_supports_algo         = sw_accel_compress_supports_algo,
	.get_compress_level_range       = sw_accel_get_compress_level_range,
	.get_operation_info		= sw_accel_get_operation_info,
};

+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
	spdk_accel_submit_compress_ext;
	spdk_accel_submit_decompress_ext;
	spdk_accel_append_decompress_ext;
	spdk_accel_get_compress_level_range;

	# functions needed by modules
	spdk_accel_module_list_add;
Loading