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

lib/vhost: move vq settings into a function



With this change, then we can call vq settings after the
VRING_KICK message, currently we will stop/start device
multiple times when a new vq is added.

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


Community-CI: Mellanox Build Bot
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 a1cd28c6
Loading
Loading
Loading
Loading
+92 −76
Original line number Diff line number Diff line
@@ -918,6 +918,7 @@ _stop_session(struct spdk_vhost_session *vsession)

		rte_vhost_set_vring_base(vsession->vid, i, q->last_avail_idx, q->last_used_idx);
	}
	vsession->max_queues = 0;

	return 0;
}
@@ -1013,59 +1014,37 @@ vhost_user_session_start(struct spdk_vhost_dev *vdev, struct spdk_vhost_session
}

static int
start_device(int vid)
enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
{
	struct spdk_vhost_dev *vdev;
	struct spdk_vhost_session *vsession;
	int rc = -1;
	uint16_t i;
	struct spdk_vhost_virtqueue *q;
	bool packed_ring;

	spdk_vhost_lock();

	vsession = vhost_session_find_by_vid(vid);
	if (vsession == NULL) {
		SPDK_ERRLOG("Couldn't find session with vid %d.\n", vid);
		goto out;
	}

	vdev = vsession->vdev;
	if (vsession->started) {
		/* already started, nothing to do */
		rc = 0;
		goto out;
	}

	if (!vsession->mem) {
		SPDK_ERRLOG("Session %s doesn't set memory table yet\n", vsession->name);
		goto out;
	if (qid >= SPDK_VHOST_MAX_VQUEUES) {
		return -EINVAL;
	}

	q = &vsession->virtqueue[qid];
	memset(q, 0, sizeof(*q));
	packed_ring = ((vsession->negotiated_features & (1ULL << VIRTIO_F_RING_PACKED)) != 0);

	vsession->max_queues = 0;
	memset(vsession->virtqueue, 0, sizeof(vsession->virtqueue));
	for (i = 0; i < SPDK_VHOST_MAX_VQUEUES; i++) {
		struct spdk_vhost_virtqueue *q = &vsession->virtqueue[i];

	q->vsession = vsession;
	q->vring_idx = -1;
		if (rte_vhost_get_vhost_vring(vid, i, &q->vring)) {
			continue;
	if (rte_vhost_get_vhost_vring(vsession->vid, qid, &q->vring)) {
		return 0;
	}
		q->vring_idx = i;
		rte_vhost_get_vhost_ring_inflight(vid, i, &q->vring_inflight);
	q->vring_idx = qid;
	rte_vhost_get_vhost_ring_inflight(vsession->vid, qid, &q->vring_inflight);

	/* vring.desc and vring.desc_packed are in a union struct
	 * so q->vring.desc can replace q->vring.desc_packed.
	 */
	if (q->vring.desc == NULL || q->vring.size == 0) {
			continue;
		return 0;
	}

		if (rte_vhost_get_vring_base(vsession->vid, i, &q->last_avail_idx, &q->last_used_idx)) {
	if (rte_vhost_get_vring_base(vsession->vid, qid, &q->last_avail_idx, &q->last_used_idx)) {
		q->vring.desc = NULL;
			continue;
		return 0;
	}

	/*
@@ -1091,8 +1070,8 @@ start_device(int vid)
		 * supports split ring inflight because it doesn't send negotiated features
		 * before get inflight fd. Users can use RPC to enable this function.
		 */
			if (spdk_unlikely(vdev->packed_ring_recovery)) {
				rte_vhost_get_vring_base_from_inflight(vsession->vid, i,
		if (spdk_unlikely(vsession->vdev->packed_ring_recovery)) {
			rte_vhost_get_vring_base_from_inflight(vsession->vid, qid,
							       &q->last_avail_idx,
							       &q->last_used_idx);
		}
@@ -1117,7 +1096,44 @@ start_device(int vid)
	}

	q->packed.packed_ring = packed_ring;
		vsession->max_queues = i + 1;
	vsession->max_queues = spdk_max(vsession->max_queues, qid + 1);

	return 0;
}

static int
start_device(int vid)
{
	struct spdk_vhost_dev *vdev;
	struct spdk_vhost_session *vsession;
	int rc = -1;
	uint16_t i;

	spdk_vhost_lock();

	vsession = vhost_session_find_by_vid(vid);
	if (vsession == NULL) {
		SPDK_ERRLOG("Couldn't find session with vid %d.\n", vid);
		goto out;
	}

	vdev = vsession->vdev;
	if (vsession->started) {
		/* already started, nothing to do */
		rc = 0;
		goto out;
	}

	if (!vsession->mem) {
		SPDK_ERRLOG("Session %s doesn't set memory table yet\n", vsession->name);
		goto out;
	}

	for (i = 0; i < SPDK_VHOST_MAX_VQUEUES; i++) {
		rc = enable_device_vq(vsession, i);
		if (rc != 0) {
			goto out;
		}
	}

	vhost_user_session_set_coalescing(vdev, vsession, NULL);