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: paul luse <paul.e.luse@intel.com> Change-Id: Id20a08f6e61b9a51fa4a1634a5314e6ca18fa504 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12310 Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
997433f918
commit
d780d23532
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
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 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]) {
|
||||
spdk_put_io_channel(accel_ch->engine_ch[i]);
|
||||
accel_ch->engine_ch[i] = NULL;
|
||||
}
|
||||
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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user