vhost: negotiate the packed ring feature
Add the packed ring support in spdk vhost. Negotiate packed ring feature when start device. Change-Id: Idef50a1426b6e38d789d8c6982a3ed7594e32cf5 Signed-off-by: Jin Yu <jin.yu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/672 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
4d2e26d888
commit
39276ee82c
@ -880,9 +880,24 @@ _stop_session(struct spdk_vhost_session *vsession)
|
||||
|
||||
for (i = 0; i < vsession->max_queues; i++) {
|
||||
q = &vsession->virtqueue[i];
|
||||
|
||||
/* 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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Packed virtqueues support up to 2^15 entries each
|
||||
* so left one bit can be used as wrap counter.
|
||||
*/
|
||||
if (q->packed.packed_ring) {
|
||||
q->last_avail_idx = q->last_avail_idx |
|
||||
((uint16_t)q->packed.avail_phase << 15);
|
||||
q->last_used_idx = q->last_used_idx |
|
||||
((uint16_t)q->packed.used_phase << 15);
|
||||
}
|
||||
|
||||
rte_vhost_set_vring_base(vsession->vid, i, q->last_avail_idx, q->last_used_idx);
|
||||
}
|
||||
|
||||
@ -925,6 +940,7 @@ vhost_start_device_cb(int vid)
|
||||
struct spdk_vhost_session *vsession;
|
||||
int rc = -1;
|
||||
uint16_t i;
|
||||
bool packed_ring;
|
||||
|
||||
pthread_mutex_lock(&g_vhost_mutex);
|
||||
|
||||
@ -941,6 +957,13 @@ vhost_start_device_cb(int vid)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vhost_get_negotiated_features(vid, &vsession->negotiated_features) != 0) {
|
||||
SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
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++) {
|
||||
@ -953,6 +976,9 @@ vhost_start_device_cb(int vid)
|
||||
q->vring_idx = i;
|
||||
rte_vhost_get_vhost_ring_inflight(vid, i, &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;
|
||||
}
|
||||
@ -962,14 +988,24 @@ vhost_start_device_cb(int vid)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Disable I/O submission notifications, we'll be polling. */
|
||||
q->vring.used->flags = VRING_USED_F_NO_NOTIFY;
|
||||
vsession->max_queues = i + 1;
|
||||
}
|
||||
if (packed_ring) {
|
||||
/* Packed virtqueues support up to 2^15 entries each
|
||||
* so left one bit can be used as wrap counter.
|
||||
*/
|
||||
q->packed.avail_phase = q->last_avail_idx >> 15;
|
||||
q->last_avail_idx = q->last_avail_idx & 0x7FFF;
|
||||
q->packed.used_phase = q->last_used_idx >> 15;
|
||||
q->last_used_idx = q->last_used_idx & 0x7FFF;
|
||||
|
||||
if (vhost_get_negotiated_features(vid, &vsession->negotiated_features) != 0) {
|
||||
SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
|
||||
goto out;
|
||||
/* Disable I/O submission notifications, we'll be polling. */
|
||||
q->vring.device_event->flags = VRING_PACKED_EVENT_FLAG_DISABLE;
|
||||
} else {
|
||||
/* Disable I/O submission notifications, we'll be polling. */
|
||||
q->vring.used->flags = VRING_USED_F_NO_NOTIFY;
|
||||
}
|
||||
|
||||
q->packed.packed_ring = packed_ring;
|
||||
vsession->max_queues = i + 1;
|
||||
}
|
||||
|
||||
if (vhost_get_mem_table(vid, &vsession->mem) != 0) {
|
||||
@ -989,6 +1025,9 @@ vhost_start_device_cb(int vid)
|
||||
for (i = 0; i < vsession->max_queues; i++) {
|
||||
struct spdk_vhost_virtqueue *q = &vsession->virtqueue[i];
|
||||
|
||||
/* 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) {
|
||||
rte_vhost_vring_call(vsession->vid, q->vring_idx);
|
||||
}
|
||||
|
@ -68,7 +68,6 @@
|
||||
*/
|
||||
#define SPDK_VHOST_COALESCING_DELAY_BASE_US 0
|
||||
|
||||
|
||||
#define SPDK_VHOST_FEATURES ((1ULL << VHOST_F_LOG_ALL) | \
|
||||
(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
|
||||
(1ULL << VIRTIO_F_VERSION_1) | \
|
||||
@ -88,6 +87,19 @@ struct spdk_vhost_virtqueue {
|
||||
uint16_t last_avail_idx;
|
||||
uint16_t last_used_idx;
|
||||
|
||||
struct {
|
||||
/* To mark a descriptor as available in packed ring
|
||||
* Equal to avail_wrap_counter in spec.
|
||||
*/
|
||||
uint8_t avail_phase : 1;
|
||||
/* To mark a descriptor as used in packed ring
|
||||
* Equal to used_wrap_counter in spec.
|
||||
*/
|
||||
uint8_t used_phase : 1;
|
||||
uint8_t padding : 5;
|
||||
bool packed_ring : 1;
|
||||
} packed;
|
||||
|
||||
void *tasks;
|
||||
|
||||
/* Request count from last stats check */
|
||||
|
Loading…
Reference in New Issue
Block a user