accel: add support for appending a decompress operation
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: I5f091a554e08f0e052ab9e7eb9a1789d381b885f Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15635 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
6293ac8759
commit
59f55d23f2
@ -319,6 +319,32 @@ int spdk_accel_append_fill(struct spdk_accel_sequence **seq, struct spdk_io_chan
|
|||||||
struct spdk_memory_domain *domain, void *domain_ctx, uint8_t pattern,
|
struct spdk_memory_domain *domain, void *domain_ctx, uint8_t pattern,
|
||||||
int flags, spdk_accel_step_cb cb_fn, void *cb_arg);
|
int flags, spdk_accel_step_cb cb_fn, void *cb_arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a decompress operation to a sequence.
|
||||||
|
*
|
||||||
|
* \param seq Sequence object. If NULL, a new sequence object will be created.
|
||||||
|
* \param ch I/O channel.
|
||||||
|
* \param dst_iovs Destination I/O vector array.
|
||||||
|
* \param dst_iovcnt Size of the `dst_iovs` array.
|
||||||
|
* \param dst_domain Memory domain to which the destination buffers belong.
|
||||||
|
* \param dst_domain_ctx Destination buffer domain context.
|
||||||
|
* \param src_iovs Source I/O vector array.
|
||||||
|
* \param src_iovcnt Size of the `src_iovs` array.
|
||||||
|
* \param src_domain Memory domain to which the source buffers belong.
|
||||||
|
* \param src_domain_ctx Source buffer domain context.
|
||||||
|
* \param flags Accel operation flags.
|
||||||
|
* \param cb_fn Callback to be executed once this operation is completed.
|
||||||
|
* \param cb_arg Argument to be passed to `cb_fn`.
|
||||||
|
*
|
||||||
|
* \return 0 if operation was successfully added to the sequence, negative errno otherwise.
|
||||||
|
*/
|
||||||
|
int spdk_accel_append_decompress(struct spdk_accel_sequence **seq, struct spdk_io_channel *ch,
|
||||||
|
struct iovec *dst_iovs, size_t dst_iovcnt,
|
||||||
|
struct spdk_memory_domain *dst_domain, void *dst_domain_ctx,
|
||||||
|
struct iovec *src_iovs, size_t src_iovcnt,
|
||||||
|
struct spdk_memory_domain *src_domain, void *src_domain_ctx,
|
||||||
|
int flags, spdk_accel_step_cb cb_fn, void *cb_arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish a sequence and execute all its operations. After the completion callback is executed, the
|
* Finish a sequence and execute all its operations. After the completion callback is executed, the
|
||||||
* sequence object is automatically freed.
|
* sequence object is automatically freed.
|
||||||
|
@ -662,6 +662,57 @@ spdk_accel_append_fill(struct spdk_accel_sequence **pseq, struct spdk_io_channel
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_accel_append_decompress(struct spdk_accel_sequence **pseq, struct spdk_io_channel *ch,
|
||||||
|
struct iovec *dst_iovs, size_t dst_iovcnt,
|
||||||
|
struct spdk_memory_domain *dst_domain, void *dst_domain_ctx,
|
||||||
|
struct iovec *src_iovs, size_t src_iovcnt,
|
||||||
|
struct spdk_memory_domain *src_domain, void *src_domain_ctx,
|
||||||
|
int flags, spdk_accel_step_cb cb_fn, void *cb_arg)
|
||||||
|
{
|
||||||
|
struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);
|
||||||
|
struct spdk_accel_task *task;
|
||||||
|
struct spdk_accel_sequence *seq = *pseq;
|
||||||
|
|
||||||
|
if (dst_domain != NULL || src_domain != NULL) {
|
||||||
|
SPDK_ERRLOG("Memory domains are currently unsupported\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seq == NULL) {
|
||||||
|
seq = accel_sequence_get(accel_ch);
|
||||||
|
if (spdk_unlikely(seq == NULL)) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(seq->ch == accel_ch);
|
||||||
|
task = accel_sequence_get_task(accel_ch, seq, cb_fn, cb_arg);
|
||||||
|
if (spdk_unlikely(task == NULL)) {
|
||||||
|
if (*pseq == NULL) {
|
||||||
|
accel_sequence_put(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
task->dst_domain = dst_domain;
|
||||||
|
task->dst_domain_ctx = dst_domain_ctx;
|
||||||
|
task->d.iovs = dst_iovs;
|
||||||
|
task->d.iovcnt = dst_iovcnt;
|
||||||
|
task->src_domain = src_domain;
|
||||||
|
task->src_domain_ctx = src_domain_ctx;
|
||||||
|
task->s.iovs = src_iovs;
|
||||||
|
task->s.iovcnt = src_iovcnt;
|
||||||
|
task->flags = flags;
|
||||||
|
task->op_code = ACCEL_OPC_DECOMPRESS;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&seq->tasks, task, seq_link);
|
||||||
|
*pseq = seq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
accel_sequence_complete_tasks(struct spdk_accel_sequence *seq)
|
accel_sequence_complete_tasks(struct spdk_accel_sequence *seq)
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
spdk_accel_write_config_json;
|
spdk_accel_write_config_json;
|
||||||
spdk_accel_append_copy;
|
spdk_accel_append_copy;
|
||||||
spdk_accel_append_fill;
|
spdk_accel_append_fill;
|
||||||
|
spdk_accel_append_decompress;
|
||||||
spdk_accel_sequence_finish;
|
spdk_accel_sequence_finish;
|
||||||
spdk_accel_sequence_abort;
|
spdk_accel_sequence_abort;
|
||||||
spdk_accel_sequence_reverse;
|
spdk_accel_sequence_reverse;
|
||||||
|
@ -848,6 +848,15 @@ test_sequence_append_error(void)
|
|||||||
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
||||||
CU_ASSERT_PTR_NULL(seq);
|
CU_ASSERT_PTR_NULL(seq);
|
||||||
|
|
||||||
|
dst_iovs.iov_base = buf;
|
||||||
|
dst_iovs.iov_len = 2048;
|
||||||
|
src_iovs.iov_base = &buf[2048];
|
||||||
|
src_iovs.iov_len = 2048;
|
||||||
|
rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
|
||||||
|
&src_iovs, 1, NULL, NULL, 0, ut_sequence_step_cb, NULL);
|
||||||
|
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
||||||
|
CU_ASSERT_PTR_NULL(seq);
|
||||||
|
|
||||||
/* Check that the same happens when the sequence queue is empty */
|
/* Check that the same happens when the sequence queue is empty */
|
||||||
TAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task, link);
|
TAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task, link);
|
||||||
TAILQ_SWAP(&seqs, &accel_ch->seq_pool, spdk_accel_sequence, link);
|
TAILQ_SWAP(&seqs, &accel_ch->seq_pool, spdk_accel_sequence, link);
|
||||||
@ -866,6 +875,15 @@ test_sequence_append_error(void)
|
|||||||
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
||||||
CU_ASSERT_PTR_NULL(seq);
|
CU_ASSERT_PTR_NULL(seq);
|
||||||
|
|
||||||
|
dst_iovs.iov_base = buf;
|
||||||
|
dst_iovs.iov_len = 2048;
|
||||||
|
src_iovs.iov_base = &buf[2048];
|
||||||
|
src_iovs.iov_len = 2048;
|
||||||
|
rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
|
||||||
|
&src_iovs, 1, NULL, NULL, 0, ut_sequence_step_cb, NULL);
|
||||||
|
CU_ASSERT_EQUAL(rc, -ENOMEM);
|
||||||
|
CU_ASSERT_PTR_NULL(seq);
|
||||||
|
|
||||||
TAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task, link);
|
TAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task, link);
|
||||||
|
|
||||||
spdk_put_io_channel(ioch);
|
spdk_put_io_channel(ioch);
|
||||||
@ -1033,6 +1051,147 @@ test_sequence_completion_error(void)
|
|||||||
poll_threads();
|
poll_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SPDK_CONFIG_ISAL
|
||||||
|
static void
|
||||||
|
ut_compress_cb(void *cb_arg, int status)
|
||||||
|
{
|
||||||
|
int *completed = cb_arg;
|
||||||
|
|
||||||
|
CU_ASSERT_EQUAL(status, 0);
|
||||||
|
|
||||||
|
*completed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_sequence_decompress(void)
|
||||||
|
{
|
||||||
|
struct spdk_accel_sequence *seq = NULL;
|
||||||
|
struct spdk_io_channel *ioch;
|
||||||
|
struct ut_sequence ut_seq;
|
||||||
|
char buf[4096], tmp[2][4096], expected[4096];
|
||||||
|
struct iovec src_iovs[2], dst_iovs[2];
|
||||||
|
uint32_t compressed_size;
|
||||||
|
int rc, completed = 0;
|
||||||
|
|
||||||
|
ioch = spdk_accel_get_io_channel();
|
||||||
|
SPDK_CU_ASSERT_FATAL(ioch != NULL);
|
||||||
|
|
||||||
|
memset(expected, 0xa5, sizeof(expected));
|
||||||
|
src_iovs[0].iov_base = expected;
|
||||||
|
src_iovs[0].iov_len = sizeof(expected);
|
||||||
|
rc = spdk_accel_submit_compress(ioch, tmp[0], sizeof(tmp[0]), &src_iovs[0], 1,
|
||||||
|
&compressed_size, 0, ut_compress_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
while (!completed) {
|
||||||
|
poll_threads();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check a single decompress operation in a sequence */
|
||||||
|
seq = NULL;
|
||||||
|
completed = 0;
|
||||||
|
|
||||||
|
dst_iovs[0].iov_base = buf;
|
||||||
|
dst_iovs[0].iov_len = sizeof(buf);
|
||||||
|
src_iovs[0].iov_base = tmp[0];
|
||||||
|
src_iovs[0].iov_len = compressed_size;
|
||||||
|
rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
|
||||||
|
&src_iovs[0], 1, NULL, NULL, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
ut_seq.complete = false;
|
||||||
|
rc = spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
poll_threads();
|
||||||
|
|
||||||
|
CU_ASSERT_EQUAL(completed, 1);
|
||||||
|
CU_ASSERT(ut_seq.complete);
|
||||||
|
CU_ASSERT_EQUAL(ut_seq.status, 0);
|
||||||
|
CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
|
||||||
|
|
||||||
|
/* Put the decompress operation in the middle of a sequence with a copy operation at the
|
||||||
|
* beginning and a fill at the end modifying the first 2048B of the buffer.
|
||||||
|
*/
|
||||||
|
memset(expected, 0xfe, 2048);
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
seq = NULL;
|
||||||
|
completed = 0;
|
||||||
|
|
||||||
|
dst_iovs[0].iov_base = tmp[1];
|
||||||
|
dst_iovs[0].iov_len = compressed_size;
|
||||||
|
src_iovs[0].iov_base = tmp[0];
|
||||||
|
src_iovs[0].iov_len = compressed_size;
|
||||||
|
rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
|
||||||
|
&src_iovs[0], 1, NULL, NULL, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
dst_iovs[1].iov_base = buf;
|
||||||
|
dst_iovs[1].iov_len = sizeof(buf);
|
||||||
|
src_iovs[1].iov_base = tmp[1];
|
||||||
|
src_iovs[1].iov_len = compressed_size;
|
||||||
|
rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
|
||||||
|
&src_iovs[1], 1, NULL, NULL, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
rc = spdk_accel_append_fill(&seq, ioch, buf, 2048, NULL, NULL, 0xfe, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
ut_seq.complete = false;
|
||||||
|
rc = spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
poll_threads();
|
||||||
|
|
||||||
|
CU_ASSERT_EQUAL(completed, 3);
|
||||||
|
CU_ASSERT(ut_seq.complete);
|
||||||
|
CU_ASSERT_EQUAL(ut_seq.status, 0);
|
||||||
|
CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
|
||||||
|
|
||||||
|
/* Check sequence with decompress at the beginning: decompress -> copy */
|
||||||
|
memset(expected, 0xa5, sizeof(expected));
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
seq = NULL;
|
||||||
|
completed = 0;
|
||||||
|
|
||||||
|
dst_iovs[0].iov_base = tmp[1];
|
||||||
|
dst_iovs[0].iov_len = sizeof(tmp[1]);
|
||||||
|
src_iovs[0].iov_base = tmp[0];
|
||||||
|
src_iovs[0].iov_len = compressed_size;
|
||||||
|
rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
|
||||||
|
&src_iovs[0], 1, NULL, NULL, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
dst_iovs[1].iov_base = buf;
|
||||||
|
dst_iovs[1].iov_len = sizeof(buf);
|
||||||
|
src_iovs[1].iov_base = tmp[1];
|
||||||
|
src_iovs[1].iov_len = sizeof(tmp[1]);
|
||||||
|
rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
|
||||||
|
&src_iovs[1], 1, NULL, NULL, 0,
|
||||||
|
ut_sequence_step_cb, &completed);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
ut_seq.complete = false;
|
||||||
|
rc = spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
|
||||||
|
CU_ASSERT_EQUAL(rc, 0);
|
||||||
|
|
||||||
|
poll_threads();
|
||||||
|
|
||||||
|
CU_ASSERT_EQUAL(completed, 2);
|
||||||
|
CU_ASSERT(ut_seq.complete);
|
||||||
|
CU_ASSERT_EQUAL(ut_seq.status, 0);
|
||||||
|
CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
|
||||||
|
|
||||||
|
spdk_put_io_channel(ioch);
|
||||||
|
poll_threads();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_sequence_setup(void)
|
test_sequence_setup(void)
|
||||||
{
|
{
|
||||||
@ -1094,6 +1253,9 @@ main(int argc, char **argv)
|
|||||||
CU_ADD_TEST(seq_suite, test_sequence_abort);
|
CU_ADD_TEST(seq_suite, test_sequence_abort);
|
||||||
CU_ADD_TEST(seq_suite, test_sequence_append_error);
|
CU_ADD_TEST(seq_suite, test_sequence_append_error);
|
||||||
CU_ADD_TEST(seq_suite, test_sequence_completion_error);
|
CU_ADD_TEST(seq_suite, test_sequence_completion_error);
|
||||||
|
#ifdef SPDK_CONFIG_ISAL /* accel_sw requires isa-l for compression */
|
||||||
|
CU_ADD_TEST(seq_suite, test_sequence_decompress);
|
||||||
|
#endif
|
||||||
|
|
||||||
suite = CU_add_suite("accel", test_setup, test_cleanup);
|
suite = CU_add_suite("accel", test_setup, test_cleanup);
|
||||||
CU_ADD_TEST(suite, test_spdk_accel_task_complete);
|
CU_ADD_TEST(suite, test_spdk_accel_task_complete);
|
||||||
|
Loading…
Reference in New Issue
Block a user