Commit 661feb15 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

bdev_virtio: defer bdev registration until the scan finishes



bdev_virtio I/O poller used to interfere with scan poller.
e.g. GPT read could be picked up by scan poller.

Even if such request is instantly rejected, this would cause
both GPT and scan to fail. Instead, defer bdev_register
until after the virtio_hw scan has finished.

I/O poller logic will still have to be greatly refactored to
add proper multiqueue/multibdev support. However, this patch
lifts scan processing responsibility from any I/O pollers.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 5f6306ea
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -77,6 +77,10 @@ struct virtio_scsi_scan_base {
	struct virtio_hw		*hw;
	struct spdk_bdev_poller		*scan_poller;
	unsigned			refcount;

	/* Disks to be registered after the scan finishes */
	TAILQ_HEAD(, virtio_scsi_disk) found_disks;

	struct virtio_scsi_scan_buf	buf[BDEV_VIRTIO_MAX_TARGET];
};

@@ -85,6 +89,7 @@ struct virtio_scsi_disk {
	struct virtio_hw	*hw;
	uint64_t		num_blocks;
	uint32_t		block_size;
	TAILQ_ENTRY(virtio_scsi_disk) link;
};

struct bdev_virtio_io_channel {
@@ -284,14 +289,26 @@ bdev_virtio_destroy_cb(void *io_device, void *ctx_buf)
static void
scan_target_finish(struct virtio_scsi_scan_base *base)
{
	struct virtio_scsi_disk *disk;

	assert(base->refcount > 0);
	base->refcount--;
	if (base->refcount == 0) {
	if (base->refcount > 0) {
		return;
	}

	spdk_bdev_poller_stop(&base->scan_poller);

	while ((disk = TAILQ_FIRST(&base->found_disks))) {
		TAILQ_REMOVE(&base->found_disks, disk, link);
		spdk_io_device_register(&disk->hw, bdev_virtio_create_cb, bdev_virtio_destroy_cb,
					sizeof(struct bdev_virtio_io_channel));
		spdk_bdev_register(&disk->bdev);
	}

	spdk_dma_free(base);
	spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi));
}
}

static int
process_scan_inquiry(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
@@ -356,10 +373,7 @@ process_read_cap(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
	bdev->fn_table = &virtio_fn_table;
	bdev->module = SPDK_GET_BDEV_MODULE(virtio_scsi);

	spdk_io_device_register(&disk->hw, bdev_virtio_create_cb, bdev_virtio_destroy_cb,
				sizeof(struct bdev_virtio_io_channel));
	spdk_bdev_register(bdev);

	TAILQ_INSERT_TAIL(&base->found_disks, disk, link);
	scan_target_finish(base);
	return 0;
}
@@ -503,6 +517,7 @@ bdev_virtio_initialize(void)

	base->hw = hw;
	base->refcount = BDEV_VIRTIO_MAX_TARGET;
	TAILQ_INIT(&base->found_disks);

	spdk_bdev_poller_start(&base->scan_poller, bdev_scan_poll, base,
			       spdk_env_get_current_core(), 0);