Commit bd7b05e4 authored by Darek Stojaczyk's avatar Darek Stojaczyk
Browse files

vhost/blk: refactor APIs to base on sessions



Prepared APIs to operate on a session parameter rather
than a device parameter. Some of those functions are
now ready to support more than one session per device.

Change-Id: Id55e70ae521039f5acc47e80ab8b0aa043679d95
Signed-off-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/438679


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent a9019c6d
Loading
Loading
Loading
Loading
+36 −28
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@

struct spdk_vhost_blk_task {
	struct spdk_bdev_io *bdev_io;
	struct spdk_vhost_blk_dev *bvdev;
	struct spdk_vhost_blk_session *bvsession;
	struct spdk_vhost_virtqueue *vq;

	volatile uint8_t *status;
@@ -85,14 +85,15 @@ struct spdk_vhost_blk_session {
static const struct spdk_vhost_dev_backend vhost_blk_device_backend;

static int
process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev *bvdev,
process_blk_request(struct spdk_vhost_blk_task *task,
		    struct spdk_vhost_blk_session *bvsession,
		    struct spdk_vhost_virtqueue *vq);

static void
blk_task_finish(struct spdk_vhost_blk_task *task)
{
	assert(task->bvdev->vdev.session->task_cnt > 0);
	task->bvdev->vdev.session->task_cnt--;
	assert(task->bvsession->vsession.task_cnt > 0);
	task->bvsession->vsession.task_cnt--;
	task->used = false;
}

@@ -103,7 +104,7 @@ invalid_blk_request(struct spdk_vhost_blk_task *task, uint8_t status)
		*task->status = status;
	}

	spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
	spdk_vhost_vq_used_ring_enqueue(&task->bvsession->vsession, task->vq, task->req_idx,
					task->used_len);
	blk_task_finish(task);
	SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK_DATA, "Invalid request (status=%" PRIu8")\n", status);
@@ -117,15 +118,17 @@ invalid_blk_request(struct spdk_vhost_blk_task *task, uint8_t status)
 *   FIXME: Make this function return to rd_cnt and wr_cnt
 */
static int
blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uint16_t req_idx,
	       struct iovec *iovs, uint16_t *iovs_cnt, uint32_t *length)
blk_iovs_setup(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq,
	       uint16_t req_idx, struct iovec *iovs, uint16_t *iovs_cnt, uint32_t *length)
{
	struct spdk_vhost_session *vsession = &bvsession->vsession;
	struct spdk_vhost_dev *vdev = vsession->vdev;
	struct vring_desc *desc, *desc_table;
	uint16_t out_cnt = 0, cnt = 0;
	uint32_t desc_table_size, len = 0;
	int rc;

	rc = spdk_vhost_vq_get_desc(vdev->session, vq, req_idx, &desc, &desc_table, &desc_table_size);
	rc = spdk_vhost_vq_get_desc(vsession, vq, req_idx, &desc, &desc_table, &desc_table_size);
	if (rc != 0) {
		SPDK_ERRLOG("%s: Invalid descriptor at index %"PRIu16".\n", vdev->name, req_idx);
		return -1;
@@ -142,7 +145,7 @@ blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uin
			return -1;
		}

		if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vdev->session, iovs, &cnt, desc))) {
		if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vsession, iovs, &cnt, desc))) {
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Invalid descriptor %" PRIu16" (req_idx = %"PRIu16").\n",
				      req_idx, cnt);
			return -1;
@@ -180,7 +183,7 @@ static void
blk_request_finish(bool success, struct spdk_vhost_blk_task *task)
{
	*task->status = success ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR;
	spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
	spdk_vhost_vq_used_ring_enqueue(&task->bvsession->vsession, task->vq, task->req_idx,
					task->used_len);
	SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Finished task (%p) req_idx=%d\n status: %s\n", task,
		      task->req_idx, success ? "OK" : "FAIL");
