vhost-scsi: Reduce vhost_scsi_mutex use
We on longer need to hold the vhost_scsi_mutex the entire time we set/clear the endpoint. The tv_tpg_mutex handles tpg accesses not related to the tpg list, the port link/unlink functions use the tv_tpg_mutex while accessing the tpg->vhost_scsi pointer, vhost_scsi_do_plug will no longer queue events after the virtqueue's backend has been cleared and flushed, and we don't drop our refcount to the tpg until after we have stopped cmds and wait for outstanding cmds to complete. This moves the vhost_scsi_mutex use to it's documented use of being used to access the tpg list. We then don't need to hold it while a flush is being performed causing other device's vhost_scsi_set_endpoint and vhost_scsi_make_tpg/vhost_scsi_drop_tpg calls to have to wait on a flakey device. Signed-off-by: Mike Christie <michael.christie@oracle.com> Message-Id: <20230321020624.13323-8-michael.christie@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f5ed6f9e82
commit
bea273c7a8
|
@ -229,7 +229,10 @@ struct vhost_scsi_ctx {
|
|||
struct iov_iter out_iter;
|
||||
};
|
||||
|
||||
/* Global spinlock to protect vhost_scsi TPG list for vhost IOCTL access */
|
||||
/*
|
||||
* Global mutex to protect vhost_scsi TPG list for vhost IOCTLs and LIO
|
||||
* configfs management operations.
|
||||
*/
|
||||
static DEFINE_MUTEX(vhost_scsi_mutex);
|
||||
static LIST_HEAD(vhost_scsi_list);
|
||||
|
||||
|
@ -1526,7 +1529,7 @@ out:
|
|||
* vhost_scsi_tpg with an active struct vhost_scsi_nexus
|
||||
*
|
||||
* The lock nesting rule is:
|
||||
* vhost_scsi_mutex -> vs->dev.mutex -> tpg->tv_tpg_mutex -> vq->mutex
|
||||
* vs->dev.mutex -> vhost_scsi_mutex -> tpg->tv_tpg_mutex -> vq->mutex
|
||||
*/
|
||||
static int
|
||||
vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
||||
|
@ -1540,7 +1543,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
|||
int index, ret, i, len;
|
||||
bool match = false;
|
||||
|
||||
mutex_lock(&vhost_scsi_mutex);
|
||||
mutex_lock(&vs->dev.mutex);
|
||||
|
||||
/* Verify that ring has been setup correctly. */
|
||||
|
@ -1561,6 +1563,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
|||
if (vs->vs_tpg)
|
||||
memcpy(vs_tpg, vs->vs_tpg, len);
|
||||
|
||||
mutex_lock(&vhost_scsi_mutex);
|
||||
list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
|
||||
mutex_lock(&tpg->tv_tpg_mutex);
|
||||
if (!tpg->tpg_nexus) {
|
||||
|
@ -1576,6 +1579,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
|||
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
|
||||
if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
|
||||
mutex_unlock(&tpg->tv_tpg_mutex);
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
ret = -EEXIST;
|
||||
goto undepend;
|
||||
}
|
||||
|
@ -1590,6 +1594,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
|||
if (ret) {
|
||||
pr_warn("target_depend_item() failed: %d\n", ret);
|
||||
mutex_unlock(&tpg->tv_tpg_mutex);
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
goto undepend;
|
||||
}
|
||||
tpg->tv_tpg_vhost_count++;
|
||||
|
@ -1599,6 +1604,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
|
|||
}
|
||||
mutex_unlock(&tpg->tv_tpg_mutex);
|
||||
}
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
|
||||
if (match) {
|
||||
memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn,
|
||||
|
@ -1654,7 +1660,6 @@ undepend:
|
|||
kfree(vs_tpg);
|
||||
out:
|
||||
mutex_unlock(&vs->dev.mutex);
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1670,7 +1675,6 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
|
|||
int index, ret, i;
|
||||
u8 target;
|
||||
|
||||
mutex_lock(&vhost_scsi_mutex);
|
||||
mutex_lock(&vs->dev.mutex);
|
||||
/* Verify that ring has been setup correctly. */
|
||||
for (index = 0; index < vs->dev.nvqs; ++index) {
|
||||
|
@ -1757,12 +1761,10 @@ free_vs_tpg:
|
|||
vs->vs_tpg = NULL;
|
||||
WARN_ON(vs->vs_events_nr);
|
||||
mutex_unlock(&vs->dev.mutex);
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
return 0;
|
||||
|
||||
err_dev:
|
||||
mutex_unlock(&vs->dev.mutex);
|
||||
mutex_unlock(&vhost_scsi_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue