From 0329c9b5e58ee5be92ef2c62f56e3b2c1f5c118d Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Mon, 21 Aug 2017 20:50:56 +0200 Subject: [PATCH] bdev_virtio: added async I/O Added struct bdev_virtio_io_channel. Virtio bdev io_channel now creates a poller that listens on vhost-user socket. Change-Id: I9a1c11264384c703f514be87029edbadf9cc7361 Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/375005 Tested-by: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- lib/bdev/virtio/bdev_virtio.c | 55 +++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/lib/bdev/virtio/bdev_virtio.c b/lib/bdev/virtio/bdev_virtio.c index 53dd7b2aa7..8bf0119081 100644 --- a/lib/bdev/virtio/bdev_virtio.c +++ b/lib/bdev/virtio/bdev_virtio.c @@ -40,6 +40,7 @@ #include "spdk/string.h" #include "spdk/endian.h" #include "spdk/stdinc.h" +#include "spdk/util.h" #include "spdk_internal/bdev.h" #include "spdk_internal/log.h" @@ -65,9 +66,14 @@ struct virtio_scsi_disk { }; struct virtio_scsi_io_ctx { - struct virtio_req vreq; - struct virtio_scsi_cmd_req req; - struct virtio_scsi_cmd_resp resp; + struct virtio_req vreq; + struct virtio_scsi_cmd_req req; + struct virtio_scsi_cmd_resp resp; +}; + +struct bdev_virtio_io_channel { + struct virtio_hw *hw; + struct spdk_bdev_poller *poller; }; static int @@ -85,8 +91,6 @@ bdev_virtio_rw(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) struct virtio_req *vreq; struct virtio_scsi_cmd_req *req; struct virtio_scsi_cmd_resp *resp; - uint16_t cnt; - struct virtio_req *complete; struct virtio_scsi_disk *disk = (struct virtio_scsi_disk *)bdev_io->bdev; struct virtio_scsi_io_ctx *io_ctx = (struct virtio_scsi_io_ctx *)bdev_io->driver_ctx; bool is_read = (bdev_io->type == SPDK_BDEV_IO_TYPE_READ); @@ -122,12 +126,6 @@ bdev_virtio_rw(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) } virtio_xmit_pkts(disk->hw->vqs[2], vreq); - - do { - cnt = virtio_recv_pkts(disk->hw->vqs[2], &complete, 1); - } while (cnt == 0); - - spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS); } static int _bdev_virtio_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) @@ -194,15 +192,47 @@ static const struct spdk_bdev_fn_table virtio_fn_table = { .get_io_channel = bdev_virtio_get_io_channel, }; +static void +bdev_virtio_io_cpl(struct virtio_req *req) +{ + struct virtio_scsi_io_ctx *io_ctx = SPDK_CONTAINEROF(req, struct virtio_scsi_io_ctx, vreq); + struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(io_ctx); + + spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS); +} + + +static void +bdev_virtio_poll(void *arg) +{ + struct bdev_virtio_io_channel *ch = arg; + struct virtio_req *req[32]; + uint16_t i, cnt; + + cnt = virtio_recv_pkts(ch->hw->vqs[2], req, SPDK_COUNTOF(req)); + for (i = 0; i < cnt; ++i) { + bdev_virtio_io_cpl(req[i]); + } +} + static int bdev_virtio_create_cb(void *io_device, void *ctx_buf) { + struct virtio_hw **hw = io_device; + struct bdev_virtio_io_channel *ch = ctx_buf; + + ch->hw = *hw; + spdk_bdev_poller_start(&ch->poller, bdev_virtio_poll, ch, + spdk_env_get_current_core(), 0); return 0; } static void bdev_virtio_destroy_cb(void *io_device, void *ctx_buf) { + struct bdev_virtio_io_channel *io_channel = ctx_buf; + + spdk_bdev_poller_stop(&io_channel->poller); } static void @@ -289,7 +319,8 @@ scan_target(struct virtio_hw *hw, uint8_t target) 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, 0); + spdk_io_device_register(&disk->hw, bdev_virtio_create_cb, bdev_virtio_destroy_cb, + sizeof(struct bdev_virtio_io_channel)); spdk_bdev_register(bdev); }