vhost: generalized spdk_vhost_dev struct

Moved controller-related variables from spdk_vhost_scsi_controller to
spdk_vhost_dev. Generalized vhost to operate on non scsi-specific
controller struct.

Now spdk_vhost_scsi_dev contains direct spdk_vhost_dev field instead
of a pointer. This means there is no more allocation/deallocation
on poller start/stop.

Change-Id: I99739d58833ee023a75cb530cc80294e02f28090
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/361880
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-05-17 14:42:20 +02:00 committed by Jim Harris
parent 78360d5646
commit c6745bc2b8
5 changed files with 168 additions and 171 deletions

View File

@ -52,24 +52,25 @@ void spdk_vhost_startup(void *arg1, void *arg2);
void spdk_vhost_shutdown_cb(void); void spdk_vhost_shutdown_cb(void);
/* Forward declaration */ /* Forward declaration */
struct spdk_vhost_scsi_ctrlr; struct spdk_vhost_dev;
struct spdk_vhost_scsi_dev;
/** /**
* Get handle to next controller. * Get handle to next controller.
* \param prev Previous controller or NULL to get first one. * \param prev Previous controller or NULL to get first one.
* \return handle to next controller ot NULL if prev was the last 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); 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_scsi_ctrlr_get_name(struct spdk_vhost_scsi_ctrlr *ctrl); const char *spdk_vhost_dev_get_name(struct spdk_vhost_dev *ctrl);
uint64_t spdk_vhost_scsi_ctrlr_get_cpumask(struct spdk_vhost_scsi_ctrlr *ctrl); uint64_t spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *ctrl);
struct spdk_vhost_scsi_ctrlr *spdk_vhost_scsi_ctrlr_find(const char *ctrlr_name); int spdk_vhost_scsi_dev_construct(const char *name, uint64_t cpumask);
int spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask); int spdk_vhost_scsi_dev_remove(struct spdk_vhost_scsi_dev *vdev);
int spdk_vhost_scsi_ctrlr_remove(struct spdk_vhost_scsi_ctrlr *vdev);
int spdk_vhost_parse_core_mask(const char *mask, uint64_t *cpumask); 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); 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_dev_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_remove_dev(struct spdk_vhost_scsi_dev *vdev, unsigned scsi_dev_num);
#endif /* SPDK_VHOST_H */ #endif /* SPDK_VHOST_H */

View File

@ -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); struct spdk_vhost_task *task = container_of(scsi_task, struct spdk_vhost_task, scsi);
rte_mempool_put(g_task_pool, task); 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 * 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; struct spdk_vhost_task *task;
int rc; int rc;
@ -84,8 +84,8 @@ spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev)
} }
memset(task, 0, sizeof(*task)); memset(task, 0, sizeof(*task));
task->vdev = vdev; task->svdev = vdev;
spdk_vhost_scsi_ctrlr_task_ref(task->vdev); spdk_vhost_dev_task_ref((struct spdk_vhost_dev *) task->svdev);
spdk_scsi_task_construct(&task->scsi, spdk_vhost_task_free_cb, NULL); spdk_scsi_task_construct(&task->scsi, spdk_vhost_task_free_cb, NULL);
return task; return task;

View File

@ -39,6 +39,8 @@
/* Allocated iovec buffer len */ /* Allocated iovec buffer len */
#define VHOST_SCSI_IOVS_LEN 128 #define VHOST_SCSI_IOVS_LEN 128
struct spdk_vhost_dev;
struct spdk_vhost_task { struct spdk_vhost_task {
struct spdk_scsi_task scsi; struct spdk_scsi_task scsi;
@ -47,7 +49,7 @@ struct spdk_vhost_task {
struct virtio_scsi_ctrl_tmf_resp *tmf_resp; 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; struct spdk_scsi_dev *scsi_dev;
int req_idx; 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); struct spdk_vhost_task *spdk_vhost_dequeue_task(void);
void spdk_vhost_task_put(struct spdk_vhost_task *task); 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_dev_task_ref(struct spdk_vhost_dev *vdev);
void spdk_vhost_scsi_ctrlr_task_unref(struct spdk_vhost_scsi_ctrlr *vdev); void spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev);
void spdk_vhost_iovec_free(struct iovec *iov); void spdk_vhost_iovec_free(struct iovec *iov);
struct iovec *spdk_vhost_iovec_alloc(void); struct iovec *spdk_vhost_iovec_alloc(void);

View File

@ -95,35 +95,36 @@ static char dev_dirname[PATH_MAX] = "";
struct spdk_vhost_dev { struct spdk_vhost_dev {
struct rte_vhost_memory *mem; struct rte_vhost_memory *mem;
char *name;
int vid; int vid;
int task_cnt;
int32_t lcore;
uint64_t cpumask;
uint16_t num_queues; uint16_t num_queues;
uint64_t negotiated_features; uint64_t negotiated_features;
struct rte_vhost_vring virtqueue[MAX_VHOST_VRINGS] __attribute((aligned(SPDK_CACHE_LINE_SIZE))); struct rte_vhost_vring virtqueue[MAX_VHOST_VRINGS] __attribute((aligned(SPDK_CACHE_LINE_SIZE)));
}; };
static void static void
spdk_vhost_dev_free(struct spdk_vhost_dev *dev) spdk_vhost_dev_destruct(struct spdk_vhost_dev *vdev)
{
free(dev->mem);
spdk_free(dev);
}
static void
spdk_vhost_dev_destruct(struct spdk_vhost_dev *dev)
{ {
struct rte_vhost_vring *q; struct rte_vhost_vring *q;
uint16_t i; uint16_t i;
for (i = 0; i < dev->num_queues; i++) { for (i = 0; i < vdev->num_queues; i++) {
q = &dev->virtqueue[i]; q = &vdev->virtqueue[i];
rte_vhost_set_vhost_vring_last_idx(dev->vid, i, q->last_avail_idx, q->last_used_idx); rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx);
} }
free(vdev->mem);
} }
static int 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 num_queues = rte_vhost_get_vring_num(vid);
uint16_t i; uint16_t i;
@ -134,7 +135,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *dev)
} }
for (i = 0; i < num_queues; i++) { 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); SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
return -1; 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); SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
return -1; 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); SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid);
return -1; 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); return rte_vhost_gpa_to_vva(vdev->mem, addr);
} }
struct spdk_vhost_scsi_ctrlr { struct spdk_vhost_scsi_dev {
char *name; struct spdk_vhost_dev vdev;
struct spdk_vhost_dev *dev;
/**< 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]; struct spdk_scsi_dev *scsi_dev[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
int task_cnt;
struct spdk_poller *requestq_poller; struct spdk_poller *requestq_poller;
struct spdk_poller *controlq_poller; struct spdk_poller *controlq_poller;
int32_t lcore;
uint64_t cpumask;
} __rte_cache_aligned; } __rte_cache_aligned;
/* This maps from the integer index passed by DPDK to the our controller representation. */ /* This maps from the integer index passed by DPDK to the our controller representation. */
/* MAX_VHOST_DEVICE from DPDK. */ /* 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. * 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 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)) { spdk_unlikely(vq->avail->idx == vq->last_avail_idx)) {
return 1; 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. * Enqueue id and len to used ring.
*/ */
static void 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) uint32_t len)
{ {
struct vring_used *used = vq->used; 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(); rte_compiler_barrier();
vq->used->idx = vq->last_used_idx; 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); eventfd_write(vq->callfd, (eventfd_t)1);
} }
} }
@ -287,7 +277,7 @@ submit_completion(struct spdk_vhost_task *task)
struct iovec *iovs = NULL; struct iovec *iovs = NULL;
int result; 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); SPDK_TRACELOG(SPDK_TRACE_VHOST, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
if (task->scsi.iovs != &task->scsi.iov) { 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 static void
invalid_request(struct spdk_vhost_task *task) 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_vhost_task_put(task);
SPDK_TRACELOG(SPDK_TRACE_VHOST, "Invalid request (status=%" PRIu8")\n", 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 * 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); SPDK_TRACEDUMP(SPDK_TRACE_VHOST_QUEUE, "LUN", lun, 8);
/* First byte must be 1 and second is target */ /* First byte must be 1 and second is target */
if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS)
return NULL; return NULL;
return vdev->scsi_dev[lun[1]]; return svdev->scsi_dev[lun[1]];
} }
static struct spdk_scsi_lun * static struct spdk_scsi_lun *
@ -412,21 +402,21 @@ get_scsi_lun(struct spdk_scsi_dev *scsi_dev, const __u8 *lun)
} }
void 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); assert(vdev->task_cnt < INT_MAX);
vdev->task_cnt++; vdev->task_cnt++;
} }
void 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); assert(vdev->task_cnt > 0);
vdev->task_cnt--; vdev->task_cnt--;
} }
static void 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) uint16_t req_idx)
{ {
struct spdk_vhost_task *task; 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; struct virtio_scsi_ctrl_an_resp *an_resp;
desc = &controlq->desc[req_idx]; 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, 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", "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, SPDK_TRACEDUMP(SPDK_TRACE_VHOST_QUEUE, "Request desriptor", (uint8_t *)ctrl_req,
desc->len); desc->len);
task = spdk_vhost_task_get(vdev); task = spdk_vhost_task_get(svdev);
task->vq = controlq; task->vq = controlq;
task->vdev = vdev; task->svdev = svdev;
task->req_idx = req_idx; 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 */ /* Process the TMF request */
switch (ctrl_req->type) { 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 */ /* Get the response buffer */
assert(vring_desc_has_next(desc)); assert(vring_desc_has_next(desc));
desc = vring_desc_get_next(controlq->desc, 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 */ /* Check if we are processing a valid request */
if (task->scsi_dev == NULL) { 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_QUERY:
case VIRTIO_SCSI_T_AN_SUBSCRIBE: { case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
desc = vring_desc_get_next(controlq->desc, desc); 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; an_resp->response = VIRTIO_SCSI_S_ABORTED;
break; break;
} }
@ -492,7 +482,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring
break; 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); spdk_vhost_task_put(task);
} }
@ -508,7 +498,7 @@ task_data_setup(struct spdk_vhost_task *task,
struct virtio_scsi_cmd_req **req) struct virtio_scsi_cmd_req **req)
{ {
struct rte_vhost_vring *vq = task->vq; 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 vring_desc *desc = &task->vq->desc[task->req_idx];
struct iovec *iovs = task->scsi.iovs; struct iovec *iovs = task->scsi.iovs;
uint16_t iovcnt = 0, iovcnt_max = task->scsi.iovcnt; uint16_t iovcnt = 0, iovcnt_max = task->scsi.iovcnt;
@ -523,7 +513,7 @@ task_data_setup(struct spdk_vhost_task *task,
goto abort_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); 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; 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] * 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)) { if (!vring_desc_has_next(desc)) {
/* /*
* TEST UNIT READY command and some others might not contain any payload and this is not an error. * 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. */ /* All remaining descriptors are data. */
while (iovcnt < iovcnt_max) { 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; iovs[iovcnt].iov_len = desc->len;
len += desc->len; len += desc->len;
iovcnt++; iovcnt++;
@ -596,7 +586,7 @@ task_data_setup(struct spdk_vhost_task *task,
/* Process descriptors up to response. */ /* Process descriptors up to response. */
while (!vring_desc_is_wr(desc) && iovcnt < iovcnt_max) { 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; iovs[iovcnt].iov_len = desc->len;
len += desc->len; len += desc->len;
iovcnt++; iovcnt++;
@ -610,7 +600,7 @@ task_data_setup(struct spdk_vhost_task *task,
desc = vring_desc_get_next(vq->desc, desc); 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)) { if (vring_desc_has_next(desc)) {
SPDK_WARNLOG("TO_DEV cmd: ignoring unexpected descriptors after response descriptor.\n"); 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; 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)) { if (unlikely(task->scsi_dev == NULL)) {
task->resp->response = VIRTIO_SCSI_S_BAD_TARGET; task->resp->response = VIRTIO_SCSI_S_BAD_TARGET;
return -1; return -1;
@ -664,7 +654,7 @@ process_request(struct spdk_vhost_task *task)
} }
static void 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[32];
uint16_t reqs_cnt, i; uint16_t reqs_cnt, i;
@ -676,7 +666,7 @@ process_controlq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq)
} }
static void 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[32];
uint16_t reqs_cnt, i; 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); assert(reqs_cnt <= 32);
for (i = 0; i < reqs_cnt; i++) { 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", SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Starting processing request idx %"PRIu16"======\n",
reqs[i]); reqs[i]);
task->vq = vq; task->vq = vq;
task->vdev = vdev; task->svdev = svdev;
task->req_idx = reqs[i]; task->req_idx = reqs[i];
result = process_request(task); result = process_request(task);
if (likely(result == 0)) { if (likely(result == 0)) {
@ -712,19 +702,19 @@ process_requestq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq)
static void static void
vdev_controlq_worker(void *arg) 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 static void
vdev_worker(void *arg) vdev_worker(void *arg)
{ {
struct spdk_vhost_scsi_ctrlr *vdev = arg; struct spdk_vhost_scsi_dev *svdev = arg;
uint32_t q_idx; uint32_t q_idx;
for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vdev->dev->num_queues; q_idx++) { for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < svdev->vdev.num_queues; q_idx++) {
process_requestq(vdev, &vdev->dev->virtqueue[q_idx]); process_requestq(svdev, &svdev->vdev.virtqueue[q_idx]);
} }
} }
@ -766,21 +756,22 @@ vhost_sem_timedwait(sem_t *sem, unsigned sec)
static void static void
add_vdev_cb(void *arg1, void *arg2) 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; struct rte_vhost_mem_region *region;
uint32_t i; uint32_t i;
for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; 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; 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); 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; uint64_t start, end, len;
region = &vdev->dev->mem->regions[i]; region = &vdev->mem->regions[i];
start = FLOOR_2MB(region->mmap_addr); start = FLOOR_2MB(region->mmap_addr);
end = CEIL_2MB(region->mmap_addr + region->mmap_size); end = CEIL_2MB(region->mmap_addr + region->mmap_size);
len = end - start; 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(&svdev->requestq_poller, vdev_worker, svdev, vdev->lcore, 0);
spdk_poller_register(&vdev->controlq_poller, vdev_controlq_worker, vdev, vdev->lcore, spdk_poller_register(&svdev->controlq_poller, vdev_controlq_worker, svdev, vdev->lcore,
CONTROLQ_POLL_PERIOD_US); CONTROLQ_POLL_PERIOD_US);
sem_post((sem_t *)arg2); sem_post((sem_t *)arg2);
} }
@ -800,21 +791,21 @@ add_vdev_cb(void *arg1, void *arg2)
static void static void
remove_vdev_cb(void *arg1, void *arg2) 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; struct rte_vhost_mem_region *region;
uint32_t i; uint32_t i;
for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; 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; 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); SPDK_NOTICELOG("Stopping poller for vhost controller %s\n", svdev->vdev.name);
for (i = 0; i < vdev->dev->mem->nregions; i++) { for (i = 0; i < svdev->vdev.mem->nregions; i++) {
uint64_t start, end, len; uint64_t start, end, len;
region = &vdev->dev->mem->regions[i]; region = &svdev->vdev.mem->regions[i];
start = FLOOR_2MB(region->mmap_addr); start = FLOOR_2MB(region->mmap_addr);
end = CEIL_2MB(region->mmap_addr + region->mmap_size); end = CEIL_2MB(region->mmap_addr + region->mmap_size);
len = end - start; len = end - start;
@ -828,21 +819,23 @@ remove_vdev_cb(void *arg1, void *arg2)
static void static void
destroy_device(int vid) 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; struct spdk_event *event;
sem_t done_sem; sem_t done_sem;
uint32_t i; uint32_t i;
assert(vid < MAX_VHOST_DEVICE); assert(vid < MAX_VHOST_DEVICE);
vdev = dpdk_vid_mapping[vid]; 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); 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)) if (vhost_sem_timedwait(&done_sem, 1))
rte_panic("%s: failed to unregister request queue poller.\n", vdev->name); 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); 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)) if (vhost_sem_timedwait(&done_sem, 1))
rte_panic("%s: failed to unregister control queue poller.\n", vdev->name); 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); 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); spdk_event_call(event);
if (vhost_sem_timedwait(&done_sem, 1)) if (vhost_sem_timedwait(&done_sem, 1))
rte_panic("%s: failed to unregister poller.\n", vdev->name); rte_panic("%s: failed to unregister poller.\n", vdev->name);
@ -863,19 +856,17 @@ destroy_device(int vid)
g_num_ctrlrs[vdev->lcore]--; g_num_ctrlrs[vdev->lcore]--;
vdev->lcore = -1; vdev->lcore = -1;
spdk_vhost_dev_destruct(vdev->dev); spdk_vhost_dev_destruct(&svdev->vdev);
spdk_vhost_dev_free(vdev->dev);
vdev->dev = NULL;
dpdk_vid_mapping[vid] = NULL; dpdk_vid_mapping[vid] = NULL;
} }
#define LUN_DEV_NAME_SIZE 8 #define LUN_DEV_NAME_SIZE 8
#define MAX_SCSI_CTRLRS 15 #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 * struct spdk_vhost_dev *
spdk_vhost_scsi_ctrlr_find(const char *ctrlr_name) spdk_vhost_dev_find(const char *ctrlr_name)
{ {
unsigned i; unsigned i;
size_t dev_dirname_len = strlen(dev_dirname); size_t dev_dirname_len = strlen(dev_dirname);
@ -910,9 +901,10 @@ static const struct vhost_device_ops spdk_vhost_scsi_device_ops = {
}; };
int 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; unsigned ctrlr_num;
char path[PATH_MAX]; char path[PATH_MAX];
struct stat file_stat; struct stat file_stat;
@ -928,7 +920,7 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask)
return -EINVAL; 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); SPDK_ERRLOG("vhost scsi controller %s already exists.\n", name);
return -EEXIST; return -EEXIST;
} }
@ -975,12 +967,13 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask)
return -ENOENT; return -ENOENT;
} }
vdev = spdk_zmalloc(sizeof(*vdev), RTE_CACHE_LINE_SIZE, NULL); svdev = spdk_zmalloc(sizeof(*svdev), SPDK_CACHE_LINE_SIZE, NULL);
if (vdev == NULL) { if (svdev == NULL) {
SPDK_ERRLOG("Couldn't allocate memory for vhost dev\n"); SPDK_ERRLOG("Couldn't allocate memory for vhost dev\n");
return -ENOMEM; return -ENOMEM;
} }
vdev = &svdev->vdev;
vdev->name = strdup(name); vdev->name = strdup(name);
vdev->cpumask = cpumask; vdev->cpumask = cpumask;
vdev->lcore = -1; 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, SPDK_ERRLOG("Failed to start vhost driver for controller %s (%d): %s", name, errno,
strerror(errno)); strerror(errno));
free(vdev->name); free(vdev->name);
spdk_free(vdev); spdk_free(svdev);
return -EIO; return -EIO;
} }
@ -999,12 +992,14 @@ spdk_vhost_scsi_ctrlr_construct(const char *name, uint64_t cpumask)
} }
int 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; unsigned ctrlr_num;
char path[PATH_MAX]; char path[PATH_MAX];
int i; int i;
vdev = &svdev->vdev;
if (vdev->lcore != -1) { if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", vdev->name); SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", vdev->name);
return -ENODEV; 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) { 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); SPDK_ERRLOG("Trying to remove non-empty controller: %s.\n", vdev->name);
return -EBUSY; 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); 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); free(vdev->name);
spdk_free(spdk_vhost_ctrlrs[ctrlr_num]); spdk_free(svdev);
spdk_vhost_ctrlrs[ctrlr_num] = NULL; spdk_vhost_ctrlrs[ctrlr_num] = NULL;
return 0; return 0;
@ -1073,17 +1072,18 @@ spdk_vhost_parse_core_mask(const char *mask, uint64_t *cpumask)
} }
struct spdk_scsi_dev * 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); assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
return ctrlr->scsi_dev[num]; return svdev->scsi_dev[num];
} }
int 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]; char dev_name[SPDK_SCSI_DEV_MAX_NAME];
int lun_id_list[1]; int lun_id_list[1];
char *lun_names_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; return -1;
} }
vdev = spdk_vhost_scsi_ctrlr_find(ctrlr_name); svdev = (struct spdk_vhost_scsi_dev *) spdk_vhost_dev_find(ctrlr_name);
if (vdev == NULL) { if (svdev == NULL) {
SPDK_ERRLOG("Controller %s is not defined\n", ctrlr_name); SPDK_ERRLOG("Controller %s is not defined\n", ctrlr_name);
return -ENODEV; return -ENODEV;
} }
vdev = &svdev->vdev;
if (vdev->lcore != -1) { if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", ctrlr_name); SPDK_ERRLOG("Controller %s is in use and hotplug is not supported\n", ctrlr_name);
return -ENODEV; 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); SPDK_ERRLOG("Controller %s dev %u already occupied\n", ctrlr_name, scsi_dev_num);
return -EEXIST; 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_id_list[0] = 0;
lun_names_list[0] = (char *)lun_name; 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); svdev->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) { 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", SPDK_ERRLOG("Couldn't create spdk SCSI device '%s' using lun device '%s' in controller: %s\n",
dev_name, lun_name, vdev->name); dev_name, lun_name, vdev->name);
return -EINVAL; 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", SPDK_NOTICELOG("Controller %s: defined device '%s' using lun '%s'\n",
vdev->name, dev_name, lun_name); vdev->name, dev_name, lun_name);
return 0; return 0;
} }
int 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) { if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s is in use and hotremove is not supported\n", vdev->name); SPDK_ERRLOG("Controller %s is in use and hotremove is not supported\n", vdev->name);
return -EBUSY; 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); SPDK_ERRLOG("Controller %s dev %u is not occupied\n", vdev->name, scsi_dev_num);
return -ENODEV; return -ENODEV;
} }
spdk_scsi_dev_destruct(vdev->scsi_dev[scsi_dev_num]); spdk_scsi_dev_destruct(svdev->scsi_dev[scsi_dev_num]);
vdev->scsi_dev[scsi_dev_num] = NULL; svdev->scsi_dev[scsi_dev_num] = NULL;
SPDK_NOTICELOG("Controller %s: removed device 'Dev %u'\n", SPDK_NOTICELOG("Controller %s: removed device 'Dev %u'\n",
vdev->name, scsi_dev_num); vdev->name, scsi_dev_num);
return 0; return 0;
} }
struct spdk_vhost_scsi_ctrlr * struct spdk_vhost_dev *
spdk_vhost_scsi_ctrlr_next(struct spdk_vhost_scsi_ctrlr *prev) spdk_vhost_dev_next(struct spdk_vhost_dev *prev)
{ {
int i = 0; int i = 0;
@ -1192,17 +1195,17 @@ spdk_vhost_scsi_ctrlr_next(struct spdk_vhost_scsi_ctrlr *prev)
} }
const char * 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); assert(vdev != NULL);
return ctrlr->name; return vdev->name;
} }
uint64_t 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); assert(vdev != NULL);
return ctrlr->cpumask; return vdev->cpumask;
} }
static int spdk_vhost_scsi_controller_construct(void) static int spdk_vhost_scsi_controller_construct(void)
@ -1236,7 +1239,7 @@ static int spdk_vhost_scsi_controller_construct(void)
return -1; return -1;
} }
if (spdk_vhost_scsi_ctrlr_construct(name, cpumask) < 0) { if (spdk_vhost_scsi_dev_construct(name, cpumask) < 0) {
return -1; return -1;
} }
@ -1257,7 +1260,7 @@ static int spdk_vhost_scsi_controller_construct(void)
return -1; 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; return -1;
} }
} }
@ -1270,7 +1273,7 @@ static int spdk_vhost_scsi_controller_construct(void)
} }
static uint32_t 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 i, selected_core;
uint32_t min_ctrlrs; uint32_t min_ctrlrs;
@ -1306,9 +1309,8 @@ spdk_vhost_scsi_allocate_reactor(uint64_t cpumask)
static int static int
new_device(int vid) new_device(int vid)
{ {
struct spdk_vhost_scsi_ctrlr *vdev = NULL; struct spdk_vhost_dev *vdev = NULL;
struct spdk_event *event; struct spdk_event *event;
struct spdk_vhost_dev *dev;
char ifname[PATH_MAX]; char ifname[PATH_MAX];
sem_t added; sem_t added;
@ -1320,7 +1322,7 @@ new_device(int vid)
return -1; return -1;
} }
vdev = spdk_vhost_scsi_ctrlr_find(ifname); vdev = spdk_vhost_dev_find(ifname);
if (vdev == NULL) { if (vdev == NULL) {
SPDK_ERRLOG("Controller %s not found.\n", ifname); SPDK_ERRLOG("Controller %s not found.\n", ifname);
return -1; return -1;
@ -1331,21 +1333,13 @@ new_device(int vid)
return -1; return -1;
} }
dev = spdk_zmalloc(sizeof(*dev), SPDK_CACHE_LINE_SIZE, NULL); vdev->vid = vid;
if (dev == NULL) { if (spdk_vhost_dev_construct(vdev) != 0) {
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);
return -1; return -1;
} }
vdev->dev = dev;
dpdk_vid_mapping[vid] = vdev; 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); event = vhost_sem_event_alloc(vdev->lcore, add_vdev_cb, vdev, &added);
spdk_event_call(event); spdk_event_call(event);
@ -1380,7 +1374,7 @@ spdk_vhost_startup(void *arg1, void *arg2)
static void * static void *
session_shutdown(void *arg) session_shutdown(void *arg)
{ {
struct spdk_vhost_scsi_ctrlr *vdev = NULL; struct spdk_vhost_dev *vdev = NULL;
int i; int i;
for (i = 0; i < MAX_SCSI_CTRLRS; i++) { for (i = 0; i < MAX_SCSI_CTRLRS; i++) {

View File

@ -80,7 +80,7 @@ spdk_rpc_get_vhost_scsi_controllers(struct spdk_jsonrpc_server_conn *conn,
const struct spdk_json_val *id) const struct spdk_json_val *id)
{ {
struct spdk_json_write_ctx *w; struct spdk_json_write_ctx *w;
struct spdk_vhost_scsi_ctrlr *ctrlr = NULL; struct spdk_vhost_dev *vdev = NULL;
struct spdk_scsi_dev *dev; struct spdk_scsi_dev *dev;
uint32_t i; uint32_t i;
char buf[32]; 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); w = spdk_jsonrpc_begin_result(conn, id);
spdk_json_write_array_begin(w); 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_object_begin(w);
spdk_json_write_name(w, "ctrlr"); 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"); 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_string(w, buf);
spdk_json_write_name(w, "scsi_devs"); spdk_json_write_name(w, "scsi_devs");
spdk_json_write_array_begin(w); spdk_json_write_array_begin(w);
for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { 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) if (!dev)
continue; continue;
@ -169,7 +169,7 @@ spdk_rpc_construct_vhost_scsi_controller(struct spdk_jsonrpc_server_conn *conn,
goto invalid; goto invalid;
} }
rc = spdk_vhost_scsi_ctrlr_construct(req.ctrlr, cpumask); rc = spdk_vhost_scsi_dev_construct(req.ctrlr, cpumask);
if (rc < 0) { if (rc < 0) {
goto invalid; 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 rpc_remove_vhost_scsi_ctrlr req = {NULL};
struct spdk_json_write_ctx *w; struct spdk_json_write_ctx *w;
struct spdk_vhost_scsi_ctrlr *vdev; struct spdk_vhost_dev *vdev;
int rc; int rc;
if (spdk_json_decode_object(params, rpc_remove_vhost_ctrlr, 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; goto invalid;
} }
if (!(vdev = spdk_vhost_scsi_ctrlr_find(req.ctrlr))) { if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) {
rc = -ENODEV; rc = -ENODEV;
goto invalid; goto invalid;
} }
rc = spdk_vhost_scsi_ctrlr_remove(vdev); rc = spdk_vhost_scsi_dev_remove((struct spdk_vhost_scsi_dev *) vdev);
if (rc < 0) { if (rc < 0) {
goto invalid; goto invalid;
} }
@ -280,7 +280,7 @@ spdk_rpc_add_vhost_scsi_lun(struct spdk_jsonrpc_server_conn *conn,
goto invalid; 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) { if (rc < 0) {
goto invalid; 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 rpc_remove_vhost_scsi_ctrlr_dev req = {0};
struct spdk_json_write_ctx *w; struct spdk_json_write_ctx *w;
struct spdk_vhost_scsi_ctrlr *vdev; struct spdk_vhost_dev *vdev;
int rc; int rc;
if (spdk_json_decode_object(params, rpc_vhost_remove_dev, 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; goto invalid;
} }
if (!(vdev = spdk_vhost_scsi_ctrlr_find(req.ctrlr))) { if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) {
rc = -ENODEV; rc = -ENODEV;
goto invalid; 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) { if (rc < 0) {
goto invalid; goto invalid;
} }