From 250566568a8614d4ab70dbb48c07dc20c33c5fba Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Tue, 21 Feb 2023 15:02:47 +0100 Subject: [PATCH] bdev: delay reset until accel/memory domain ops completion These operations are handled internally by the bdev layer, so it should first wait until they're completed before issuing reset to a bdev module. Signed-off-by: Konrad Sztyber Change-Id: I74f0d42dcb9a289aa7c3115ca309cb92870548e2 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17019 Reviewed-by: Ben Walker Community-CI: Mellanox Build Bot Reviewed-by: Aleksey Marchuk Tested-by: SPDK CI Jenkins --- lib/bdev/bdev.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index b6307a96b..a2d891d7c 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -3308,8 +3308,15 @@ _bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io) static inline void _bdev_io_submit_ext(struct spdk_bdev_desc *desc, struct spdk_bdev_io *bdev_io) { + struct spdk_bdev_channel *ch = bdev_io->internal.ch; bool needs_exec = bdev_io_needs_sequence_exec(desc, bdev_io); + if (spdk_unlikely(ch->flags & BDEV_CH_RESET_IN_PROGRESS)) { + bdev_io->internal.status = SPDK_BDEV_IO_STATUS_ABORTED; + bdev_io_complete_unsubmitted(bdev_io); + return; + } + /* We need to allocate bounce buffer if bdev doesn't support memory domains, or if it does * support them, but we need to execute an accel sequence and the data buffer is from accel * memory domain (to avoid doing a push/pull from that domain). @@ -5974,10 +5981,18 @@ bdev_reset_check_outstanding_io_done(struct spdk_bdev *bdev, void *_ctx, int sta bdev_io->u.reset.wait_poller.poller = SPDK_POLLER_REGISTER(bdev_reset_poll_for_outstanding_io, ch, BDEV_RESET_CHECK_OUTSTANDING_IO_PERIOD); } else { - /* If outstanding IOs are still present and reset_io_drain_timeout seconds passed, - * start the reset. */ TAILQ_REMOVE(&ch->queued_resets, bdev_io, internal.link); - bdev_io_submit_reset(bdev_io); + + if (TAILQ_EMPTY(&ch->io_memory_domain) && TAILQ_EMPTY(&ch->io_accel_exec)) { + /* If outstanding IOs are still present and reset_io_drain_timeout + * seconds passed, start the reset. */ + bdev_io_submit_reset(bdev_io); + } else { + /* We still have in progress memory domain pull/push or we're + * executing accel sequence. Since we cannot abort either of those + * operaions, fail the reset request. */ + spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); + } } } else { TAILQ_REMOVE(&ch->queued_resets, bdev_io, internal.link); @@ -5996,7 +6011,9 @@ bdev_reset_check_outstanding_io(struct spdk_bdev_channel_iter *i, struct spdk_bd struct spdk_bdev_channel *cur_ch = __io_ch_to_bdev_ch(io_ch); int status = 0; - if (cur_ch->io_outstanding > 0) { + if (cur_ch->io_outstanding > 0 || + !TAILQ_EMPTY(&cur_ch->io_memory_domain) || + !TAILQ_EMPTY(&cur_ch->io_accel_exec)) { /* If a channel has outstanding IO, set status to -EBUSY code. This will stop * further iteration over the rest of the channels and pass non-zero status * to the callback function. */