bdev/crypto: complete IOs on ENOMEM from accel
spdk_bdev_queue_io_wait() can only be used when one of bdev submission functions returns ENOMEM (i.e. there are no more spdk_bdev_ios on that IO channel). Using it in any other case, e.g. on spdk_accel_append_*() returning ENOMEM, will most likely result in failure. Therefore, to avoid that, the IOs are completed with NOMEM status relying on the bdev layer to retry them. Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: Ie0f03496e5d3180c481815b3f1b021e74ae2f46d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17319 Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
31bfcb45b7
commit
3824f6e39b
@ -44,7 +44,6 @@ struct crypto_io_channel {
|
||||
};
|
||||
|
||||
enum crypto_io_resubmit_state {
|
||||
CRYPTO_IO_NEW, /* Resubmit IO from the scratch */
|
||||
CRYPTO_IO_DECRYPT_DONE, /* Appended decrypt, need to read */
|
||||
CRYPTO_IO_ENCRYPT_DONE, /* Need to write */
|
||||
};
|
||||
@ -164,7 +163,7 @@ crypto_encrypt(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io
|
||||
crypto_io->aux_domain, crypto_io->aux_domain_ctx);
|
||||
if (rc == -ENOMEM) {
|
||||
SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
|
||||
vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
|
||||
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
|
||||
} else {
|
||||
SPDK_ERRLOG("Failed to submit bdev_io!\n");
|
||||
crypto_io_fail(crypto_io);
|
||||
@ -193,14 +192,8 @@ vbdev_crypto_resubmit_io(void *arg)
|
||||
{
|
||||
struct spdk_bdev_io *bdev_io = (struct spdk_bdev_io *)arg;
|
||||
struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
|
||||
struct spdk_io_channel *ch;
|
||||
|
||||
switch (crypto_io->resubmit_state) {
|
||||
case CRYPTO_IO_NEW:
|
||||
assert(crypto_io->crypto_ch);
|
||||
ch = spdk_io_channel_from_ctx(crypto_io->crypto_ch);
|
||||
vbdev_crypto_submit_request(ch, bdev_io);
|
||||
break;
|
||||
case CRYPTO_IO_ENCRYPT_DONE:
|
||||
crypto_write(crypto_io->crypto_ch, bdev_io);
|
||||
break;
|
||||
@ -223,9 +216,6 @@ vbdev_crypto_queue_io(struct spdk_bdev_io *bdev_io, enum crypto_io_resubmit_stat
|
||||
crypto_io->bdev_io_wait.cb_arg = bdev_io;
|
||||
crypto_io->resubmit_state = state;
|
||||
|
||||
/* TODO: We shouldn't use spdk_bdev_queue_io_wait() for queueing IOs due to receiving ENOMEM
|
||||
* from anything other than one of the bdev functions (e.g. accel). We should have a
|
||||
* different mechanism for handling such requests. */
|
||||
rc = spdk_bdev_queue_io_wait(bdev_io->bdev, crypto_io->crypto_ch->base_ch,
|
||||
&crypto_io->bdev_io_wait);
|
||||
if (rc != 0) {
|
||||
@ -294,7 +284,7 @@ crypto_read_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
|
||||
if (rc != 0) {
|
||||
if (rc == -ENOMEM) {
|
||||
SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
|
||||
vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
|
||||
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
|
||||
} else {
|
||||
SPDK_ERRLOG("Failed to submit bdev_io!\n");
|
||||
crypto_io_fail(crypto_io);
|
||||
@ -371,7 +361,7 @@ vbdev_crypto_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bde
|
||||
if (rc != 0) {
|
||||
if (rc == -ENOMEM) {
|
||||
SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
|
||||
vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
|
||||
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
|
||||
} else {
|
||||
SPDK_ERRLOG("Failed to submit bdev_io!\n");
|
||||
crypto_io_fail(crypto_io);
|
||||
|
@ -49,17 +49,21 @@ update_stats() {
|
||||
stats[copy_executed]=$(get_stat executed copy)
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
tgtcleanup() {
|
||||
[[ -v input ]] && rm -f "$input" || :
|
||||
[[ -v output ]] && rm -f "$output" || :
|
||||
nvmftestfini
|
||||
}
|
||||
|
||||
bperfcleanup() {
|
||||
[[ -v bperfpid ]] && killprocess $bperfpid
|
||||
}
|
||||
|
||||
nvmftestinit
|
||||
nvmfappstart -m 0x2
|
||||
|
||||
input=$(mktemp) output=$(mktemp)
|
||||
trap 'cleanup; exit 1' SIGINT SIGTERM EXIT
|
||||
trap 'tgtcleanup; exit 1' SIGINT SIGTERM EXIT
|
||||
|
||||
rpc_cmd <<- CONFIG
|
||||
bdev_malloc_create 32 4096 -b malloc0
|
||||
@ -115,4 +119,27 @@ spdk_dd --of "$output" --ib Nvme0n1 --bs 4096 --count 16
|
||||
cmp "$input" "$output"
|
||||
|
||||
trap - SIGINT SIGTERM EXIT
|
||||
cleanup
|
||||
tgtcleanup
|
||||
|
||||
# Verify bdev crypto ENOMEM handling by setting low accel task count and sending IO with high qd
|
||||
trap 'bperfcleanup; exit 1' SIGINT SIGTERM EXIT
|
||||
|
||||
"$rootdir/build/examples/bdevperf" -t 5 -w verify -o 4096 -q 256 --wait-for-rpc -z &
|
||||
bperfpid=$!
|
||||
|
||||
waitforlisten $bperfpid
|
||||
rpc_cmd <<- CONFIG
|
||||
accel_set_options --task-count 16
|
||||
framework_start_init
|
||||
bdev_malloc_create 32 4096 -b malloc0
|
||||
accel_crypto_key_create -c AES_XTS -k "${key0[0]}" -e "${key0[1]}" -n key0
|
||||
accel_crypto_key_create -c AES_XTS -k "${key1[0]}" -e "${key1[1]}" -n key1
|
||||
bdev_crypto_create malloc0 crypto0 -n key0
|
||||
bdev_crypto_create crypto0 crypto1 -n key1
|
||||
CONFIG
|
||||
|
||||
"$rootdir/examples/bdev/bdevperf/bdevperf.py" perform_tests
|
||||
|
||||
trap - SIGINT SIGTERM EXIT
|
||||
killprocess $bperfpid
|
||||
wait $bperfpid
|
||||
|
@ -254,13 +254,10 @@ test_error_paths(void)
|
||||
|
||||
/* test error returned by accel fw */
|
||||
MOCK_SET(spdk_accel_append_encrypt, -ENOMEM);
|
||||
g_completion_called = false;
|
||||
vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
|
||||
CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io);
|
||||
CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_NEW);
|
||||
memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait));
|
||||
CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_NOMEM);
|
||||
CU_ASSERT(g_completion_called);
|
||||
|
||||
MOCK_SET(spdk_accel_append_encrypt, -EINVAL);
|
||||
vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
|
||||
@ -328,15 +325,12 @@ test_error_paths(void)
|
||||
/* test error returned by accel fw */
|
||||
g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
|
||||
MOCK_SET(spdk_accel_append_decrypt, -ENOMEM);
|
||||
g_completion_called = false;
|
||||
vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
|
||||
poll_threads();
|
||||
CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io);
|
||||
CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io);
|
||||
CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_NEW);
|
||||
memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait));
|
||||
CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_NOMEM);
|
||||
CU_ASSERT(g_completion_called);
|
||||
MOCK_SET(spdk_accel_append_decrypt, 0);
|
||||
g_completion_called = false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user