examples/vhost: relax memory ordering when enqueue/dequeue
authorJoyce Kong <joyce.kong@arm.com>
Mon, 21 Dec 2020 15:50:26 +0000 (23:50 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 8 Jan 2021 17:07:55 +0000 (18:07 +0100)
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>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
examples/vhost/virtio_net.c

index 8ea6b36..64bf3d1 100644 (file)
@@ -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);