accel: add support for xor

Change-Id: I3c7461a7abfc64402929c0bb24f8458814d9c706
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16394
Community-CI: Mellanox Build Bot
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Artur Paszkiewicz 2022-10-04 15:15:52 +02:00 committed by Tomasz Zawadzki
parent 1ae6a83aa5
commit b41efae2c6
7 changed files with 112 additions and 6 deletions

View File

@ -2,6 +2,10 @@
## v23.05: (Upcoming Release)
### accel
Added API `spdk_accel_submit_xor` to perform XOR.
### bdev
A new API `spdk_bdev_module_claim_bdev_desc` was added. Unlike `spdk_bdev_module_claim_bdev`, this

View File

@ -42,7 +42,8 @@ enum accel_opcode {
ACCEL_OPC_DECOMPRESS = 7,
ACCEL_OPC_ENCRYPT = 8,
ACCEL_OPC_DECRYPT = 9,
ACCEL_OPC_LAST = 10,
ACCEL_OPC_XOR = 10,
ACCEL_OPC_LAST = 11,
};
/**
@ -298,6 +299,22 @@ int spdk_accel_submit_decompress(struct spdk_io_channel *ch, struct iovec *dst_i
size_t src_iovcnt, uint32_t *output_size, int flags,
spdk_accel_completion_cb cb_fn, void *cb_arg);
/**
* Submit an xor request.
*
* \param ch I/O channel associated with this call.
* \param dst Destination to write the data to.
* \param sources Array of source buffers.
* \param nsrcs Number of source buffers in the array.
* \param nbytes Length in bytes.
* \param cb_fn Called when this copy operation completes.
* \param cb_arg Callback argument.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_accel_submit_xor(struct spdk_io_channel *ch, void *dst, void **sources, uint32_t nsrcs,
uint64_t nbytes, spdk_accel_completion_cb cb_fn, void *cb_arg);
/** Object grouping multiple accel operations to be executed at the same point in time */
struct spdk_accel_sequence;

View File

