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: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1590
Community-CI: Broadcom CI
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Ben Walker 2020-03-30 15:07:14 -07:00 committed by Tomasz Zawadzki
parent c8bdbc12c3
commit 50529593c4

View File

@ -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);
}