xdp/xsk.c: missing read memory barrier in xsk_poll()

From: Yewon Choi
Date: Fri Nov 24 2023 - 02:00:19 EST


Hello,

We found some possibility of missing read memory barrier in xsk_poll(),
so we would like to ask to check it.

commit e6762c8b adds two smp_rmb() in xsk_mmap(), which are paired with
smp_wmb() in XDP_UMEM_REG and xsk_init_queue each. The later one is
added in order to prevent reordering between reading of q and reading
of q->ring.
One example in simplied code is:

xsk_mmap():
if (offset == XDP_PGOFF_RX_RING) {
q = READ_ONCE(xs->rx);
}
...
if (!q)
return -EINVAL;

/* Matches the smp_wmb() in xsk_init_queue */
smp_rmb();
...
return remap_vmalloc_range(vma, q->ring, 0);

Also, the similar logic exists in xsk_poll() without smp_rmb().

xsk_poll():
...
if (xs->rx && !xskq_prod_is_empty(xs->rx))
mask |= EPOLLIN | EPOLLRDNORM;
if (xs->tx && xsk_tx_writeable(xs))
mask |= EPOLLOUT | EPOLLWRNORM;

xskq_prod_is_empty():
return READ_ONCE(q->ring->consumer) && ...

To be consistent, I think that smp_rmb() is needed between
xs->rx and !xsq_prod_is_empty() and the same applies for xs->tx.

Could you check this please?
If a patch is needed, we will send them.


Best Regards,
Yewon Choi