diff --git a/include/spdk/vhost.h b/include/spdk/vhost.h index c4e2ca6d6..5cf980e6a 100644 --- a/include/spdk/vhost.h +++ b/include/spdk/vhost.h @@ -52,24 +52,25 @@ void spdk_vhost_startup(void *arg1, void *arg2); void spdk_vhost_shutdown_cb(void); /* Forward declaration */ -struct spdk_vhost_scsi_ctrlr; +struct spdk_vhost_dev; +struct spdk_vhost_scsi_dev; /** * Get handle to next controller. * \param prev Previous controller or NULL to get first one. * \return handle to next controller ot NULL if prev was the last one. */ -struct spdk_vhost_scsi_ctrlr *spdk_vhost_scsi_ctrlr_next(struct spdk_vhost_scsi_ctrlr *prev); - -const char *spdk_vhost_scsi_ctrlr_get_name(struct spdk_vhost_scsi_ctrlr *ctrl); -uint64_t spdk_vhost_scsi_ctrlr_get_cpumask(struct spdk_vhost_scsi_ctrlr *ctrl); -struct spdk_vhost_scsi_ctrlr *spdk_vhost_scsi_ctrlr_find(const char *ctrlr_name); -int spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask); -int spdk_vhost_scsi_ctrlr_remove(struct spdk_vhost_scsi_ctrlr *vdev); +struct spdk_vhost_dev *spdk_vhost_dev_next(struct spdk_vhost_dev *prev); +struct spdk_vhost_dev *spdk_vhost_dev_find(const char *ctrlr_name); +const char *spdk_vhost_dev_get_name(struct spdk_vhost_dev *ctrl); +uint64_t spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *ctrl); +int spdk_vhost_scsi_dev_construct(const char *name, uint64_t cpumask); +int spdk_vhost_scsi_dev_remove(struct spdk_vhost_scsi_dev *vdev); int spdk_vhost_parse_core_mask(const char *mask, uint64_t *cpumask); -struct spdk_scsi_dev *spdk_vhost_scsi_ctrlr_get_dev(struct spdk_vhost_scsi_ctrlr *ctrl, + +struct spdk_scsi_dev *spdk_vhost_scsi_dev_get_dev(struct spdk_vhost_scsi_dev *ctrl, uint8_t num); -int spdk_vhost_scsi_ctrlr_add_dev(const char *name, unsigned scsi_dev_num, const char *lun_name); -int spdk_vhost_scsi_ctrlr_remove_dev(struct spdk_vhost_scsi_ctrlr *vdev, unsigned scsi_dev_num); +int spdk_vhost_scsi_dev_add_dev(const char *name, unsigned scsi_dev_num, const char *lun_name); +int spdk_vhost_scsi_dev_remove_dev(struct spdk_vhost_scsi_dev *vdev, unsigned scsi_dev_num); #endif /* SPDK_VHOST_H */ diff --git a/lib/vhost/task.c b/lib/vhost/task.c index 31d727f9a..3cfb11414 100644 --- a/lib/vhost/task.c +++ b/lib/vhost/task.c @@ -68,11 +68,11 @@ spdk_vhost_task_free_cb(struct spdk_scsi_task *scsi_task) struct spdk_vhost_task *task = container_of(scsi_task, struct spdk_vhost_task, scsi); rte_mempool_put(g_task_pool, task); - spdk_vhost_scsi_ctrlr_task_unref(task->vdev); + spdk_vhost_dev_task_unref((struct spdk_vhost_dev *) task->svdev); } struct spdk_vhost_task * -spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev) +spdk_vhost_task_get(struct spdk_vhost_scsi_dev *vdev) { struct spdk_vhost_task *task; int rc; @@ -84,8 +84,8 @@ spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev) } memset(task, 0, sizeof(*task)); - task->vdev = vdev; - spdk_vhost_scsi_ctrlr_task_ref(task->vdev); + task->svdev = vdev; + spdk_vhost_dev_task_ref((struct spdk_vhost_dev *) task->svdev); spdk_scsi_task_construct(&task->scsi, spdk_vhost_task_free_cb, NULL); return task; diff --git a/lib/vhost/task.h b/lib/vhost/task.h index 1be79b491..e1c31eb10 100644 --- a/lib/vhost/task.h +++ b/lib/vhost/task.h @@ -39,6 +39,8 @@ /* Allocated iovec buffer len */ #define VHOST_SCSI_IOVS_LEN 128 +struct spdk_vhost_dev; + struct spdk_vhost_task { struct spdk_scsi_task scsi; @@ -47,7 +49,7 @@ struct spdk_vhost_task { struct virtio_scsi_ctrl_tmf_resp *tmf_resp; }; - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_scsi_dev *svdev; struct spdk_scsi_dev *scsi_dev; int req_idx; @@ -61,10 +63,10 @@ void spdk_vhost_enqueue_task(struct spdk_vhost_task *task); struct spdk_vhost_task *spdk_vhost_dequeue_task(void); void spdk_vhost_task_put(struct spdk_vhost_task *task); -struct spdk_vhost_task *spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev); +struct spdk_vhost_task *spdk_vhost_task_get(struct spdk_vhost_scsi_dev *vdev); -void spdk_vhost_scsi_ctrlr_task_ref(struct spdk_vhost_scsi_ctrlr *vdev); -void spdk_vhost_scsi_ctrlr_task_unref(struct spdk_vhost_scsi_ctrlr *vdev); +void spdk_vhost_dev_task_ref(struct spdk_vhost_dev *vdev); +void spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev); void spdk_vhost_iovec_free(struct iovec *iov); struct iovec *spdk_vhost_iovec_alloc(void); diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 6f29d2694..a427882cc 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -95,35 +95,36 @@ static char dev_dirname[PATH_MAX] = ""; struct spdk_vhost_dev { struct rte_vhost_memory *mem; + char *name; + int vid; + int task_cnt; + int32_t lcore; + uint64_t cpumask; + uint16_t num_queues; uint64_t negotiated_features; struct rte_vhost_vring virtqueue[MAX_VHOST_VRINGS] __attribute((aligned(SPDK_CACHE_LINE_SIZE))); }; static void -spdk_vhost_dev_free(struct spdk_vhost_dev *dev) -{ - free(dev->mem); - spdk_free(dev); -} - -static void -spdk_vhost_dev_destruct(struct spdk_vhost_dev *dev) +spdk_vhost_dev_destruct(struct spdk_vhost_dev *vdev) { struct rte_vhost_vring *q; uint16_t i; - for (i = 0; i < dev->num_queues; i++) { - q = &dev->virtqueue[i]; - rte_vhost_set_vhost_vring_last_idx(dev->vid, i, q->last_avail_idx, q->last_used_idx); + for (i = 0; i < vdev->num_queues; i++) { + q = &vdev->virtqueue[i]; + rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx); } + + free(vdev->mem); } static int -spdk_vhost_dev_construct(struct spdk_vhost_dev *dev) +spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev) { - int vid = dev->vid; + int vid = vdev->vid; uint16_t num_queues = rte_vhost_get_vring_num(vid); uint16_t i; @@ -134,7 +135,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *dev) } for (i = 0; i < num_queues; i++) { - if (rte_vhost_get_vhost_vring(vid, i, &dev->virtqueue[i])) { + if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) { SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i); return -1; } @@ -147,14 +148,14 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *dev) } - dev->num_queues = num_queues; + vdev->num_queues = num_queues; - if (rte_vhost_get_negotiated_features(vid, &dev->negotiated_features) != 0) { + if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) { SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid); return -1; } - if (rte_vhost_get_mem_table(vid, &dev->mem) != 0) { + if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) { SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid); return -1; } @@ -168,28 +169,17 @@ gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr) return rte_vhost_gpa_to_vva(vdev->mem, addr); } -struct spdk_vhost_scsi_ctrlr { - char *name; - struct spdk_vhost_dev *dev; +struct spdk_vhost_scsi_dev { + struct spdk_vhost_dev vdev; - /**< TODO make this an array of spdk_scsi_devs. The vhost scsi - * request will tell us which scsi_dev to use. - */ struct spdk_scsi_dev *scsi_dev[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS]; - - int task_cnt; - struct spdk_poller *requestq_poller; struct spdk_poller *controlq_poller; - - int32_t lcore; - - uint64_t cpumask; } __rte_cache_aligned; /* This maps from the integer index passed by DPDK to the our controller representation. */ /* MAX_VHOST_DEVICE from DPDK. */ -static struct spdk_vhost_scsi_ctrlr *dpdk_vid_mapping[MAX_VHOST_DEVICE]; +static struct spdk_vhost_dev *dpdk_vid_mapping[MAX_VHOST_DEVICE]; /* * Get available requests from avail ring. @@ -220,9 +210,9 @@ vq_avail_ring_get(struct rte_vhost_vring *vq, uint16_t *reqs, uint16_t reqs_len) } static bool -vq_should_notify(struct spdk_vhost_dev *dev, struct rte_vhost_vring *vq) +vq_should_notify(struct spdk_vhost_dev *vdev, struct rte_vhost_vring *vq) { - if ((dev->negotiated_features & (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY)) && + if ((vdev->negotiated_features & (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY)) && spdk_unlikely(vq->avail->idx == vq->last_avail_idx)) { return 1; } @@ -234,7 +224,7 @@ vq_should_notify(struct spdk_vhost_dev *dev, struct rte_vhost_vring *vq) * Enqueue id and len to used ring. */ static void -vq_used_ring_enqueue(struct spdk_vhost_dev *dev, struct rte_vhost_vring *vq, uint16_t id, +vq_used_ring_enqueue(struct spdk_vhost_dev *vdev, struct rte_vhost_vring *vq, uint16_t id, uint32_t len) { struct vring_used *used = vq->used; @@ -253,7 +243,7 @@ vq_used_ring_enqueue(struct spdk_vhost_dev *dev, struct rte_vhost_vring *vq, uin rte_compiler_barrier(); vq->used->idx = vq->last_used_idx; - if (vq_should_notify(dev, vq)) { + if (vq_should_notify(vdev, vq)) { eventfd_write(vq->callfd, (eventfd_t)1); } } @@ -287,7 +277,7 @@ submit_completion(struct spdk_vhost_task *task) struct iovec *iovs = NULL; int result; - vq_used_ring_enqueue(task->vdev->dev, task->vq, task->req_idx, task->scsi.data_transferred); + vq_used_ring_enqueue(&task->svdev->vdev, task->vq, task->req_idx, task->scsi.data_transferred); SPDK_TRACELOG(SPDK_TRACE_VHOST, "Finished task (%p) req_idx=%d\n", task, task->req_idx); if (task->scsi.iovs != &task->scsi.iov) { @@ -380,7 +370,7 @@ mgmt_task_submit(struct spdk_vhost_task *task, enum spdk_scsi_task_func func) static void invalid_request(struct spdk_vhost_task *task) { - vq_used_ring_enqueue(task->vdev->dev, task->vq, task->req_idx, 0); + vq_used_ring_enqueue(&task->svdev->vdev, task->vq, task->req_idx, 0); spdk_vhost_task_put(task); SPDK_TRACELOG(SPDK_TRACE_VHOST, "Invalid request (status=%" PRIu8")\n", @@ -388,14 +378,14 @@ invalid_request(struct spdk_vhost_task *task) } static struct spdk_scsi_dev * -get_scsi_dev(struct spdk_vhost_scsi_ctrlr *vdev, const __u8 *lun) +get_scsi_dev(struct spdk_vhost_scsi_dev *svdev, const __u8 *lun) { SPDK_TRACEDUMP(SPDK_TRACE_VHOST_QUEUE, "LUN", lun, 8); /* First byte must be 1 and second is target */ if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) return NULL; - return vdev->scsi_dev[lun[1]]; + return svdev->scsi_dev[lun[1]]; } static struct spdk_scsi_lun * @@ -412,21 +402,21 @@ get_scsi_lun(struct spdk_scsi_dev *scsi_dev, const __u8 *lun) } void -spdk_vhost_scsi_ctrlr_task_ref(struct spdk_vhost_scsi_ctrlr *vdev) +spdk_vhost_dev_task_ref(struct spdk_vhost_dev *vdev) { assert(vdev->task_cnt < INT_MAX); vdev->task_cnt++; } void -spdk_vhost_scsi_ctrlr_task_unref(struct spdk_vhost_scsi_ctrlr *vdev) +spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev) { assert(vdev->task_cnt > 0); vdev->task_cnt--; } static void -process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *controlq, +process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *controlq, uint16_t req_idx) { struct spdk_vhost_task *task; @@ -436,7 +426,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring struct virtio_scsi_ctrl_an_resp *an_resp; desc = &controlq->desc[req_idx]; - ctrl_req = (void *)gpa_to_vva(vdev->dev, desc->addr); + ctrl_req = (void *)gpa_to_vva(&svdev->vdev, desc->addr); SPDK_TRACELOG(SPDK_TRACE_VHOST_QUEUE, "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n", @@ -445,11 +435,11 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring SPDK_TRACEDUMP(SPDK_TRACE_VHOST_QUEUE, "Request desriptor", (uint8_t *)ctrl_req, desc->len); - task = spdk_vhost_task_get(vdev); + task = spdk_vhost_task_get(svdev); task->vq = controlq; - task->vdev = vdev; + task->svdev = svdev; task->req_idx = req_idx; - task->scsi_dev = get_scsi_dev(task->vdev, ctrl_req->lun); + task->scsi_dev = get_scsi_dev(task->svdev, ctrl_req->lun); /* Process the TMF request */ switch (ctrl_req->type) { @@ -457,7 +447,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring /* Get the response buffer */ assert(vring_desc_has_next(desc)); desc = vring_desc_get_next(controlq->desc, desc); - task->tmf_resp = (void *)gpa_to_vva(vdev->dev, desc->addr); + task->tmf_resp = (void *)gpa_to_vva(&svdev->vdev, desc->addr); /* Check if we are processing a valid request */ if (task->scsi_dev == NULL) { @@ -483,7 +473,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring case VIRTIO_SCSI_T_AN_QUERY: case VIRTIO_SCSI_T_AN_SUBSCRIBE: { desc = vring_desc_get_next(controlq->desc, desc); - an_resp = (void *)gpa_to_vva(vdev->dev, desc->addr); + an_resp = (void *)gpa_to_vva(&svdev->vdev, desc->addr); an_resp->response = VIRTIO_SCSI_S_ABORTED; break; } @@ -492,7 +482,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring break; } - vq_used_ring_enqueue(vdev->dev, controlq, req_idx, 0); + vq_used_ring_enqueue(&svdev->vdev, controlq, req_idx, 0); spdk_vhost_task_put(task); } @@ -508,7 +498,7 @@ task_data_setup(struct spdk_vhost_task *task, struct virtio_scsi_cmd_req **req) { struct rte_vhost_vring *vq = task->vq; - struct spdk_vhost_dev *dev = task->vdev->dev; + struct spdk_vhost_dev *vdev = &task->svdev->vdev; struct vring_desc *desc = &task->vq->desc[task->req_idx]; struct iovec *iovs = task->scsi.iovs; uint16_t iovcnt = 0, iovcnt_max = task->scsi.iovcnt; @@ -523,7 +513,7 @@ task_data_setup(struct spdk_vhost_task *task, goto abort_task; } - *req = (void *)gpa_to_vva(dev, desc->addr); + *req = (void *)gpa_to_vva(vdev, desc->addr); desc = vring_desc_get_next(vq->desc, desc); task->scsi.dxfer_dir = vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV : SPDK_SCSI_DIR_TO_DEV; @@ -532,7 +522,7 @@ task_data_setup(struct spdk_vhost_task *task, /* * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN] */ - task->resp = (void *)gpa_to_vva(dev, desc->addr); + task->resp = (void *)gpa_to_vva(vdev, desc->addr); if (!vring_desc_has_next(desc)) { /* * TEST UNIT READY command and some others might not contain any payload and this is not an error. @@ -559,7 +549,7 @@ task_data_setup(struct spdk_vhost_task *task, /* All remaining descriptors are data. */ while (iovcnt < iovcnt_max) { - iovs[iovcnt].iov_base = (void *)gpa_to_vva(dev, desc->addr); + iovs[iovcnt].iov_base = (void *)gpa_to_vva(vdev, desc->addr); iovs[iovcnt].iov_len = desc->len; len += desc->len; iovcnt++; @@ -596,7 +586,7 @@ task_data_setup(struct spdk_vhost_task *task, /* Process descriptors up to response. */ while (!vring_desc_is_wr(desc) && iovcnt < iovcnt_max) { - iovs[iovcnt].iov_base = (void *)gpa_to_vva(dev, desc->addr); + iovs[iovcnt].iov_base = (void *)gpa_to_vva(vdev, desc->addr); iovs[iovcnt].iov_len = desc->len; len += desc->len; iovcnt++; @@ -610,7 +600,7 @@ task_data_setup(struct spdk_vhost_task *task, desc = vring_desc_get_next(vq->desc, desc); } - task->resp = (void *)gpa_to_vva(dev, desc->addr); + task->resp = (void *)gpa_to_vva(vdev, desc->addr); if (vring_desc_has_next(desc)) { SPDK_WARNLOG("TO_DEV cmd: ignoring unexpected descriptors after response descriptor.\n"); } @@ -650,7 +640,7 @@ process_request(struct spdk_vhost_task *task) return result; } - task->scsi_dev = get_scsi_dev(task->vdev, req->lun); + task->scsi_dev = get_scsi_dev(task->svdev, req->lun); if (unlikely(task->scsi_dev == NULL)) { task->resp->response = VIRTIO_SCSI_S_BAD_TARGET; return -1; @@ -664,7 +654,7 @@ process_request(struct spdk_vhost_task *task) } static void -process_controlq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) +process_controlq(struct spdk_vhost_scsi_dev *vdev, struct rte_vhost_vring *vq) { uint16_t reqs[32]; uint16_t reqs_cnt, i; @@ -676,7 +666,7 @@ process_controlq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) } static void -process_requestq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) +process_requestq(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *vq) { uint16_t reqs[32]; uint16_t reqs_cnt, i; @@ -687,12 +677,12 @@ process_requestq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) assert(reqs_cnt <= 32); for (i = 0; i < reqs_cnt; i++) { - task = spdk_vhost_task_get(vdev); + task = spdk_vhost_task_get(svdev); SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Starting processing request idx %"PRIu16"======\n", reqs[i]); task->vq = vq; - task->vdev = vdev; + task->svdev = svdev; task->req_idx = reqs[i]; result = process_request(task); if (likely(result == 0)) { @@ -712,19 +702,19 @@ process_requestq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) static void vdev_controlq_worker(void *arg) { - struct spdk_vhost_scsi_ctrlr *vdev = arg; + struct spdk_vhost_scsi_dev *svdev = arg; - process_controlq(vdev, &vdev->dev->virtqueue[VIRTIO_SCSI_CONTROLQ]); + process_controlq(svdev, &svdev->vdev.virtqueue[VIRTIO_SCSI_CONTROLQ]); } static void vdev_worker(void *arg) { - struct spdk_vhost_scsi_ctrlr *vdev = arg; + struct spdk_vhost_scsi_dev *svdev = arg; uint32_t q_idx; - for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vdev->dev->num_queues; q_idx++) { - process_requestq(vdev, &vdev->dev->virtqueue[q_idx]); + for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < svdev->vdev.num_queues; q_idx++) { + process_requestq(svdev, &svdev->vdev.virtqueue[q_idx]); } } @@ -766,21 +756,22 @@ vhost_sem_timedwait(sem_t *sem, unsigned sec) static void add_vdev_cb(void *arg1, void *arg2) { - struct spdk_vhost_scsi_ctrlr *vdev = arg1; + struct spdk_vhost_scsi_dev *svdev = arg1; + struct spdk_vhost_dev *vdev = &svdev->vdev; struct rte_vhost_mem_region *region; uint32_t i; for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { - if (vdev->scsi_dev[i] == NULL) { + if (svdev->scsi_dev[i] == NULL) { continue; } - spdk_scsi_dev_allocate_io_channels(vdev->scsi_dev[i]); + spdk_scsi_dev_allocate_io_channels(svdev->scsi_dev[i]); } SPDK_NOTICELOG("Started poller for vhost controller %s on lcore %d\n", vdev->name, vdev->lcore); - for (i = 0; i < vdev->dev->mem->nregions; i++) { + for (i = 0; i < vdev->mem->nregions; i++) { uint64_t start, end, len; - region = &vdev->dev->mem->regions[i]; + region = &vdev->mem->regions[i]; start = FLOOR_2MB(region->mmap_addr); end = CEIL_2MB(region->mmap_addr + region->mmap_size); len = end - start; @@ -791,8 +782,8 @@ add_vdev_cb(void *arg1, void *arg2) } - spdk_poller_register(&vdev->requestq_poller, vdev_worker, vdev, vdev->lcore, 0); - spdk_poller_register(&vdev->controlq_poller, vdev_controlq_worker, vdev, vdev->lcore, + spdk_poller_register(&svdev->requestq_poller, vdev_worker, svdev, vdev->lcore, 0); + spdk_poller_register(&svdev->controlq_poller, vdev_controlq_worker, svdev, vdev->lcore, CONTROLQ_POLL_PERIOD_US); sem_post((sem_t *)arg2); } @@ -800,21 +791,21 @@ add_vdev_cb(void *arg1, void *arg2) static void remove_vdev_cb(void *arg1, void *arg2) { - struct spdk_vhost_scsi_ctrlr *vdev = arg1; + struct spdk_vhost_scsi_dev *svdev = arg1; struct rte_vhost_mem_region *region; uint32_t i; for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { - if (vdev->scsi_dev[i] == NULL) { + if (svdev->scsi_dev[i] == NULL) { continue; } - spdk_scsi_dev_free_io_channels(vdev->scsi_dev[i]); + spdk_scsi_dev_free_io_channels(svdev->scsi_dev[i]); } - SPDK_NOTICELOG("Stopping poller for vhost controller %s\n", vdev->name); - for (i = 0; i < vdev->dev->mem->nregions; i++) { + SPDK_NOTICELOG("Stopping poller for vhost controller %s\n", svdev->vdev.name); + for (i = 0; i < svdev->vdev.mem->nregions; i++) { uint64_t start, end, len; - region = &vdev->dev->mem->regions[i]; + region = &svdev->vdev.mem->regions[i]; start = FLOOR_2MB(region->mmap_addr); end = CEIL_2MB(region->mmap_addr + region->mmap_size); len = end - start; @@ -828,21 +819,23 @@ remove_vdev_cb(void *arg1, void *arg2) static void destroy_device(int vid) { - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_scsi_dev *svdev; + struct spdk_vhost_dev *vdev; struct spdk_event *event; sem_t done_sem; uint32_t i; assert(vid < MAX_VHOST_DEVICE); vdev = dpdk_vid_mapping[vid]; + svdev = (struct spdk_vhost_scsi_dev *) vdev; event = vhost_sem_event_alloc(vdev->lcore, vdev_event_done_cb, NULL, &done_sem); - spdk_poller_unregister(&vdev->requestq_poller, event); + spdk_poller_unregister(&svdev->requestq_poller, event); if (vhost_sem_timedwait(&done_sem, 1)) rte_panic("%s: failed to unregister request queue poller.\n", vdev->name); event = vhost_sem_event_alloc(vdev->lcore, vdev_event_done_cb, NULL, &done_sem); - spdk_poller_unregister(&vdev->controlq_poller, event); + spdk_poller_unregister(&svdev->controlq_poller, event); if (vhost_sem_timedwait(&done_sem, 1)) rte_panic("%s: failed to unregister control queue poller.\n", vdev->name); @@ -855,7 +848,7 @@ destroy_device(int vid) rte_panic("%s: pending tasks did not finish in 1s.\n", vdev->name); } - event = vhost_sem_event_alloc(vdev->lcore, remove_vdev_cb, vdev, &done_sem); + event = vhost_sem_event_alloc(vdev->lcore, remove_vdev_cb, svdev, &done_sem); spdk_event_call(event); if (vhost_sem_timedwait(&done_sem, 1)) rte_panic("%s: failed to unregister poller.\n", vdev->name); @@ -863,19 +856,17 @@ destroy_device(int vid) g_num_ctrlrs[vdev->lcore]--; vdev->lcore = -1; - spdk_vhost_dev_destruct(vdev->dev); - spdk_vhost_dev_free(vdev->dev); - vdev->dev = NULL; + spdk_vhost_dev_destruct(&svdev->vdev); dpdk_vid_mapping[vid] = NULL; } #define LUN_DEV_NAME_SIZE 8 #define MAX_SCSI_CTRLRS 15 -static struct spdk_vhost_scsi_ctrlr *spdk_vhost_ctrlrs[MAX_SCSI_CTRLRS]; +static struct spdk_vhost_dev *spdk_vhost_ctrlrs[MAX_SCSI_CTRLRS]; -struct spdk_vhost_scsi_ctrlr * -spdk_vhost_scsi_ctrlr_find(const char *ctrlr_name) +struct spdk_vhost_dev * +spdk_vhost_dev_find(const char *ctrlr_name) { unsigned i; size_t dev_dirname_len = strlen(dev_dirname); @@ -910,9 +901,10 @@ static const struct vhost_device_ops spdk_vhost_scsi_device_ops = { }; int -spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask) +spdk_vhost_scsi_dev_construct(const char *name, uint64_t cpumask) { - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_scsi_dev *svdev; + struct spdk_vhost_dev *vdev; unsigned ctrlr_num; char path[PATH_MAX]; struct stat file_stat; @@ -928,7 +920,7 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask) return -EINVAL; } - if (spdk_vhost_scsi_ctrlr_find(name)) { + if (spdk_vhost_dev_find(name)) { SPDK_ERRLOG("vhost scsi controller %s already exists.\n", name); return -EEXIST; } @@ -975,12 +967,13 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask) return -ENOENT; } - vdev = spdk_zmalloc(sizeof(*vdev), RTE_CACHE_LINE_SIZE, NULL); - if (vdev == NULL) { + svdev = spdk_zmalloc(sizeof(*svdev), SPDK_CACHE_LINE_SIZE, NULL); + if (svdev == NULL) { SPDK_ERRLOG("Couldn't allocate memory for vhost dev\n"); return -ENOMEM; } + vdev = &svdev->vdev; vdev->name = strdup(name); vdev->cpumask = cpumask; vdev->lcore = -1; @@ -989,7 +982,7 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask) SPDK_ERRLOG("Failed to start vhost driver for controller %s (%d): %s", name, errno, strerror(errno)); free(vdev->name); - spdk_free(vdev); + spdk_free(svdev); return -EIO; } @@ -999,12 +992,14 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask) } int -spdk_vhost_scsi_ctrlr_remove(struct spdk_vhost_scsi_ctrlr *vdev) +spdk_vhost_scsi_dev_remove(struct spdk_vhost_scsi_dev *svdev) { + struct spdk_vhost_dev *vdev; unsigned ctrlr_num; char path[PATH_MAX]; int i; + vdev = &svdev->vdev; if (vdev->lcore != -1) { SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", vdev->name); return -ENODEV; @@ -1028,7 +1023,7 @@ spdk_vhost_scsi_ctrlr_remove(struct spdk_vhost_scsi_ctrlr *vdev) } for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) { - if (vdev->scsi_dev[i]) { + if (svdev->scsi_dev[i]) { SPDK_ERRLOG("Trying to remove non-empty controller: %s.\n", vdev->name); return -EBUSY; } @@ -1042,8 +1037,12 @@ spdk_vhost_scsi_ctrlr_remove(struct spdk_vhost_scsi_ctrlr *vdev) SPDK_NOTICELOG("Controller %s: removed\n", vdev->name); + /* + * since spdk_vhost_scsi_vdev must not be in use, + * it should be already *destructed* (spdk_vhost_dev_destruct) + */ free(vdev->name); - spdk_free(spdk_vhost_ctrlrs[ctrlr_num]); + spdk_free(svdev); spdk_vhost_ctrlrs[ctrlr_num] = NULL; return 0; @@ -1073,17 +1072,18 @@ spdk_vhost_parse_core_mask(const char *mask, uint64_t *cpumask) } struct spdk_scsi_dev * -spdk_vhost_scsi_ctrlr_get_dev(struct spdk_vhost_scsi_ctrlr *ctrlr, uint8_t num) +spdk_vhost_scsi_dev_get_dev(struct spdk_vhost_scsi_dev *svdev, uint8_t num) { - assert(ctrlr != NULL); + assert(svdev != NULL); assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS); - return ctrlr->scsi_dev[num]; + return svdev->scsi_dev[num]; } int -spdk_vhost_scsi_ctrlr_add_dev(const char *ctrlr_name, unsigned scsi_dev_num, const char *lun_name) +spdk_vhost_scsi_dev_add_dev(const char *ctrlr_name, unsigned scsi_dev_num, const char *lun_name) { - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_scsi_dev *svdev; + struct spdk_vhost_dev *vdev; char dev_name[SPDK_SCSI_DEV_MAX_NAME]; int lun_id_list[1]; char *lun_names_list[1]; @@ -1107,18 +1107,20 @@ spdk_vhost_scsi_ctrlr_add_dev(const char *ctrlr_name, unsigned scsi_dev_num, con return -1; } - vdev = spdk_vhost_scsi_ctrlr_find(ctrlr_name); - if (vdev == NULL) { + svdev = (struct spdk_vhost_scsi_dev *) spdk_vhost_dev_find(ctrlr_name); + if (svdev == NULL) { SPDK_ERRLOG("Controller %s is not defined\n", ctrlr_name); return -ENODEV; } + vdev = &svdev->vdev; + if (vdev->lcore != -1) { SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", ctrlr_name); return -ENODEV; } - if (vdev->scsi_dev[scsi_dev_num] != NULL) { + if (svdev->scsi_dev[scsi_dev_num] != NULL) { SPDK_ERRLOG("Controller %s dev %u already occupied\n", ctrlr_name, scsi_dev_num); return -EEXIST; } @@ -1130,43 +1132,44 @@ spdk_vhost_scsi_ctrlr_add_dev(const char *ctrlr_name, unsigned scsi_dev_num, con lun_id_list[0] = 0; lun_names_list[0] = (char *)lun_name; - vdev->scsi_dev[scsi_dev_num] = spdk_scsi_dev_construct(dev_name, lun_names_list, lun_id_list, 1); - if (vdev->scsi_dev[scsi_dev_num] == NULL) { + svdev->scsi_dev[scsi_dev_num] = spdk_scsi_dev_construct(dev_name, lun_names_list, lun_id_list, 1); + if (svdev->scsi_dev[scsi_dev_num] == NULL) { SPDK_ERRLOG("Couldn't create spdk SCSI device '%s' using lun device '%s' in controller: %s\n", dev_name, lun_name, vdev->name); return -EINVAL; } - spdk_scsi_dev_add_port(vdev->scsi_dev[scsi_dev_num], 0, "vhost"); + spdk_scsi_dev_add_port(svdev->scsi_dev[scsi_dev_num], 0, "vhost"); SPDK_NOTICELOG("Controller %s: defined device '%s' using lun '%s'\n", vdev->name, dev_name, lun_name); return 0; } - int -spdk_vhost_scsi_ctrlr_remove_dev(struct spdk_vhost_scsi_ctrlr *vdev, unsigned scsi_dev_num) +spdk_vhost_scsi_dev_remove_dev(struct spdk_vhost_scsi_dev *svdev, unsigned scsi_dev_num) { + struct spdk_vhost_dev *vdev = &svdev->vdev; + if (vdev->lcore != -1) { SPDK_ERRLOG("Controller %s is in use and hotremove is not supported\n", vdev->name); return -EBUSY; } - if (vdev->scsi_dev[scsi_dev_num] == NULL) { + if (svdev->scsi_dev[scsi_dev_num] == NULL) { SPDK_ERRLOG("Controller %s dev %u is not occupied\n", vdev->name, scsi_dev_num); return -ENODEV; } - spdk_scsi_dev_destruct(vdev->scsi_dev[scsi_dev_num]); - vdev->scsi_dev[scsi_dev_num] = NULL; + spdk_scsi_dev_destruct(svdev->scsi_dev[scsi_dev_num]); + svdev->scsi_dev[scsi_dev_num] = NULL; SPDK_NOTICELOG("Controller %s: removed device 'Dev %u'\n", vdev->name, scsi_dev_num); return 0; } -struct spdk_vhost_scsi_ctrlr * -spdk_vhost_scsi_ctrlr_next(struct spdk_vhost_scsi_ctrlr *prev) +struct spdk_vhost_dev * +spdk_vhost_dev_next(struct spdk_vhost_dev *prev) { int i = 0; @@ -1192,17 +1195,17 @@ spdk_vhost_scsi_ctrlr_next(struct spdk_vhost_scsi_ctrlr *prev) } const char * -spdk_vhost_scsi_ctrlr_get_name(struct spdk_vhost_scsi_ctrlr *ctrlr) +spdk_vhost_dev_get_name(struct spdk_vhost_dev *vdev) { - assert(ctrlr != NULL); - return ctrlr->name; + assert(vdev != NULL); + return vdev->name; } uint64_t -spdk_vhost_scsi_ctrlr_get_cpumask(struct spdk_vhost_scsi_ctrlr *ctrlr) +spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev) { - assert(ctrlr != NULL); - return ctrlr->cpumask; + assert(vdev != NULL); + return vdev->cpumask; } static int spdk_vhost_scsi_controller_construct(void) @@ -1236,7 +1239,7 @@ static int spdk_vhost_scsi_controller_construct(void) return -1; } - if (spdk_vhost_scsi_ctrlr_construct(name, cpumask) < 0) { + if (spdk_vhost_scsi_dev_construct(name, cpumask) < 0) { return -1; } @@ -1257,7 +1260,7 @@ static int spdk_vhost_scsi_controller_construct(void) return -1; } - if (spdk_vhost_scsi_ctrlr_add_dev(name, dev_num, lun_name) < 0) { + if (spdk_vhost_scsi_dev_add_dev(name, dev_num, lun_name) < 0) { return -1; } } @@ -1270,7 +1273,7 @@ static int spdk_vhost_scsi_controller_construct(void) } static uint32_t -spdk_vhost_scsi_allocate_reactor(uint64_t cpumask) +spdk_vhost_allocate_reactor(uint64_t cpumask) { uint32_t i, selected_core; uint32_t min_ctrlrs; @@ -1306,9 +1309,8 @@ spdk_vhost_scsi_allocate_reactor(uint64_t cpumask) static int new_device(int vid) { - struct spdk_vhost_scsi_ctrlr *vdev = NULL; + struct spdk_vhost_dev *vdev = NULL; struct spdk_event *event; - struct spdk_vhost_dev *dev; char ifname[PATH_MAX]; sem_t added; @@ -1320,7 +1322,7 @@ new_device(int vid) return -1; } - vdev = spdk_vhost_scsi_ctrlr_find(ifname); + vdev = spdk_vhost_dev_find(ifname); if (vdev == NULL) { SPDK_ERRLOG("Controller %s not found.\n", ifname); return -1; @@ -1331,21 +1333,13 @@ new_device(int vid) return -1; } - dev = spdk_zmalloc(sizeof(*dev), SPDK_CACHE_LINE_SIZE, NULL); - if (dev == NULL) { - SPDK_ERRLOG("vhost device %d: Failed to allocate enough memory\n", vid); - return -1; - } - dev->vid = vid; - - if (spdk_vhost_dev_construct(dev) != 0) { - spdk_free(dev); + vdev->vid = vid; + if (spdk_vhost_dev_construct(vdev) != 0) { return -1; } - vdev->dev = dev; dpdk_vid_mapping[vid] = vdev; - vdev->lcore = spdk_vhost_scsi_allocate_reactor(vdev->cpumask); + vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask); event = vhost_sem_event_alloc(vdev->lcore, add_vdev_cb, vdev, &added); spdk_event_call(event); @@ -1380,7 +1374,7 @@ spdk_vhost_startup(void *arg1, void *arg2) static void * session_shutdown(void *arg) { - struct spdk_vhost_scsi_ctrlr *vdev = NULL; + struct spdk_vhost_dev *vdev = NULL; int i; for (i = 0; i < MAX_SCSI_CTRLRS; i++) { diff --git a/lib/vhost/vhost_rpc.c b/lib/vhost/vhost_rpc.c index 39b377265..9d7429d54 100644 --- a/lib/vhost/vhost_rpc.c +++ b/lib/vhost/vhost_rpc.c @@ -80,7 +80,7 @@ spdk_rpc_get_vhost_scsi_controllers(struct spdk_jsonrpc_server_conn *conn, const struct spdk_json_val *id) { struct spdk_json_write_ctx *w; - struct spdk_vhost_scsi_ctrlr *ctrlr = NULL; + struct spdk_vhost_dev *vdev = NULL; struct spdk_scsi_dev *dev; uint32_t i; char buf[32]; @@ -93,21 +93,21 @@ spdk_rpc_get_vhost_scsi_controllers(struct spdk_jsonrpc_server_conn *conn, w = spdk_jsonrpc_begin_result(conn, id); spdk_json_write_array_begin(w); - while ((ctrlr = spdk_vhost_scsi_ctrlr_next(ctrlr)) != NULL) { + while ((vdev = spdk_vhost_dev_next(vdev)) != NULL) { spdk_json_write_object_begin(w); spdk_json_write_name(w, "ctrlr"); - spdk_json_write_string(w, spdk_vhost_scsi_ctrlr_get_name(ctrlr)); + spdk_json_write_string(w, spdk_vhost_dev_get_name(vdev)); spdk_json_write_name(w, "cpu_mask"); - snprintf(buf, sizeof(buf), "%#" PRIx64, spdk_vhost_scsi_ctrlr_get_cpumask(ctrlr)); + snprintf(buf, sizeof(buf), "%#" PRIx64, spdk_vhost_dev_get_cpumask(vdev)); spdk_json_write_string(w, buf); spdk_json_write_name(w, "scsi_devs"); spdk_json_write_array_begin(w); for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { - dev = spdk_vhost_scsi_ctrlr_get_dev(ctrlr, i); + dev = spdk_vhost_scsi_dev_get_dev((struct spdk_vhost_scsi_dev *) vdev, i); if (!dev) continue; @@ -169,7 +169,7 @@ spdk_rpc_construct_vhost_scsi_controller(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - rc = spdk_vhost_scsi_ctrlr_construct(req.ctrlr, cpumask); + rc = spdk_vhost_scsi_dev_construct(req.ctrlr, cpumask); if (rc < 0) { goto invalid; } @@ -207,7 +207,7 @@ spdk_rpc_remove_vhost_scsi_controller(struct spdk_jsonrpc_server_conn *conn, { struct rpc_remove_vhost_scsi_ctrlr req = {NULL}; struct spdk_json_write_ctx *w; - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_dev *vdev; int rc; if (spdk_json_decode_object(params, rpc_remove_vhost_ctrlr, @@ -218,12 +218,12 @@ spdk_rpc_remove_vhost_scsi_controller(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - if (!(vdev = spdk_vhost_scsi_ctrlr_find(req.ctrlr))) { + if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) { rc = -ENODEV; goto invalid; } - rc = spdk_vhost_scsi_ctrlr_remove(vdev); + rc = spdk_vhost_scsi_dev_remove((struct spdk_vhost_scsi_dev *) vdev); if (rc < 0) { goto invalid; } @@ -280,7 +280,7 @@ spdk_rpc_add_vhost_scsi_lun(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - rc = spdk_vhost_scsi_ctrlr_add_dev(req.ctrlr, req.scsi_dev_num, req.lun_name); + rc = spdk_vhost_scsi_dev_add_dev(req.ctrlr, req.scsi_dev_num, req.lun_name); if (rc < 0) { goto invalid; } @@ -323,7 +323,7 @@ spdk_rpc_remove_vhost_scsi_dev(struct spdk_jsonrpc_server_conn *conn, { struct rpc_remove_vhost_scsi_ctrlr_dev req = {0}; struct spdk_json_write_ctx *w; - struct spdk_vhost_scsi_ctrlr *vdev; + struct spdk_vhost_dev *vdev; int rc; if (spdk_json_decode_object(params, rpc_vhost_remove_dev, @@ -334,12 +334,12 @@ spdk_rpc_remove_vhost_scsi_dev(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - if (!(vdev = spdk_vhost_scsi_ctrlr_find(req.ctrlr))) { + if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) { rc = -ENODEV; goto invalid; } - rc = spdk_vhost_scsi_ctrlr_remove_dev(vdev, req.scsi_dev_num); + rc = spdk_vhost_scsi_dev_remove_dev((struct spdk_vhost_scsi_dev *) vdev, req.scsi_dev_num); if (rc < 0) { goto invalid; }