Commit e1c0c4c7 authored by Darek Stojaczyk's avatar Darek Stojaczyk Committed by Jim Harris
Browse files

vhost/scsi: fix starting a session while SCSI targets are hotplugged



Vhost sessions currently inherit the SCSI target
status from their vhost devices when started. So
if a session is started while an asynchronous SCSI
target hotplug is in progress, the newly started
session will inherit the VHOST_SCSI_DEV_ADDING
state, which was not meant to be used in sessions
and will likely cause vhost to misbehave. The
ADDING status is used by the entire vhost device
to indicate that some sessions are still hotplugging
the SCSI target and that target can't be hotremoved
just yet. The sessions set their targets' state to
PRESENT when hotplugging them, so newly started
sessions should do the same.

This patch also prevents the same SCSI target to be
hotplugged twice to a single session. It wouldn't
cause any problems, but some resources could've been
leaked.

Change-Id: Icdbff78c167fc1f2f65137087334bd5512e81546
Signed-off-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/450052


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 2fcc09ec
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -946,15 +946,14 @@ spdk_vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev,
		return 0;
	}

	if (vsession->lcore == -1) {
	svsession = (struct spdk_vhost_scsi_session *)vsession;
	session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];
	if (vsession->lcore == -1 || session_sdev->dev != NULL) {
		/* Nothing to do. */
		return 0;
	}

	svsession = (struct spdk_vhost_scsi_session *)vsession;
	vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num];
	session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];

	session_sdev->dev = vhost_sdev->dev;
	session_sdev->status = VHOST_SCSI_DEV_PRESENT;

@@ -1333,7 +1332,7 @@ spdk_vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,

		assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY);
		svsession->scsi_dev_state[i].dev = state->dev;
		svsession->scsi_dev_state[i].status = state->status;
		svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT;
		rc = spdk_scsi_dev_allocate_io_channels(state->dev);
		if (rc != 0) {
			SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n", vdev->name, i);