nbd: Continue revising the nbd subsystem fini logic

After carefully checking the code, spdk_nbd_stop should
be called in the same spdk thread which creates the io_channel.
Usually, the spdk thread which handles the rpc call should be
same with the thread which finalizes the thread. But it could
be different. So adding another async call to make sure we should
call spdk_nbd_stop on the same spdk thread.

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
Change-Id: I276eb35e78b930d31869f10137712a78aaee71ed
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5705
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: <dongx.yi@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Ziye Yang 2020-12-28 23:00:51 +08:00 committed by Tomasz Zawadzki
parent 60af3c00d8
commit aa4b4e17f3

View File

@ -123,6 +123,8 @@ static struct spdk_nbd_disk_globals g_spdk_nbd;
static spdk_nbd_fini_cb g_fini_cb_fn; static spdk_nbd_fini_cb g_fini_cb_fn;
static void *g_fini_cb_arg; static void *g_fini_cb_arg;
static void _nbd_fini(void *arg1);
static int static int
nbd_submit_bdev_io(struct spdk_nbd_disk *nbd, struct nbd_io *io); nbd_submit_bdev_io(struct spdk_nbd_disk *nbd, struct nbd_io *io);
@ -134,29 +136,38 @@ spdk_nbd_init(void)
return 0; return 0;
} }
static void
_nbd_stop_async(void *arg)
{
struct spdk_nbd_disk *nbd = arg;
int rc;
rc = spdk_nbd_stop(nbd);
if (rc) {
/* spdk_nbd_stop failed because some IO are still executing. Send a message
* to this thread to try again later. */
spdk_thread_send_msg(spdk_get_thread(),
_nbd_stop_async, nbd);
} else {
_nbd_fini(NULL);
}
}
static void static void
_nbd_fini(void *arg1) _nbd_fini(void *arg1)
{ {
struct spdk_nbd_disk *nbd_idx, *nbd_tmp; struct spdk_nbd_disk *nbd_first;
int rc = 0;
/* nbd_first = TAILQ_FIRST(&g_spdk_nbd.disk_head);
* Stop running spdk_nbd_disk. if (nbd_first) {
* Here, nbd removing are unnecessary, but _SAFE variant /* Stop running spdk_nbd_disk */
* is needed, since internal nbd_disk_unregister will spdk_thread_send_msg(spdk_io_channel_get_thread(nbd_first->ch),
* remove nbd from TAILQ. _nbd_stop_async, nbd_first);
*/
TAILQ_FOREACH_SAFE(nbd_idx, &g_spdk_nbd.disk_head, tailq, nbd_tmp) {
rc = spdk_nbd_stop(nbd_idx);
if (rc) {
break;
}
}
if (!rc) {
g_fini_cb_fn(g_fini_cb_arg);
} else { } else {
spdk_thread_send_msg(spdk_get_thread(), _nbd_fini, NULL); /* We can directly call final function here, because
spdk_subsystem_fini_next handles the case: current thread does not equal
to g_final_thread */
g_fini_cb_fn(g_fini_cb_arg);
} }
} }