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);
/* 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 */

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);
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;

View File

@ -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);

View File

@ -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++) {

View File

@ -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;
}