From 9abd8becc5271a70487a0d709b3644d64d7bc7b8 Mon Sep 17 00:00:00 2001 From: Andrey Kuzmin Date: Wed, 6 Jun 2018 16:46:13 +0300 Subject: [PATCH] Avoid scheduling removal of the same bdev descriptor multiple times. Deferred descriptor removal invocation under bdev_unregister() does not account for the possibility of bdev_unregister being entered multiple times for the same bdev (which is possible thanks to multiple paths to unregistration - consider bdev hotremove callback and _spdk_bdev_finish_unregister_bdevs_iter iterator - being present). Therefore, currently nothing prevents _remove_notify for the same bdev descriptor from being scheduled multiple times. This commit adds boolean remove_scheduled field to struct spdk_bdev_desc. The value is set when remove_notify for the descriptor is being scheduled for the first time, and checked on subsequent attempts. Change-Id: If2c5a365c05c4123c50edf5a2db164be9dd26f8e Signed-off-by: Andrey Kuzmin Reviewed-on: https://review.gerrithub.io/415319 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/bdev/bdev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index eadd94c7b..e6d974eaf 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -240,6 +240,7 @@ struct spdk_bdev_desc { struct spdk_bdev *bdev; spdk_bdev_remove_cb_t remove_cb; void *remove_ctx; + bool remove_scheduled; bool write; TAILQ_ENTRY(spdk_bdev_desc) link; }; @@ -2912,7 +2913,11 @@ spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void * we don't recursively unregister this bdev again if the remove_cb * immediately closes its descriptor. */ - spdk_thread_send_msg(thread, _remove_notify, desc); + if (!desc->remove_scheduled) { + /* Avoid scheduling removal of the same descriptor multiple times. */ + desc->remove_scheduled = true; + spdk_thread_send_msg(thread, _remove_notify, desc); + } } }