Commit aa4b4e17 authored by Ziye Yang's avatar Ziye Yang Committed by Tomasz Zawadzki
Browse files

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: default avatarZiye 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatar <dongx.yi@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 60af3c00
Loading
Loading
Loading
Loading
+28 −17
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ static struct spdk_nbd_disk_globals g_spdk_nbd;
static spdk_nbd_fini_cb g_fini_cb_fn;
static void *g_fini_cb_arg;

static void _nbd_fini(void *arg1);

static int
nbd_submit_bdev_io(struct spdk_nbd_disk *nbd, struct nbd_io *io);

@@ -135,28 +137,37 @@ spdk_nbd_init(void)
}

static void
_nbd_fini(void *arg1)
_nbd_stop_async(void *arg)
{
	struct spdk_nbd_disk *nbd_idx, *nbd_tmp;
	int rc = 0;
	struct spdk_nbd_disk *nbd = arg;
	int rc;

	/*
	 * Stop running spdk_nbd_disk.
	 * Here, nbd removing are unnecessary, but _SAFE variant
	 * is needed, since internal nbd_disk_unregister will
	 * remove nbd from TAILQ.
	 */
	TAILQ_FOREACH_SAFE(nbd_idx, &g_spdk_nbd.disk_head, tailq, nbd_tmp) {
		rc = spdk_nbd_stop(nbd_idx);
	rc = spdk_nbd_stop(nbd);
	if (rc) {
			break;
		/* 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);
	}
}

	if (!rc) {
		g_fini_cb_fn(g_fini_cb_arg);
static void
_nbd_fini(void *arg1)
{
	struct spdk_nbd_disk *nbd_first;

	nbd_first = TAILQ_FIRST(&g_spdk_nbd.disk_head);
	if (nbd_first) {
		/* Stop running spdk_nbd_disk */
		spdk_thread_send_msg(spdk_io_channel_get_thread(nbd_first->ch),
				     _nbd_stop_async, nbd_first);
	} 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);
	}
}