[v1,1/8] examples/vhost: relax memory ordering when enqueue/dequeue
Checks
Commit Message
Use C11 atomic APIs with one-way barriers to replace two-way
barriers when operating enqueue/dequeue. Used->idx and avail->idx
are the synchronization points for split vring.
Signed-off-by: Joyce Kong <joyce.kong@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
examples/vhost/virtio_net.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
Comments
On 12/21/20 4:50 PM, Joyce Kong wrote:
> Use C11 atomic APIs with one-way barriers to replace two-way
> barriers when operating enqueue/dequeue. Used->idx and avail->idx
> are the synchronization points for split vring.
>
> Signed-off-by: Joyce Kong <joyce.kong@arm.com>
> Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> ---
> examples/vhost/virtio_net.c | 12 ++++--------
> 1 file changed, 4 insertions(+), 8 deletions(-)
Nice!
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
@@ -191,7 +191,7 @@ vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id,
queue = &dev->queues[queue_id];
vr = &queue->vr;
- avail_idx = *((volatile uint16_t *)&vr->avail->idx);
+ avail_idx = __atomic_load_n(&vr->avail->idx, __ATOMIC_ACQUIRE);
start_idx = queue->last_used_idx;
free_entries = avail_idx - start_idx;
count = RTE_MIN(count, free_entries);
@@ -224,9 +224,7 @@ vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id,
rte_prefetch0(&vr->desc[desc_indexes[i+1]]);
}
- rte_smp_wmb();
-
- *(volatile uint16_t *)&vr->used->idx += count;
+ __atomic_add_fetch(&vr->used->idx, count, __ATOMIC_RELEASE);
queue->last_used_idx += count;
rte_vhost_vring_call(dev->vid, queue_id);
@@ -374,7 +372,7 @@ vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
queue = &dev->queues[queue_id];
vr = &queue->vr;
- free_entries = *((volatile uint16_t *)&vr->avail->idx) -
+ free_entries = __atomic_load_n(&vr->avail->idx, __ATOMIC_ACQUIRE) -
queue->last_avail_idx;
if (free_entries == 0)
return 0;
@@ -429,10 +427,8 @@ vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
queue->last_avail_idx += i;
queue->last_used_idx += i;
- rte_smp_wmb();
- rte_smp_rmb();
- vr->used->idx += i;
+ __atomic_add_fetch(&vr->used->idx, i, __ATOMIC_ACQ_REL);
rte_vhost_vring_call(dev->vid, queue_id);