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>
queue = &dev->queues[queue_id];
vr = &queue->vr;
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);
start_idx = queue->last_used_idx;
free_entries = avail_idx - start_idx;
count = RTE_MIN(count, free_entries);
rte_prefetch0(&vr->desc[desc_indexes[i+1]]);
}
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);
queue->last_used_idx += count;
rte_vhost_vring_call(dev->vid, queue_id);
queue = &dev->queues[queue_id];
vr = &queue->vr;
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;
queue->last_avail_idx;
if (free_entries == 0)
return 0;
queue->last_avail_idx += i;
queue->last_used_idx += i;
queue->last_avail_idx += i;
queue->last_used_idx += i;
- rte_smp_wmb();
- rte_smp_rmb();
+ __atomic_add_fetch(&vr->used->idx, i, __ATOMIC_ACQ_REL);
rte_vhost_vring_call(dev->vid, queue_id);
rte_vhost_vring_call(dev->vid, queue_id);