From 6146c6785690a72bff8488a50ffe5c8116e3d86d Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 15 Jan 2020 00:21:50 -0500 Subject: [PATCH] lib/thread: Assert if spdk_poller_unregister() is called on wrong thread Bdevperf tool had not called spdk_poller_unregister() called on the same thread that called spdk_poller_register(). But it had not caused any issue because spdk_poller_unregister() simply set the state to unregistered. This design flaw has been fixed recently. However the new pause feature has been added to poller and this design flaw might cause any unexpected behavior if paused poller is unregistered. We do not know any other case such that spdk_poller_unregister() is not called on the same thread that called spdk_poller_register(), but we have no way to know it even if it exists. Hence let's add assert for such cases. Parsing poller lists managed by thread may be another option but spdk_poller_unregister() is performance critical. So we do not check list. Signed-off-by: Shuhei Matsumoto Change-Id: I9d91daaeb81fa33d5f042dbe7ddbd8ab6ea98d55 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479391 Tested-by: SPDK CI Jenkins Community-CI: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Alexey Marchuk Reviewed-by: Ben Walker Reviewed-by: Changpeng Liu --- lib/thread/thread.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/thread/thread.c b/lib/thread/thread.c index b6e855037..8964d4236 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -111,6 +111,7 @@ struct spdk_poller { uint64_t next_run_tick; spdk_poller_fn fn; void *arg; + struct spdk_thread *thread; }; struct spdk_thread { @@ -789,6 +790,7 @@ spdk_poller_register(spdk_poller_fn fn, poller->state = SPDK_POLLER_STATE_WAITING; poller->fn = fn; poller->arg = arg; + poller->thread = thread; if (period_microseconds) { quotient = period_microseconds / SPDK_SEC_TO_USEC; @@ -824,6 +826,12 @@ spdk_poller_unregister(struct spdk_poller **ppoller) return; } + if (poller->thread != thread) { + SPDK_ERRLOG("different from the thread that called spdk_poller_register()\n"); + assert(false); + return; + } + /* If the poller was paused, put it on the active_pollers list so that * its unregistration can be processed by spdk_thread_poll(). */