vhost_scsi: get vhost tasks in bulks

Instead of getting tasks from mempool 1 by 1, prefetch a whole chunk.

Change-Id: I17f61e3de9b081b61af7a2a8568681aafe26ab0a
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/366719
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-06-22 11:44:41 +02:00 committed by Jim Harris
parent 475d400394
commit b3ecb4c45c
3 changed files with 46 additions and 38 deletions

View File

@ -62,29 +62,32 @@ spdk_vhost_task_free_cb(struct spdk_scsi_task *scsi_task)
rte_mempool_put(g_task_pool, task); rte_mempool_put(g_task_pool, task);
} }
struct spdk_vhost_task * void
spdk_vhost_task_get(struct spdk_vhost_scsi_dev *vdev, spdk_scsi_task_cpl cpl_fn) spdk_vhost_task_get(struct spdk_vhost_scsi_dev *svdev, void **tasks, int count,
spdk_scsi_task_cpl cpl_fn)
{ {
struct spdk_vhost_task *task; struct spdk_vhost_task *task;
int rc; int rc, i;
rc = rte_mempool_get(g_task_pool, (void **)&task); rc = rte_mempool_get_bulk(g_task_pool, tasks, count);
if ((rc < 0) || !task) { if (rc < 0) {
SPDK_ERRLOG("Unable to get task\n"); SPDK_ERRLOG("Unable to get task\n");
rte_panic("no memory\n"); rte_panic("no memory\n");
} }
memset(task, 0, sizeof(*task)); assert(((struct spdk_vhost_dev *) svdev)->task_cnt <= INT_MAX - count);
task->svdev = vdev; ((struct spdk_vhost_dev *) svdev)->task_cnt += count;
assert(((struct spdk_vhost_dev *) task->svdev)->task_cnt < INT_MAX); for (i = 0; i < count; ++i) {
((struct spdk_vhost_dev *) task->svdev)->task_cnt++; task = tasks[i];
spdk_scsi_task_construct(&task->scsi, memset(task, 0, sizeof(*task));
cpl_fn,
spdk_vhost_task_free_cb,
NULL);
return task; task->svdev = svdev;
spdk_scsi_task_construct(&task->scsi,
cpl_fn,
spdk_vhost_task_free_cb,
NULL);
}
} }
int int

View File

@ -64,10 +64,11 @@ struct spdk_vhost_task {
}; };
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_dev *vdev, void spdk_vhost_task_get(struct spdk_vhost_scsi_dev *svdev, void **tasks, int count,
spdk_scsi_task_cpl cpl_fn); spdk_scsi_task_cpl cpl_fn);
void spdk_vhost_task_cpl(struct spdk_scsi_task *scsi_task); void spdk_vhost_task_cpl(struct spdk_scsi_task *scsi_task);
void spdk_vhost_task_mgmt_cpl(struct spdk_scsi_task *scsi_task); void spdk_vhost_task_mgmt_cpl(struct spdk_scsi_task *scsi_task);
#endif /* SPDK_VHOST_TASK_H */ #endif /* SPDK_VHOST_TASK_H */

View File

@ -262,29 +262,22 @@ get_scsi_lun(struct spdk_scsi_dev *scsi_dev, const __u8 *lun)
} }
static void static void
process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *controlq, process_ctrl_request(struct spdk_vhost_task *task)
uint16_t req_idx)
{ {
struct spdk_vhost_task *task;
struct vring_desc *desc; struct vring_desc *desc;
struct virtio_scsi_ctrl_tmf_req *ctrl_req; struct virtio_scsi_ctrl_tmf_req *ctrl_req;
struct virtio_scsi_ctrl_an_resp *an_resp; struct virtio_scsi_ctrl_an_resp *an_resp;
desc = spdk_vhost_vq_get_desc(controlq, req_idx); desc = spdk_vhost_vq_get_desc(task->vq, task->req_idx);
ctrl_req = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr); ctrl_req = spdk_vhost_gpa_to_vva(&task->svdev->vdev, desc->addr);
SPDK_TRACELOG(SPDK_TRACE_VHOST_SCSI_QUEUE, SPDK_TRACELOG(SPDK_TRACE_VHOST_SCSI_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",
req_idx, desc, (void *)desc->addr, desc->len, desc->flags, controlq->last_used_idx, task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx,
controlq->kickfd, controlq->size); task->vq->kickfd, task->vq->size);
SPDK_TRACEDUMP(SPDK_TRACE_VHOST_SCSI_QUEUE, "Request desriptor", (uint8_t *)ctrl_req, SPDK_TRACEDUMP(SPDK_TRACE_VHOST_SCSI_QUEUE, "Request desriptor", (uint8_t *)ctrl_req,
desc->len); desc->len);
task = spdk_vhost_task_get(svdev, spdk_vhost_task_mgmt_cpl);
task->vq = controlq;
task->svdev = svdev;
task->req_idx = req_idx;
task->scsi_dev = get_scsi_dev(task->svdev, ctrl_req->lun); task->scsi_dev = get_scsi_dev(task->svdev, ctrl_req->lun);
/* Process the TMF request */ /* Process the TMF request */
@ -292,8 +285,8 @@ process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *
case VIRTIO_SCSI_T_TMF: case VIRTIO_SCSI_T_TMF:
/* Get the response buffer */ /* Get the response buffer */
assert(spdk_vhost_vring_desc_has_next(desc)); assert(spdk_vhost_vring_desc_has_next(desc));
desc = spdk_vhost_vring_desc_get_next(controlq->desc, desc); desc = spdk_vhost_vring_desc_get_next(task->vq->desc, desc);
task->tmf_resp = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr); task->tmf_resp = spdk_vhost_gpa_to_vva(&task->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) {
@ -318,8 +311,8 @@ process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *
break; break;
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 = spdk_vhost_vring_desc_get_next(controlq->desc, desc); desc = spdk_vhost_vring_desc_get_next(task->vq->desc, desc);
an_resp = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr); an_resp = spdk_vhost_gpa_to_vva(&task->svdev->vdev, desc->addr);
an_resp->response = VIRTIO_SCSI_S_ABORTED; an_resp->response = VIRTIO_SCSI_S_ABORTED;
break; break;
} }
@ -328,7 +321,7 @@ process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *
break; break;
} }
spdk_vhost_vq_used_ring_enqueue(&svdev->vdev, controlq, req_idx, 0); spdk_vhost_vq_used_ring_enqueue(&task->svdev->vdev, task->vq, task->req_idx, 0);
spdk_vhost_task_put(task); spdk_vhost_task_put(task);
} }
@ -479,33 +472,44 @@ process_request(struct spdk_vhost_task *task)
} }
static void static void
process_controlq(struct spdk_vhost_scsi_dev *vdev, struct rte_vhost_vring *vq) process_controlq(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *vq)
{ {
struct spdk_vhost_task *tasks[32];
struct spdk_vhost_task *task;
uint16_t reqs[32]; uint16_t reqs[32];
uint16_t reqs_cnt, i; uint16_t reqs_cnt, i;
reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, RTE_DIM(reqs)); reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, RTE_DIM(reqs));
spdk_vhost_task_get(svdev, (void **)tasks, reqs_cnt, spdk_vhost_task_mgmt_cpl);
for (i = 0; i < reqs_cnt; i++) { for (i = 0; i < reqs_cnt; i++) {
process_ctrl_request(vdev, vq, reqs[i]); task = tasks[i];
task->vq = vq;
task->svdev = svdev;
task->req_idx = reqs[i];
process_ctrl_request(task);
} }
} }
static void static void
process_requestq(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *vq) process_requestq(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *vq)
{ {
struct spdk_vhost_task *tasks[32];
struct spdk_vhost_task *task;
uint16_t reqs[32]; uint16_t reqs[32];
uint16_t reqs_cnt, i; uint16_t reqs_cnt, i;
struct spdk_vhost_task *task;
int result; int result;
reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, RTE_DIM(reqs)); reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, RTE_DIM(reqs));
assert(reqs_cnt <= 32); assert(reqs_cnt <= 32);
for (i = 0; i < reqs_cnt; i++) { spdk_vhost_task_get(svdev, (void **)tasks, reqs_cnt, spdk_vhost_task_cpl);
task = spdk_vhost_task_get(svdev, spdk_vhost_task_cpl);
for (i = 0; i < reqs_cnt; i++) {
SPDK_TRACELOG(SPDK_TRACE_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n", SPDK_TRACELOG(SPDK_TRACE_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n",
reqs[i]); reqs[i]);
task = tasks[i];
task->vq = vq; task->vq = vq;
task->svdev = svdev; task->svdev = svdev;
task->req_idx = reqs[i]; task->req_idx = reqs[i];