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:
parent
60af3c00d8
commit
aa4b4e17f3
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user