@ -63,10 +63,16 @@ struct spdk_accel_task {
void *src_domain_ctx;
struct spdk_memory_domain *dst_domain;
void *dst_domain_ctx;
union {
struct {
struct iovec *iovs; /* iovs passed by the caller */
uint32_t iovcnt; /* iovcnt passed by the caller */
} s;
struct {
void **srcs;
uint32_t cnt;
} nsrcs;
};
union {
struct {
struct iovec *iovs; /* iovs passed by the caller */

View File

@ -65,7 +65,7 @@ static struct spdk_accel_driver *g_accel_driver;
static const char *g_opcode_strings[ACCEL_OPC_LAST] = {
"copy", "fill", "dualcast", "compare", "crc32c", "copy_crc32c",
"compress", "decompress", "encrypt", "decrypt"
"compress", "decompress", "encrypt", "decrypt", "xor"
};
enum accel_sequence_state {
@ -695,6 +695,34 @@ spdk_accel_submit_decrypt(struct spdk_io_channel *ch, struct spdk_accel_crypto_k
return module->submit_tasks(module_ch, accel_task);
}
int
spdk_accel_submit_xor(struct spdk_io_channel *ch, void *dst, void **sources, uint32_t nsrcs,
uint64_t nbytes, 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;
struct spdk_accel_module_if *module = g_modules_opc[ACCEL_OPC_XOR].module;
struct spdk_io_channel *module_ch = accel_ch->module_ch[ACCEL_OPC_XOR];
accel_task = _get_task(accel_ch, cb_fn, cb_arg);
if (accel_task == NULL) {
return -ENOMEM;
}
accel_task->nsrcs.srcs = sources;
accel_task->nsrcs.cnt = nsrcs;
accel_task->d.iovs = &accel_task->aux_iovs[SPDK_ACCEL_AUX_IOV_DST];
accel_task->d.iovs[0].iov_base = dst;
accel_task->d.iovs[0].iov_len = nbytes;
accel_task->d.iovcnt = 1;
accel_task->op_code = ACCEL_OPC_XOR;
accel_task->src_domain = NULL;
accel_task->dst_domain = NULL;
accel_task->step_cb_fn = NULL;
return module->submit_tasks(module_ch, accel_task);
}
static inline struct accel_buffer *
accel_get_buf(struct accel_io_channel *ch, uint64_t len)
{

View File

@ -16,6 +16,7 @@
#include "spdk/json.h"
#include "spdk/crc32.h"
#include "spdk/util.h"
#include "spdk/xor.h"
#ifdef SPDK_CONFIG_PMDK
#include "libpmem.h"
@ -98,6 +99,7 @@ sw_accel_supports_opcode(enum accel_opcode opc)
case ACCEL_OPC_DECOMPRESS:
case ACCEL_OPC_ENCRYPT:
case ACCEL_OPC_DECRYPT:
case ACCEL_OPC_XOR:
return true;
default:
return false;
@ -510,6 +512,15 @@ _sw_accel_decrypt(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *acc
return _sw_accel_crypto_operation(accel_task, key, key_data->decrypt);
}
static int
_sw_accel_xor(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
{
return spdk_xor_gen(accel_task->d.iovs[0].iov_base,
accel_task->nsrcs.srcs,
accel_task->nsrcs.cnt,
accel_task->d.iovs[0].iov_len);
}
static int
sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_task)
{
@ -566,6 +577,9 @@ sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_
case ACCEL_OPC_DECOMPRESS:
rc = _sw_accel_decompress(sw_ch, accel_task);
break;
case ACCEL_OPC_XOR:
rc = _sw_accel_xor(sw_ch, accel_task);
break;
case ACCEL_OPC_ENCRYPT:
rc = _sw_accel_encrypt(sw_ch, accel_task);
break;

View File

@ -17,6 +17,7 @@
spdk_accel_submit_decompress;
spdk_accel_submit_encrypt;
spdk_accel_submit_decrypt;
spdk_accel_submit_xor;
spdk_accel_get_opc_module_name;
spdk_accel_assign_opc;
spdk_accel_write_config_json;

View File

@ -507,6 +507,41 @@ test_spdk_accel_submit_copy_crc32c(void)
CU_ASSERT(expected_accel_task == &task);
}
static void
test_spdk_accel_submit_xor(void)
{
const uint64_t nbytes = TEST_SUBMIT_SIZE;
uint8_t dst[TEST_SUBMIT_SIZE] = {0};
uint8_t src1[TEST_SUBMIT_SIZE] = {0};
uint8_t src2[TEST_SUBMIT_SIZE] = {0};
void *sources[] = { src1, src2 };
uint32_t nsrcs = SPDK_COUNTOF(sources);
int rc;
struct spdk_accel_task task;
struct spdk_accel_task *expected_accel_task = NULL;
TAILQ_INIT(&g_accel_ch->task_pool);
/* Fail with no tasks on _get_task() */
rc = spdk_accel_submit_xor(g_ch, dst, sources, nsrcs, nbytes, NULL, NULL);
CU_ASSERT(rc == -ENOMEM);
TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
/* submission OK. */
rc = spdk_accel_submit_xor(g_ch, dst, sources, nsrcs, nbytes, NULL, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(task.nsrcs.srcs == sources);
CU_ASSERT(task.nsrcs.cnt == nsrcs);
CU_ASSERT(task.d.iovcnt == 1);
CU_ASSERT(task.d.iovs[0].iov_base == dst);
CU_ASSERT(task.d.iovs[0].iov_len == nbytes);
CU_ASSERT(task.op_code == ACCEL_OPC_XOR);
expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
CU_ASSERT(expected_accel_task == &task);
}
static void
test_spdk_accel_module_find_by_name(void)
{
@ -3183,6 +3218,7 @@ main(int argc, char **argv)
CU_ADD_TEST(suite, test_spdk_accel_submit_crc32c);
CU_ADD_TEST(suite, test_spdk_accel_submit_crc32cv);
CU_ADD_TEST(suite, test_spdk_accel_submit_copy_crc32c);
CU_ADD_TEST(suite, test_spdk_accel_submit_xor);
CU_ADD_TEST(suite, test_spdk_accel_module_find_by_name);
CU_ADD_TEST(suite, test_spdk_accel_module_register);