Commit 31177e64 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Ben Walker
Browse files

bdev/virtio: defer ctrlr removal if scan I/O is in progress



A public API to remove a virtio
controller is about to be published
soon. Hence, we need to cover all
possible corner-cases where calling
it could cause a segfault.

Change-Id: I804cc0bee4a60ab8fc159bb98b7712cc258117f3
Signed-off-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/392271


Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 8b0f049e
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -695,8 +695,12 @@ bdev_virtio_poll(void *arg)

	cnt = virtio_recv_pkts(ch->vq, (void **)io, io_len, SPDK_COUNTOF(io));
	for (i = 0; i < cnt; ++i) {
		if (spdk_unlikely(svdev->scan_ctx &&
				  io[i] == &svdev->scan_ctx->io_ctx)) {
		if (spdk_unlikely(svdev->scan_ctx && io[i] == &svdev->scan_ctx->io_ctx)) {
			if (svdev->removed) {
				_virtio_scsi_dev_scan_finish(svdev->scan_ctx, -EINTR);
				return;
			}

			process_scan_resp(svdev->scan_ctx);
			continue;
		}
@@ -704,7 +708,14 @@ bdev_virtio_poll(void *arg)
		bdev_virtio_io_cpl(io[i]);
	}

	if (spdk_unlikely(cnt > 0 && svdev->scan_ctx && svdev->scan_ctx->needs_resend)) {
	if (spdk_unlikely(svdev->scan_ctx && svdev->scan_ctx->needs_resend)) {
		if (svdev->removed) {
			_virtio_scsi_dev_scan_finish(svdev->scan_ctx, -EINTR);
			return;
		} else if (cnt == 0) {
			return;
		}

		rc = send_scan_io(svdev->scan_ctx);
		if (rc != 0) {
			assert(svdev->scan_ctx->retries > 0);
@@ -1553,7 +1564,6 @@ virtio_scsi_dev_unregister_cb(void *io_device)
static void
virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
{
	struct virtio_scsi_scan_base *scan_ctx;
	struct virtio_scsi_disk *disk, *disk_tmp;
	bool do_remove = true;

@@ -1564,9 +1574,9 @@ virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)

	svdev->removed = true;

	scan_ctx = svdev->scan_ctx;
	if (scan_ctx) {
		_virtio_scsi_dev_scan_finish(scan_ctx, -EINTR);
	if (svdev->scan_ctx) {
		/* The removal will continue after we receive a pending scan I/O. */
		return;
	}

	TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {