static inline void
vq_update_avail_idx(struct virtqueue *vq)
{
- virtio_wmb(vq->hw->weak_barriers);
- vq->vq_split.ring.avail->idx = vq->vq_avail_idx;
+ if (vq->hw->weak_barriers) {
+ /* x86 prefers to using rte_smp_wmb over __atomic_store_n as
+ * it reports a slightly better perf, which comes from the
+ * saved branch by the compiler.
+ * The if and else branches are identical with the smp and
+ * cio barriers both defined as compiler barriers on x86.
+ */
+#ifdef RTE_ARCH_X86_64
+ rte_smp_wmb();
+ vq->vq_split.ring.avail->idx = vq->vq_avail_idx;
+#else
+ __atomic_store_n(&vq->vq_split.ring.avail->idx,
+ vq->vq_avail_idx, __ATOMIC_RELEASE);
+#endif
+ } else {
+ rte_cio_wmb();
+ vq->vq_split.ring.avail->idx = vq->vq_avail_idx;
+ }
}
static inline void
struct buf_vector buf_vec[BUF_VECTOR_MAX];
uint16_t avail_head;
- avail_head = *((volatile uint16_t *)&vq->avail->idx);
-
/*
* The ordering between avail index and
* desc reads needs to be enforced.
*/
- rte_smp_rmb();
+ avail_head = __atomic_load_n(&vq->avail->idx, __ATOMIC_ACQUIRE);
rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]);
}
}
- free_entries = *((volatile uint16_t *)&vq->avail->idx) -
- vq->last_avail_idx;
- if (free_entries == 0)
- return 0;
-
/*
* The ordering between avail index and
* desc reads needs to be enforced.
*/
- rte_smp_rmb();
+ free_entries = __atomic_load_n(&vq->avail->idx, __ATOMIC_ACQUIRE) -
+ vq->last_avail_idx;
+ if (free_entries == 0)
+ return 0;
rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]);