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

View File

@ -64,10 +64,11 @@ struct spdk_vhost_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,
spdk_scsi_task_cpl cpl_fn);
void spdk_vhost_task_get(struct spdk_vhost_scsi_dev *svdev, void **tasks, int count,
spdk_scsi_task_cpl cpl_fn);
void spdk_vhost_task_cpl(struct spdk_scsi_task *scsi_task);
void spdk_vhost_task_mgmt_cpl(struct spdk_scsi_task *scsi_task);
#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
process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *controlq,
uint16_t req_idx)
process_ctrl_request(struct spdk_vhost_task *task)
{
struct spdk_vhost_task *task;
struct vring_desc *desc;
struct virtio_scsi_ctrl_tmf_req *ctrl_req;
struct virtio_scsi_ctrl_an_resp *an_resp;
desc = spdk_vhost_vq_get_desc(controlq, req_idx);
ctrl_req = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr);
desc = spdk_vhost_vq_get_desc(task->vq, task->req_idx);
ctrl_req = spdk_vhost_gpa_to_vva(&task->svdev->vdev, desc->addr);
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",
req_idx, desc, (void *)desc->addr, desc->len, desc->flags, controlq->last_used_idx,
controlq->kickfd, controlq->size);
task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx,
task->vq->kickfd, task->vq->size);
SPDK_TRACEDUMP(SPDK_TRACE_VHOST_SCSI_QUEUE, "Request desriptor", (uint8_t *)ctrl_req,
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);
/* 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:
/* Get the response buffer */
assert(spdk_vhost_vring_desc_has_next(desc));
desc = spdk_vhost_vring_desc_get_next(controlq->desc, desc);
task->tmf_resp = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr);
desc = spdk_vhost_vring_desc_get_next(task->vq->desc, desc);
task->tmf_resp = spdk_vhost_gpa_to_vva(&task->svdev->vdev, desc->addr);
/* Check if we are processing a valid request */
if (task->scsi_dev == NULL) {
@ -318,8 +311,8 @@ process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *
break;
case VIRTIO_SCSI_T_AN_QUERY:
case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
desc = spdk_vhost_vring_desc_get_next(controlq->desc, desc);
an_resp = spdk_vhost_gpa_to_vva(&svdev->vdev, desc->addr);
desc = spdk_vhost_vring_desc_get_next(task->vq->desc, desc);
an_resp = spdk_vhost_gpa_to_vva(&task->svdev->vdev, desc->addr);
an_resp->response = VIRTIO_SCSI_S_ABORTED;
break;
}
@ -328,7 +321,7 @@ process_ctrl_request(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *
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);
}
@ -479,33 +472,44 @@ process_request(struct spdk_vhost_task *task)
}
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_cnt, i;
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++) {
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
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_cnt, i;
struct spdk_vhost_task *task;
int result;
reqs_cnt = spdk_vhost_vq_avail_ring_get(vq, reqs, RTE_DIM(reqs));
assert(reqs_cnt <= 32);
for (i = 0; i < reqs_cnt; i++) {
task = spdk_vhost_task_get(svdev, spdk_vhost_task_cpl);
spdk_vhost_task_get(svdev, (void **)tasks, reqs_cnt, spdk_vhost_task_cpl);
for (i = 0; i < reqs_cnt; i++) {
SPDK_TRACELOG(SPDK_TRACE_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n",
reqs[i]);
task = tasks[i];
task->vq = vq;
task->svdev = svdev;
task->req_idx = reqs[i];