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: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/378064
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-09-12 14:04:50 +02:00 committed by Jim Harris
parent 5f6306ea24
commit 661feb15a8

View File

@ -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,13 +289,25 @@ 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) {
spdk_bdev_poller_stop(&base->scan_poller);
spdk_dma_free(base);
spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi));
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
@ -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);