From 64e80646caf30eb25556678a8dc87ae95095bda6 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Thu, 24 Aug 2017 21:13:12 +0200 Subject: [PATCH] bdev_virtio: use scan_base as memory pool for all requests Save us some allocations and fix scan_target() error handling path Change-Id: I29fe18a6e592c7fd32d0486f831f6b053f59b561 Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/375604 Tested-by: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- lib/bdev/virtio/bdev_virtio.c | 81 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/lib/bdev/virtio/bdev_virtio.c b/lib/bdev/virtio/bdev_virtio.c index eed6fd11d..15ea97acf 100644 --- a/lib/bdev/virtio/bdev_virtio.c +++ b/lib/bdev/virtio/bdev_virtio.c @@ -55,13 +55,29 @@ #include "spdk/scsi_spec.h" +#define BDEV_VIRTIO_MAX_TARGET 64 +#define BDEV_VIRTIO_SCAN_PAYLOAD_SIZE 256 + static int bdev_virtio_initialize(void); static void bdev_virtio_finish(void); +struct virtio_scsi_io_ctx { + struct virtio_req vreq; + struct virtio_scsi_cmd_req req; + struct virtio_scsi_cmd_resp resp; +}; + +struct virtio_scsi_scan_buf { + struct virtio_scsi_io_ctx io_ctx; + struct iovec iov; + uint8_t payload[BDEV_VIRTIO_SCAN_PAYLOAD_SIZE]; +}; + struct virtio_scsi_scan_base { - struct virtio_hw *hw; - struct spdk_bdev_poller *scan_poller; - unsigned refcount; + struct virtio_hw *hw; + struct spdk_bdev_poller *scan_poller; + unsigned refcount; + struct virtio_scsi_scan_buf buf[BDEV_VIRTIO_MAX_TARGET]; }; struct virtio_scsi_disk { @@ -71,12 +87,6 @@ struct virtio_scsi_disk { uint32_t block_size; }; -struct virtio_scsi_io_ctx { - 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; @@ -272,17 +282,9 @@ bdev_virtio_destroy_cb(void *io_device, void *ctx_buf) } static void -scan_target_finish(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) +scan_target_finish(struct virtio_scsi_scan_base *base) { assert(base->refcount > 0); - - spdk_dma_free(vreq->iov[0].iov_base); - spdk_dma_free(vreq->iov); - spdk_dma_free(vreq->iov_resp.iov_base); - spdk_dma_free(vreq->iov_req.iov_base); - - free(vreq); - base->refcount--; if (base->refcount == 0) { spdk_bdev_poller_stop(&base->scan_poller); @@ -358,7 +360,7 @@ process_read_cap(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) sizeof(struct bdev_virtio_io_channel)); spdk_bdev_register(bdev); - scan_target_finish(base, vreq); + scan_target_finish(base); return 0; } @@ -371,7 +373,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) if (vreq->iov_req.iov_len < sizeof(struct virtio_scsi_cmd_req) || vreq->iov_resp.iov_len < sizeof(struct virtio_scsi_cmd_resp)) { SPDK_ERRLOG("Received target scan message with invalid length.\n"); - scan_target_finish(base, vreq); + scan_target_finish(base); return; } @@ -389,7 +391,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) } if (rc < 0) { - scan_target_finish(base, vreq); + scan_target_finish(base); } } @@ -413,7 +415,7 @@ bdev_scan_poll(void *arg) } static void -scan_target(struct virtio_hw *hw, uint8_t target) +scan_target(struct virtio_scsi_scan_base *base, uint8_t target) { struct iovec *iov; struct virtio_req *vreq; @@ -421,28 +423,23 @@ scan_target(struct virtio_hw *hw, uint8_t target) struct virtio_scsi_cmd_resp *resp; struct spdk_scsi_cdb_inquiry *cdb; - vreq = calloc(1, sizeof(*vreq)); - if (vreq == NULL) { - SPDK_ERRLOG("Cannot allocate memory for target scan request.\n"); - return; - } + vreq = &base->buf[target].io_ctx.vreq; + req = &base->buf[target].io_ctx.req; + resp = &base->buf[target].io_ctx.resp; + iov = &base->buf[target].iov; - iov = spdk_dma_malloc(sizeof(*iov), 64, NULL); vreq->iov = iov; vreq->iovcnt = 1; vreq->is_write = 0; - req = spdk_dma_zmalloc(sizeof(*req), 64, NULL); - resp = spdk_dma_malloc(sizeof(*resp), 64, NULL); - vreq->iov_req.iov_base = (void *)req; vreq->iov_req.iov_len = sizeof(*req); vreq->iov_resp.iov_base = (void *)resp; vreq->iov_resp.iov_len = sizeof(*resp); - iov[0].iov_base = spdk_dma_malloc(4096, 64, NULL); - iov[0].iov_len = 255; + iov[0].iov_base = (void *)&base->buf[target].payload; + iov[0].iov_len = BDEV_VIRTIO_SCAN_PAYLOAD_SIZE; req->lun[0] = 1; req->lun[1] = target; @@ -451,7 +448,7 @@ scan_target(struct virtio_hw *hw, uint8_t target) cdb->opcode = SPDK_SPC_INQUIRY; cdb->alloc_len[1] = 255; - virtio_xmit_pkts(hw->vqs[2], vreq); + virtio_xmit_pkts(base->hw->vqs[2], vreq); } static int @@ -500,19 +497,21 @@ bdev_virtio_initialize(void) goto out; } - base->hw = hw; - base->refcount = 64; - spdk_bdev_poller_start(&base->scan_poller, bdev_scan_poll, base, - spdk_env_get_current_core(), 0); - /* TODO check rc, add virtio_dev_deinit() */ eth_virtio_dev_init(hw, 3); virtio_dev_start(hw); - for (i = 0; i < 64; i++) { - scan_target(hw, i); + base->hw = hw; + base->refcount = BDEV_VIRTIO_MAX_TARGET; + + spdk_bdev_poller_start(&base->scan_poller, bdev_scan_poll, base, + spdk_env_get_current_core(), 0); + + for (i = 0; i < BDEV_VIRTIO_MAX_TARGET; i++) { + scan_target(base, i); } + return 0; out: