Commit b3ecb4c4 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

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: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/366719


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 475d4003
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -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");
	}

	assert(((struct spdk_vhost_dev *) svdev)->task_cnt <= INT_MAX - count);
	((struct spdk_vhost_dev *) svdev)->task_cnt += count;

	for (i = 0; i < count; ++i) {
		task = tasks[i];
		memset(task, 0, sizeof(*task));
	task->svdev = vdev;

	assert(((struct spdk_vhost_dev *) task->svdev)->task_cnt < INT_MAX);
	((struct spdk_vhost_dev *) task->svdev)->task_cnt++;
		task->svdev = svdev;
		spdk_scsi_task_construct(&task->scsi,
					 cpl_fn,
					 spdk_vhost_task_free_cb,
					 NULL);

	return task;
	}
}

int
+3 −2
Original line number Diff line number Diff line
@@ -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,
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 */
+26 −22
Original line number Diff line number Diff line
@@ -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];