Commit 79c7744e authored by Jin Yu's avatar Jin Yu Committed by Tomasz Zawadzki
Browse files

virtio: fix virtio hw double free issue



During virtio_pci_dev_probe, if enum_cb fails, hw needs
to be released. But in bdev_virtio, if vdev fails after
initialization, it will enter the bdev destruction process
which call the modern_destruct_dev function and hw will
be released during the process. So we will encounter the
problem of hw being released twice.

Change-Id: Ifba35284c072355ba0e10428b597a1894d32d59e
Signed-off-by: default avatarJin Yu <jin.yu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3564


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent ebba5a0c
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -224,10 +224,11 @@ static void
modern_destruct_dev(struct virtio_dev *vdev)
{
	struct virtio_hw *hw = vdev->ctx;
	struct spdk_pci_device *pci_dev = hw->pci_dev;

	if (hw != NULL) {
		free_virtio_hw(hw);
	spdk_pci_device_detach(pci_dev);
		spdk_pci_device_detach(hw->pci_dev);
	}
}

static uint8_t
+9 −9
Original line number Diff line number Diff line
@@ -554,9 +554,7 @@ virtio_pci_blk_dev_create(const char *name, struct virtio_pci_ctx *pci_ctx)

	rc = virtio_dev_reset(vdev, VIRTIO_BLK_DEV_SUPPORTED_FEATURES);
	if (rc != 0) {
		virtio_dev_destruct(vdev);
		free(bvdev);
		return NULL;
		goto fail;
	}

	/* TODO: add a way to limit usable virtqueues */
@@ -565,9 +563,7 @@ virtio_pci_blk_dev_create(const char *name, struct virtio_pci_ctx *pci_ctx)
						&num_queues, sizeof(num_queues));
		if (rc) {
			SPDK_ERRLOG("%s: config read failed: %s\n", vdev->name, spdk_strerror(-rc));
			virtio_dev_destruct(vdev);
			free(bvdev);
			return NULL;
			goto fail;
		}
	} else {
		num_queues = 1;
@@ -575,12 +571,16 @@ virtio_pci_blk_dev_create(const char *name, struct virtio_pci_ctx *pci_ctx)

	rc = virtio_blk_dev_init(bvdev, num_queues);
	if (rc != 0) {
		virtio_dev_destruct(vdev);
		free(bvdev);
		return NULL;
		goto fail;
	}

	return bvdev;

fail:
	vdev->ctx = NULL;
	virtio_dev_destruct(vdev);
	free(bvdev);
	return NULL;
}

static struct virtio_blk_dev *