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: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14925
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Changpeng Liu 2022-10-11 16:14:37 +08:00 committed by Tomasz Zawadzki
parent a1cd28c6f3
commit d55bf60a89

View File

@ -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);