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:
parent
c8bdbc12c3
commit
50529593c4
@ -521,16 +521,50 @@ bdev_iscsi_create_cb(void *io_device, void *ctx_buf)
|
|||||||
return 0;
|
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
|
static void
|
||||||
bdev_iscsi_destroy_cb(void *io_device, void *ctx_buf)
|
bdev_iscsi_destroy_cb(void *io_device, void *ctx_buf)
|
||||||
{
|
{
|
||||||
struct bdev_iscsi_lun *lun = io_device;
|
struct bdev_iscsi_lun *lun = io_device;
|
||||||
|
struct spdk_thread *thread;
|
||||||
|
|
||||||
pthread_mutex_lock(&lun->mutex);
|
pthread_mutex_lock(&lun->mutex);
|
||||||
lun->ch_count--;
|
lun->ch_count--;
|
||||||
if (lun->ch_count == 0) {
|
if (lun->ch_count == 0) {
|
||||||
assert(lun->master_td != NULL);
|
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;
|
lun->master_td = NULL;
|
||||||
spdk_poller_unregister(&lun->poller);
|
spdk_poller_unregister(&lun->poller);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user