Commit 7fcbd022 authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

lib/vhost: alloc VQ tasks in VQ setting function



Currently we will allocate all VQ's tasks when starting
the device, it will not allow us to add new VQ after
starting the device, so here, we move it to VQ setting
function.

Change-Id: I59cfc393d66779ab8a0eb704bc73bcede3f0a2a0
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14926


Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent d55bf60a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,8 @@ enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
{
	struct spdk_vhost_virtqueue *q;
	bool packed_ring;
	const struct spdk_vhost_user_dev_backend *backend;
	int rc;

	if (qid >= SPDK_VHOST_MAX_VQUEUES) {
		return -EINVAL;
@@ -1047,6 +1049,12 @@ enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
		return 0;
	}

	backend = to_user_dev(vsession->vdev)->user_backend;
	rc = backend->alloc_vq_tasks(vsession, qid);
	if (rc) {
		return rc;
	}

	/*
	 * Not sure right now but this look like some kind of QEMU bug and guest IO
	 * might be frozed without kicking all queues after live-migration. This look like
+33 −37
Original line number Diff line number Diff line
@@ -1246,26 +1246,28 @@ free_task_pool(struct spdk_vhost_blk_session *bvsession)
}

static int
alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid)
{
	struct spdk_vhost_session *vsession = &bvsession->vsession;
	struct spdk_vhost_blk_session *bvsession = to_blk_session(vsession);
	struct spdk_vhost_virtqueue *vq;
	struct spdk_vhost_user_blk_task *task;
	uint32_t task_cnt;
	uint16_t i;
	uint32_t j;

	for (i = 0; i < vsession->max_queues; i++) {
		vq = &vsession->virtqueue[i];
	if (qid >= SPDK_VHOST_MAX_VQUEUES) {
		return -EINVAL;
	}

	vq = &vsession->virtqueue[qid];
	if (vq->vring.desc == NULL) {
			continue;
		return 0;
	}

	task_cnt = vq->vring.size;
	if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
		/* sanity check */
		SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
			    vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
		free_task_pool(bvsession);
		return -1;
	}
@@ -1274,7 +1276,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
				 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
	if (vq->tasks == NULL) {
		SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
				    vsession->name, task_cnt, i);
			    vsession->name, task_cnt, qid);
		free_task_pool(bvsession);
		return -1;
	}
@@ -1285,7 +1287,6 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
		task->req_idx = j;
		task->vq = vq;
	}
	}

	return 0;
}
@@ -1313,12 +1314,6 @@ vhost_blk_start(struct spdk_vhost_dev *vdev,
		}
	}

	rc = alloc_task_pool(bvsession);
	if (rc != 0) {
		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
		return rc;
	}

	if (bvdev->bdev) {
		bvsession->io_channel = vhost_blk_get_io_channel(vdev);
		if (!bvsession->io_channel) {
@@ -1544,6 +1539,7 @@ static const struct spdk_vhost_user_dev_backend vhost_blk_user_device_backend =
	.session_ctx_size = sizeof(struct spdk_vhost_blk_session) - sizeof(struct spdk_vhost_session),
	.start_session =  vhost_blk_start,
	.stop_session = vhost_blk_stop,
	.alloc_vq_tasks = alloc_vq_task_pool,
};

static const struct spdk_vhost_dev_backend vhost_blk_device_backend = {
+1 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ struct spdk_vhost_user_dev_backend {

	spdk_vhost_session_fn start_session;
	int (*stop_session)(struct spdk_vhost_session *vsession);
	int (*alloc_vq_tasks)(struct spdk_vhost_session *vsession, uint16_t qid);
};

enum vhost_backend_type {
+34 −37
Original line number Diff line number Diff line
@@ -122,11 +122,13 @@ static void vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
static int vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev,
					unsigned scsi_tgt_num);
static int alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid);

static const struct spdk_vhost_user_dev_backend spdk_vhost_scsi_user_device_backend = {
	.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
	.start_session =  vhost_scsi_start,
	.stop_session = vhost_scsi_stop,
	.alloc_vq_tasks = alloc_vq_task_pool,
};

static const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
@@ -1307,26 +1309,28 @@ free_task_pool(struct spdk_vhost_scsi_session *svsession)
}

static int
alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid)
{
	struct spdk_vhost_session *vsession = &svsession->vsession;
	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
	struct spdk_vhost_virtqueue *vq;
	struct spdk_vhost_scsi_task *task;
	uint32_t task_cnt;
	uint16_t i;
	uint32_t j;

	for (i = 0; i < vsession->max_queues; i++) {
		vq = &vsession->virtqueue[i];
	if (qid >= SPDK_VHOST_MAX_VQUEUES) {
		return -EINVAL;
	}

	vq = &vsession->virtqueue[qid];
	if (vq->vring.desc == NULL) {
			continue;
		return 0;
	}

	task_cnt = vq->vring.size;
	if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
		/* sanity check */
		SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
			    vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
		free_task_pool(svsession);
		return -1;
	}
@@ -1335,7 +1339,7 @@ alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
				 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
	if (vq->tasks == NULL) {
		SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
				    vsession->name, task_cnt, i);
			    vsession->name, task_cnt, qid);
		free_task_pool(svsession);
		return -1;
	}
@@ -1346,7 +1350,6 @@ alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
		task->vq = vq;
		task->req_idx = j;
	}
	}

	return 0;
}
@@ -1373,12 +1376,6 @@ vhost_scsi_start(struct spdk_vhost_dev *vdev,
		}
	}

	rc = alloc_task_pool(svsession);
	if (rc != 0) {
		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
		return rc;
	}

	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
		state = &svdev->scsi_dev_state[i];
		if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {