[v1,1/8] examples/vhost: relax memory ordering when enqueue/dequeue

Message ID 20201221155033.6771-2-joyce.kong@arm.com (mailing list archive)
State Accepted, archived
Delegated to: Maxime Coquelin
Headers
Series replace smp barriers in vhost with C11 atomic |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Joyce Kong Dec. 21, 2020, 3:50 p.m. UTC
  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

Maxime Coquelin Jan. 7, 2021, 4:33 p.m. UTC | #1
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
  

Patch

diff --git a/examples/vhost/virtio_net.c b/examples/vhost/virtio_net.c
index 8ea6b36d5..64bf3d19f 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);