diff --git a/lib/bdev/virtio/bdev_virtio.c b/lib/bdev/virtio/bdev_virtio.c index cbfaf2c22..c14f1816c 100644 --- a/lib/bdev/virtio/bdev_virtio.c +++ b/lib/bdev/virtio/bdev_virtio.c @@ -103,8 +103,8 @@ struct virtio_scsi_scan_info { struct virtio_scsi_scan_base { struct virtio_scsi_dev *svdev; - /** Virtqueue used for the scan I/O. */ - struct virtqueue *vq; + /** I/O channel used for the scan I/O. */ + struct bdev_virtio_io_channel *channel; bdev_virtio_create_cb cb_fn; void *cb_arg; @@ -145,6 +145,24 @@ static bool g_bdev_virtio_finish = false; static void virtio_scsi_dev_unregister_cb(void *io_device); static void virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev); +static int bdev_virtio_scsi_ch_create_cb(void *io_device, void *ctx_buf); +static void bdev_virtio_scsi_ch_destroy_cb(void *io_device, void *ctx_buf); +static void process_scan_resp(struct virtio_scsi_scan_base *base, + struct virtio_req *vreq); + +static void +virtio_scsi_dev_init(struct virtio_scsi_dev *svdev) +{ + TAILQ_INIT(&svdev->luns); + svdev->scan_ctx = NULL; + svdev->removed = false; + + spdk_io_device_register(svdev, bdev_virtio_scsi_ch_create_cb, + bdev_virtio_scsi_ch_destroy_cb, + sizeof(struct bdev_virtio_io_channel)); + + TAILQ_INSERT_TAIL(&g_virtio_driver.scsi_devs, &svdev->vdev, tailq); +} static int virtio_pci_scsi_dev_create_cb(struct virtio_pci_ctx *pci_ctx) @@ -162,10 +180,6 @@ virtio_pci_scsi_dev_create_cb(struct virtio_pci_ctx *pci_ctx) return -1; } - TAILQ_INIT(&svdev->luns); - svdev->scan_ctx = NULL; - svdev->removed = false; - vdev = &svdev->vdev; name = spdk_sprintf_alloc("VirtioScsi%"PRIu32, pci_dev_counter++); if (name == NULL) { @@ -185,7 +199,7 @@ virtio_pci_scsi_dev_create_cb(struct virtio_pci_ctx *pci_ctx) &num_queues, sizeof(num_queues)); vdev->max_queues = SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED + num_queues; - TAILQ_INSERT_TAIL(&g_virtio_driver.scsi_devs, vdev, tailq); + virtio_scsi_dev_init(svdev); return 0; } @@ -203,10 +217,6 @@ virtio_user_scsi_dev_create(const char *name, const char *path, return NULL; } - TAILQ_INIT(&svdev->luns); - svdev->scan_ctx = NULL; - svdev->removed = false; - vdev = &svdev->vdev; rc = virtio_user_dev_init(vdev, name, path, num_queues, queue_size, SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED); @@ -216,8 +226,7 @@ virtio_user_scsi_dev_create(const char *name, const char *path, return NULL; } - - TAILQ_INSERT_TAIL(&g_virtio_driver.scsi_devs, vdev, tailq); + virtio_scsi_dev_init(svdev); return svdev; } @@ -555,11 +564,18 @@ static void bdev_virtio_poll(void *arg) { struct bdev_virtio_io_channel *ch = arg; + struct virtio_scsi_dev *svdev = ch->svdev; struct virtio_req *req[32]; uint16_t i, cnt; cnt = virtio_recv_pkts(ch->vq, req, SPDK_COUNTOF(req)); for (i = 0; i < cnt; ++i) { + if (spdk_unlikely(svdev->scan_ctx && + req[i] == &svdev->scan_ctx->io_ctx.vreq)) { + process_scan_resp(svdev->scan_ctx, req[i]); + continue; + } + bdev_virtio_io_cpl(req[i]); } } @@ -684,20 +700,14 @@ static void scan_target_abort(struct virtio_scsi_scan_base *base, int error) { struct virtio_scsi_dev *svdev = base->svdev; - struct virtio_dev *vdev = &svdev->vdev; struct virtio_scsi_disk *disk; - struct virtqueue *vq; while ((disk = TAILQ_FIRST(&base->found_disks))) { TAILQ_REMOVE(&base->found_disks, disk, link); free(disk); } - vq = base->vq; - spdk_poller_unregister(&vq->poller); - spdk_dma_free(vq->poller_ctx); - vq->poller_ctx = NULL; - virtio_dev_release_queue(vdev, vq->vq_queue_index); + spdk_put_io_channel(spdk_io_channel_from_ctx(base->channel)); if (base->cb_fn) { base->cb_fn(base->cb_arg, error, NULL, 0); @@ -728,9 +738,7 @@ scan_target_finish(struct virtio_scsi_scan_base *base) return; } - spdk_poller_unregister(&base->vq->poller); - base->vq->poller_ctx = NULL; - virtio_dev_release_queue(vdev, base->vq->vq_queue_index); + spdk_put_io_channel(spdk_io_channel_from_ctx(base->channel)); ctrlq_ring = spdk_ring_create(SPDK_RING_TYPE_MP_SC, CTRLQ_RING_SIZE, SPDK_ENV_SOCKET_ID_ANY); @@ -752,10 +760,6 @@ scan_target_finish(struct virtio_scsi_scan_base *base) ctrlq->poller_ctx = ctrlq_ring; ctrlq->poller = spdk_poller_register(bdev_virtio_ctrlq_poll, vdev, CTRLQ_POLL_PERIOD_US); - spdk_io_device_register(base->svdev, bdev_virtio_scsi_ch_create_cb, - bdev_virtio_scsi_ch_destroy_cb, - sizeof(struct bdev_virtio_io_channel)); - while ((disk = TAILQ_FIRST(&base->found_disks))) { TAILQ_REMOVE(&base->found_disks, disk, link); rc = spdk_bdev_register(&disk->bdev); @@ -799,7 +803,7 @@ send_inquiry_vpd(struct virtio_scsi_scan_base *base, uint8_t target_id, struct v inquiry_cdb->page_code = page_code; to_be16(inquiry_cdb->alloc_len, iov[0].iov_len); - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -819,7 +823,7 @@ send_read_cap_10(struct virtio_scsi_scan_base *base, uint8_t target_id, struct v iov[0].iov_len = 8; req->cdb[0] = SPDK_SBC_READ_CAPACITY_10; - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -841,7 +845,7 @@ send_read_cap_16(struct virtio_scsi_scan_base *base, uint8_t target_id, struct v req->cdb[1] = SPDK_SBC_SAI_READ_CAPACITY_16; to_be32(&req->cdb[10], iov[0].iov_len); - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -858,7 +862,7 @@ send_test_unit_ready(struct virtio_scsi_scan_base *base, uint8_t target_id, stru req->lun[1] = target_id; req->cdb[0] = SPDK_SPC_TEST_UNIT_READY; - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -876,7 +880,7 @@ send_start_stop_unit(struct virtio_scsi_scan_base *base, uint8_t target_id, stru req->cdb[0] = SPDK_SBC_START_STOP_UNIT; req->cdb[4] = SPDK_SBC_START_STOP_UNIT_START_BIT; - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -1145,7 +1149,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) } /* resend the same request */ - rc = virtio_xmit_pkt(base->vq, vreq); + rc = virtio_xmit_pkt(base->channel->vq, vreq); if (rc != 0) { assert(false); } @@ -1181,19 +1185,6 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq) } } -static void -bdev_scan_poll(void *arg) -{ - struct virtio_scsi_scan_base *base = arg; - struct virtio_req *req; - uint16_t cnt; - - cnt = virtio_recv_pkts(base->vq, &req, 1); - if (cnt > 0) { - process_scan_resp(base, req); - } -} - static int scan_target(struct virtio_scsi_scan_base *base) { @@ -1232,7 +1223,7 @@ scan_target(struct virtio_scsi_scan_base *base) to_be16(cdb->alloc_len, BDEV_VIRTIO_SCAN_PAYLOAD_SIZE); base->retries = SCAN_REQUEST_RETRIES; - return virtio_xmit_pkt(base->vq, vreq); + return virtio_xmit_pkt(base->channel->vq, vreq); } static int @@ -1307,7 +1298,7 @@ bdev_virtio_scsi_dev_scan(struct virtio_scsi_dev *svdev, bdev_virtio_create_cb c { struct virtio_dev *vdev = &svdev->vdev; struct virtio_scsi_scan_base *base = spdk_dma_zmalloc(sizeof(*base), 64, NULL); - struct virtqueue *vq; + struct spdk_io_channel *io_ch; int rc; if (base == NULL) { @@ -1327,23 +1318,23 @@ bdev_virtio_scsi_dev_scan(struct virtio_scsi_dev *svdev, bdev_virtio_create_cb c base->svdev = svdev; TAILQ_INIT(&base->found_disks); - rc = virtio_dev_acquire_queue(vdev, VIRTIO_SCSI_REQUESTQ); - if (rc != 0) { - SPDK_ERRLOG("Couldn't acquire requestq for the target scan.\n"); + io_ch = spdk_get_io_channel(base->svdev); + if (io_ch == NULL) { + /* TODO: do scan on other core */ spdk_dma_free(base); - return rc; + return -EBUSY; } - vq = vdev->vqs[VIRTIO_SCSI_REQUESTQ]; - base->vq = vq; + base->channel = spdk_io_channel_get_ctx(io_ch); svdev->scan_ctx = base; - - vq->poller_ctx = base; - vq->poller = spdk_poller_register(bdev_scan_poll, base, 0); rc = scan_target(base); if (rc) { SPDK_ERRLOG("Failed to start target scan.\n"); + spdk_put_io_channel(io_ch); + spdk_dma_free(base); + svdev->scan_ctx = NULL; + return rc; } return rc;