diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 2d5298745f..8565fa1c19 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -70,7 +70,7 @@ struct vhost_virtqueue { struct vring_used *used; uint32_t size; - /* Last index used on the available ring */ + uint16_t last_avail_idx; volatile uint16_t last_used_idx; #define VIRTIO_INVALID_EVENTFD (-1) #define VIRTIO_UNINITIALIZED_EVENTFD (-2) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index e651912c52..a92377a5a3 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -343,7 +343,8 @@ vhost_user_set_vring_addr(struct virtio_net *dev, struct vhost_vring_addr *addr) "last_used_idx (%u) and vq->used->idx (%u) mismatches; " "some packets maybe resent for Tx and dropped for Rx\n", vq->last_used_idx, vq->used->idx); - vq->last_used_idx = vq->used->idx; + vq->last_used_idx = vq->used->idx; + vq->last_avail_idx = vq->used->idx; } vq->log_guest_addr = addr->log_guest_addr; @@ -367,7 +368,8 @@ static int vhost_user_set_vring_base(struct virtio_net *dev, struct vhost_vring_state *state) { - dev->virtqueue[state->index]->last_used_idx = state->num; + dev->virtqueue[state->index]->last_used_idx = state->num; + dev->virtqueue[state->index]->last_avail_idx = state->num; return 0; } diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index a59c39bb94..70301a5838 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -851,16 +851,17 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id, } } - avail_idx = *((volatile uint16_t *)&vq->avail->idx); - free_entries = avail_idx - vq->last_used_idx; + free_entries = *((volatile uint16_t *)&vq->avail->idx) - + vq->last_avail_idx; if (free_entries == 0) goto out; LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__); - /* Prefetch available ring to retrieve head indexes. */ - used_idx = vq->last_used_idx & (vq->size - 1); - rte_prefetch0(&vq->avail->ring[used_idx]); + /* Prefetch available and used ring */ + avail_idx = vq->last_avail_idx & (vq->size - 1); + used_idx = vq->last_used_idx & (vq->size - 1); + rte_prefetch0(&vq->avail->ring[avail_idx]); rte_prefetch0(&vq->used->ring[used_idx]); count = RTE_MIN(count, MAX_PKT_BURST); @@ -870,8 +871,9 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id, /* Retrieve all of the head indexes first to avoid caching issues. */ for (i = 0; i < count; i++) { - used_idx = (vq->last_used_idx + i) & (vq->size - 1); - desc_indexes[i] = vq->avail->ring[used_idx]; + avail_idx = (vq->last_avail_idx + i) & (vq->size - 1); + used_idx = (vq->last_used_idx + i) & (vq->size - 1); + desc_indexes[i] = vq->avail->ring[avail_idx]; vq->used->ring[used_idx].id = desc_indexes[i]; vq->used->ring[used_idx].len = 0; @@ -921,7 +923,8 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id, rte_smp_wmb(); rte_smp_rmb(); vq->used->idx += i; - vq->last_used_idx += i; + vq->last_avail_idx += i; + vq->last_used_idx += i; vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx), sizeof(vq->used->idx));