From 80161622b8d69606d05e570e70ef64ca03dd3448 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Thu, 15 Jun 2017 07:09:19 -0700 Subject: [PATCH] bdev: defer completion on resets This ensures a reset is completed after any I/O completions that may have been deferred. Signed-off-by: Jim Harris Change-Id: I9efe5c07435371ff8c8e0c826349e9349ade02f3 Reviewed-on: https://review.gerrithub.io/365663 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Daniel Verkamp --- include/spdk_internal/bdev.h | 5 +++++ lib/bdev/bdev.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 7960e3f5c..ba88f19a7 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -333,6 +333,11 @@ struct spdk_bdev_io { */ bool in_submit_request; + /** + * Set to true when the a bdev_io's callback routine should be deferred after completion. + */ + bool defer_callback; + /** Used in virtual device (e.g., RAID), indicates its parent spdk_bdev_io */ struct spdk_bdev_io *parent; diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 9f755b783..a306dd8df 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -993,6 +993,7 @@ spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch, bdev_io->ch = channel; bdev_io->type = SPDK_BDEV_IO_TYPE_RESET; + bdev_io->defer_callback = true; spdk_bdev_io_init(bdev_io, bdev, cb_arg, cb); /* First, abort all I/O queued up waiting for buffers. */ @@ -1137,10 +1138,15 @@ spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status sta bdev_io->status = status; if (bdev_io->in_submit_request) { + bdev_io->defer_callback = true; + } + + if (bdev_io->defer_callback) { /* * Defer completion to avoid potential infinite recursion if the * user's completion callback issues a new I/O. */ + bdev_io->defer_callback = false; spdk_thread_send_msg(spdk_io_channel_get_thread(bdev_io->ch->channel), bdev_io_deferred_completion, bdev_io); return;