bdev_virtio: use a single io_device per virtio_dev
We previously used a separate io_device for each bdev created from a virtio_dev. The new approach makes us reuse the same io_channel for different bdevs on the same core. It also provides a built-in safety check for freeing virtio_dev only when all io_channels on this device have been closed. Change-Id: Iaae66964f90aa3cef95ed2e261c6f3dfb2f26caa Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/388505 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
0618d6b0db
commit
5e8ec497d4
@ -371,7 +371,7 @@ bdev_virtio_get_io_channel(void *ctx)
|
|||||||
{
|
{
|
||||||
struct virtio_scsi_disk *disk = ctx;
|
struct virtio_scsi_disk *disk = ctx;
|
||||||
|
|
||||||
return spdk_get_io_channel(&disk->vdev);
|
return spdk_get_io_channel(disk->vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -530,8 +530,7 @@ bdev_virtio_ctrlq_poll(void *arg)
|
|||||||
static int
|
static int
|
||||||
bdev_virtio_create_cb(void *io_device, void *ctx_buf)
|
bdev_virtio_create_cb(void *io_device, void *ctx_buf)
|
||||||
{
|
{
|
||||||
struct virtio_dev **vdev_ptr = io_device;
|
struct virtio_dev *vdev = io_device;
|
||||||
struct virtio_dev *vdev = *vdev_ptr;
|
|
||||||
struct bdev_virtio_io_channel *ch = ctx_buf;
|
struct bdev_virtio_io_channel *ch = ctx_buf;
|
||||||
struct virtqueue *vq;
|
struct virtqueue *vq;
|
||||||
int32_t queue_idx;
|
int32_t queue_idx;
|
||||||
@ -629,10 +628,11 @@ scan_target_finish(struct virtio_scsi_scan_base *base)
|
|||||||
ctrlq->poller_ctx = ctrlq_ring;
|
ctrlq->poller_ctx = ctrlq_ring;
|
||||||
spdk_bdev_poller_start(&ctrlq->poller, bdev_virtio_ctrlq_poll, base->vdev, CTRLQ_POLL_PERIOD_US);
|
spdk_bdev_poller_start(&ctrlq->poller, bdev_virtio_ctrlq_poll, base->vdev, CTRLQ_POLL_PERIOD_US);
|
||||||
|
|
||||||
|
spdk_io_device_register(base->vdev, bdev_virtio_create_cb, bdev_virtio_destroy_cb,
|
||||||
|
sizeof(struct bdev_virtio_io_channel));
|
||||||
|
|
||||||
while ((disk = TAILQ_FIRST(&base->found_disks))) {
|
while ((disk = TAILQ_FIRST(&base->found_disks))) {
|
||||||
TAILQ_REMOVE(&base->found_disks, disk, link);
|
TAILQ_REMOVE(&base->found_disks, disk, link);
|
||||||
spdk_io_device_register(&disk->vdev, bdev_virtio_create_cb, bdev_virtio_destroy_cb,
|
|
||||||
sizeof(struct bdev_virtio_io_channel));
|
|
||||||
spdk_bdev_register(&disk->bdev);
|
spdk_bdev_register(&disk->bdev);
|
||||||
bdevs[bdevs_cnt] = &disk->bdev;
|
bdevs[bdevs_cnt] = &disk->bdev;
|
||||||
bdevs_cnt++;
|
bdevs_cnt++;
|
||||||
@ -1201,26 +1201,35 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bdev_virtio_finish(void)
|
virtio_scsi_dev_unregister_cb(void *io_device)
|
||||||
{
|
{
|
||||||
struct virtio_dev *vdev, *next;
|
struct virtio_dev *vdev = io_device;
|
||||||
struct virtqueue *vq;
|
struct virtqueue *vq;
|
||||||
struct spdk_ring *send_ring;
|
struct spdk_ring *send_ring;
|
||||||
|
|
||||||
|
if (virtio_dev_queue_is_acquired(vdev, VIRTIO_SCSI_CONTROLQ)) {
|
||||||
|
vq = vdev->vqs[VIRTIO_SCSI_CONTROLQ];
|
||||||
|
spdk_bdev_poller_stop(&vq->poller);
|
||||||
|
send_ring = vq->poller_ctx;
|
||||||
|
/* bdevs built on top of this vdev mustn't be destroyed with outstanding I/O. */
|
||||||
|
assert(spdk_ring_count(send_ring) == 0);
|
||||||
|
spdk_ring_free(send_ring);
|
||||||
|
vq->poller_ctx = NULL;
|
||||||
|
virtio_dev_release_queue(vdev, VIRTIO_SCSI_CONTROLQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtio_dev_reset(vdev);
|
||||||
|
virtio_dev_free(vdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdev_virtio_finish(void)
|
||||||
|
{
|
||||||
|
struct virtio_dev *vdev, *next;
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(vdev, &g_virtio_driver.attached_ctrlrs, tailq, next) {
|
TAILQ_FOREACH_SAFE(vdev, &g_virtio_driver.attached_ctrlrs, tailq, next) {
|
||||||
TAILQ_REMOVE(&g_virtio_driver.attached_ctrlrs, vdev, tailq);
|
TAILQ_REMOVE(&g_virtio_driver.attached_ctrlrs, vdev, tailq);
|
||||||
if (virtio_dev_queue_is_acquired(vdev, VIRTIO_SCSI_CONTROLQ)) {
|
spdk_io_device_unregister(vdev, virtio_scsi_dev_unregister_cb);
|
||||||
vq = vdev->vqs[VIRTIO_SCSI_CONTROLQ];
|
|
||||||
spdk_bdev_poller_stop(&vq->poller);
|
|
||||||
send_ring = vq->poller_ctx;
|
|
||||||
/* bdevs built on top of this vdev mustn't be destroyed with outstanding I/O. */
|
|
||||||
assert(spdk_ring_count(send_ring) == 0);
|
|
||||||
spdk_ring_free(send_ring);
|
|
||||||
vq->poller_ctx = NULL;
|
|
||||||
virtio_dev_release_queue(vdev, VIRTIO_SCSI_CONTROLQ);
|
|
||||||
}
|
|
||||||
virtio_dev_reset(vdev);
|
|
||||||
virtio_dev_free(vdev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user