@@ -202,7 +205,7 @@ blk_request_resubmit(void *arg)
	struct spdk_vhost_blk_task *task = (struct spdk_vhost_blk_task *)arg;
	int rc = 0;

	rc = process_blk_request(task, task->bvdev, task->vq);
	rc = process_blk_request(task, task->bvsession, task->vq);
	if (rc == 0) {
		SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p resubmitted ======\n", task);
	} else {
@@ -214,7 +217,7 @@ static inline void
blk_request_queue_io(struct spdk_vhost_blk_task *task)
{
	int rc;
	struct spdk_vhost_blk_dev *bvdev = task->bvdev;
	struct spdk_vhost_blk_dev *bvdev = task->bvsession->bvdev;
	struct spdk_bdev *bdev = bvdev->bdev;

	task->bdev_io_wait.bdev = bdev;
@@ -229,9 +232,11 @@ blk_request_queue_io(struct spdk_vhost_blk_task *task)
}

static int
process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev *bvdev,
process_blk_request(struct spdk_vhost_blk_task *task,
		    struct spdk_vhost_blk_session *bvsession,
		    struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_blk_dev *bvdev = bvsession->bvdev;
	const struct virtio_blk_outhdr *req;
	struct virtio_blk_discard_write_zeroes *desc;
	struct iovec *iov;
@@ -239,7 +244,7 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev
	uint32_t payload_len;
	int rc;

	if (blk_iovs_setup(&bvdev->vdev, vq, task->req_idx, task->iovs, &task->iovcnt, &payload_len)) {
	if (blk_iovs_setup(bvsession, vq, task->req_idx, task->iovs, &task->iovcnt, &payload_len)) {
		SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx);
		/* Only READ and WRITE are supported for now. */
		invalid_blk_request(task, VIRTIO_BLK_S_UNSUPP);
@@ -380,8 +385,9 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev
}

static void
process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
process_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_blk_dev *bvdev = bvsession->bvdev;
	struct spdk_vhost_blk_task *task;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	int rc;
@@ -419,7 +425,7 @@ process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
		task->status = NULL;
		task->used_len = 0;

		rc = process_blk_request(task, bvdev, vq);
		rc = process_blk_request(task, bvsession, vq);
		if (rc == 0) {
			SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p req_idx %d submitted ======\n", task,
				      reqs[i]);
@@ -432,12 +438,13 @@ process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
static int
vdev_worker(void *arg)
{
	struct spdk_vhost_blk_dev *bvdev = arg;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct spdk_vhost_blk_session *bvsession = arg;
	struct spdk_vhost_session *vsession = &bvsession->vsession;

	uint16_t q_idx;

	for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
		process_vq(bvdev, &vsession->virtqueue[q_idx]);
		process_vq(bvsession, &vsession->virtqueue[q_idx]);
	}

	spdk_vhost_session_used_signal(vsession);
@@ -446,9 +453,9 @@ vdev_worker(void *arg)
}

static void
no_bdev_process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
no_bdev_process_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq)
{
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct spdk_vhost_session *vsession = &bvsession->vsession;
	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
	uint32_t length;
	uint16_t iovcnt, req_idx;
@@ -458,7 +465,7 @@ no_bdev_process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue
	}

	iovcnt = SPDK_COUNTOF(iovs);
	if (blk_iovs_setup(&bvdev->vdev, vq, req_idx, iovs, &iovcnt, &length) == 0) {
	if (blk_iovs_setup(bvsession, vq, req_idx, iovs, &iovcnt, &length) == 0) {
		*(volatile uint8_t *)iovs[iovcnt - 1].iov_base = VIRTIO_BLK_S_IOERR;
		SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK_DATA, "Aborting request %" PRIu16"\n", req_idx);
	}
@@ -469,12 +476,13 @@ no_bdev_process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue
static int
no_bdev_vdev_worker(void *arg)
{
	struct spdk_vhost_blk_dev *bvdev = arg;
	struct spdk_vhost_session *vsession = bvdev->vdev.session;
	struct spdk_vhost_blk_session *bvsession = arg;
	struct spdk_vhost_session *vsession = &bvsession->vsession;
	struct spdk_vhost_blk_dev *bvdev = bvsession->bvdev;
	uint16_t q_idx;

	for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
		no_bdev_process_vq(bvdev, &vsession->virtqueue[q_idx]);
		no_bdev_process_vq(bvsession, &vsession->virtqueue[q_idx]);
	}

	spdk_vhost_session_used_signal(vsession);
@@ -536,7 +544,7 @@ _bdev_remove_cb(struct spdk_vhost_dev *vdev, void *arg)
		     bvdev->vdev.name);
	if (bvsession != NULL && bvsession->requestq_poller) {
		spdk_poller_unregister(&bvsession->requestq_poller);
		bvsession->requestq_poller = spdk_poller_register(no_bdev_vdev_worker, bvdev, 0);
		bvsession->requestq_poller = spdk_poller_register(no_bdev_vdev_worker, bvsession, 0);
	}

	spdk_bdev_close(bvdev->bdev_desc);
@@ -607,7 +615,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)

		for (j = 0; j < task_cnt; j++) {
			task = &((struct spdk_vhost_blk_task *)vq->tasks)[j];
			task->bvdev = bvdev;
			task->bvsession = bvsession;
			task->req_idx = j;
			task->vq = vq;
		}
@@ -665,7 +673,7 @@ spdk_vhost_blk_start(struct spdk_vhost_dev *vdev, void *event_ctx)
	}

	bvsession->requestq_poller = spdk_poller_register(bvdev->bdev ? vdev_worker : no_bdev_vdev_worker,
				     bvdev, 0);
				     bvsession, 0);
	SPDK_INFOLOG(SPDK_LOG_VHOST, "Started poller for vhost controller %s on lcore %d\n",
		     vdev->name, vdev->lcore);
out: