From 111cf3f4971256e0322b298ac4026f59197ea6e3 Mon Sep 17 00:00:00 2001 From: Joyce Kong Date: Mon, 21 Dec 2020 23:50:26 +0800 Subject: [PATCH] examples/vhost: relax memory ordering when enqueue/dequeue 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 Reviewed-by: Ruifeng Wang Reviewed-by: Maxime Coquelin --- examples/vhost/virtio_net.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/vhost/virtio_net.c b/examples/vhost/virtio_net.c index 8ea6b36d59..64bf3d19ff 100644 --- a/examples/vhost/virtio_net.c +++ b/examples/vhost/virtio_net.c @@ -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); -- 2.20.1