Commit 50529593 authored by Ben Walker's avatar Ben Walker Committed by Tomasz Zawadzki
Browse files

bdev/iscsi: Release lun poller on correct thread.



If thread A is the first to grab a channel, the poller will be on thread
A. But then if the shutdown happens such that thread B is the final
channel to release it's channel, it will attempt to free the lun poller
from thread B and crash.

Change-Id: I354f9f28d55e5e82cb6c737c734acadbd80e283d
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1590


Community-CI: Broadcom CI
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent c8bdbc12
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -521,16 +521,50 @@ bdev_iscsi_create_cb(void *io_device, void *ctx_buf)
	return 0;
}

static void
_iscsi_destroy_cb(void *ctx)
{
	struct bdev_iscsi_lun *lun = ctx;

	pthread_mutex_lock(&lun->mutex);

	assert(lun->master_td == spdk_get_thread());
	assert(lun->ch_count > 0);

	lun->ch_count--;
	if (lun->ch_count > 0) {
		pthread_mutex_unlock(&lun->mutex);
		return;
	}

	lun->master_td = NULL;
	spdk_poller_unregister(&lun->poller);

	pthread_mutex_unlock(&lun->mutex);
}

static void
bdev_iscsi_destroy_cb(void *io_device, void *ctx_buf)
{
	struct bdev_iscsi_lun *lun = io_device;
	struct spdk_thread *thread;

	pthread_mutex_lock(&lun->mutex);
	lun->ch_count--;
	if (lun->ch_count == 0) {
		assert(lun->master_td != NULL);

		if (lun->master_td != spdk_get_thread()) {
			/* The final channel was destroyed on a different thread
			 * than where the first channel was created. Pass a message
			 * to the master thread to unregister the poller. */
			lun->ch_count++;
			thread = lun->master_td;
			pthread_mutex_unlock(&lun->mutex);
			spdk_thread_send_msg(thread, _iscsi_destroy_cb, lun);
			return;
		}

		lun->master_td = NULL;
		spdk_poller_unregister(&lun->poller);
	}