Commit c8bdbc12 authored by Jin Yu's avatar Jin Yu Committed by Changpeng Liu
Browse files

vhost: refactor vhost scsi process_vq



Add scsi_blk_init function to replace the common
code of task initlization. The same to process_vq
function.

Change-Id: Ied0582ad7f087990c581e6e7aacde6ec201964dc
Signed-off-by: default avatarJin Yu <jin.yu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1613


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarXiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 64cfaf3f
Loading
Loading
Loading
Loading
+45 −55
Original line number Diff line number Diff line
@@ -156,6 +156,18 @@ const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
	.remove_device = vhost_scsi_dev_remove,
};

static inline void
scsi_task_init(struct spdk_vhost_scsi_task *task)
{
	memset(&task->scsi, 0, sizeof(task->scsi));
	/* Tmf_resp pointer and resp pointer are in a union.
	 * Here means task->tmf_resp = task->resp = NULL.
	 */
	task->resp = NULL;
	task->used = true;
	task->used_len = 0;
}

static void
vhost_scsi_task_put(struct spdk_vhost_scsi_task *task)
{
@@ -683,46 +695,50 @@ process_request(struct spdk_vhost_scsi_task *task)
}

static void
process_controlq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
process_scsi_task(struct spdk_vhost_session *vsession,
		  struct spdk_vhost_virtqueue *vq,
		  uint16_t req_idx)
{
	struct spdk_vhost_session *vsession = &svsession->vsession;
	struct spdk_vhost_scsi_task *task;
	uint16_t reqs[32];
	uint16_t reqs_cnt, i;

	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
	for (i = 0; i < reqs_cnt; i++) {
		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' exceeds virtqueue size (%"PRIu16")\n",
				    vsession->name, reqs[i], vq->vring.size);
			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
			continue;
		}
	int result;

		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
	task = &((struct spdk_vhost_scsi_task *)vq->tasks)[req_idx];
	if (spdk_unlikely(task->used)) {
			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' is still in use!\n",
				    vsession->name, reqs[i]);
			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
			continue;
		SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
			    vsession->name, req_idx);
		vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
		return;
	}

	vsession->task_cnt++;
		memset(&task->scsi, 0, sizeof(task->scsi));
		task->tmf_resp = NULL;
		task->used = true;
	scsi_task_init(task);

	if (spdk_unlikely(vq->vring_idx == VIRTIO_SCSI_CONTROLQ)) {
		process_ctrl_request(task);
	} else {
		result = process_request(task);
		if (likely(result == 0)) {
			task_submit(task);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d submitted ======\n", task,
				      task->req_idx);
		} else if (result > 0) {
			vhost_scsi_task_cpl(&task->scsi);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d finished early ======\n", task,
				      task->req_idx);
		} else {
			invalid_request(task);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d failed ======\n", task,
				      task->req_idx);
		}
	}
}

static void
process_requestq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
process_vq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_session *vsession = &svsession->vsession;
	struct spdk_vhost_scsi_task *task;
	uint16_t reqs[32];
	uint16_t reqs_cnt, i;
	int result;

	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
	assert(reqs_cnt <= 32);
@@ -738,33 +754,7 @@ process_requestq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_vi
			continue;
		}

		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
		if (spdk_unlikely(task->used)) {
			SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
				    vsession->name, reqs[i]);
			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
			continue;
		}

		vsession->task_cnt++;
		memset(&task->scsi, 0, sizeof(task->scsi));
		task->resp = NULL;
		task->used = true;
		task->used_len = 0;
		result = process_request(task);
		if (likely(result == 0)) {
			task_submit(task);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d submitted ======\n", task,
				      task->req_idx);
		} else if (result > 0) {
			vhost_scsi_task_cpl(&task->scsi);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d finished early ======\n", task,
				      task->req_idx);
		} else {
			invalid_request(task);
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d failed ======\n", task,
				      task->req_idx);
		}
		process_scsi_task(vsession, vq, reqs[i]);
	}
}

@@ -777,7 +767,7 @@ vdev_mgmt_worker(void *arg)
	process_removed_devs(svsession);
	vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);

	process_controlq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
	process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
	vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);

	return -1;
@@ -791,7 +781,7 @@ vdev_worker(void *arg)
	uint32_t q_idx;

	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
		process_requestq(svsession, &vsession->virtqueue[q_idx]);
		process_vq(svsession, &vsession->virtqueue[q_idx]);
	}

	vhost_session_used_signal(vsession);