> The receive path checks available data by reading the write index and then
> copies ring data. The link between the two is only the comparison, a control
> dependency, which does not order load against load on a weakly ordered
> architecture: packet data can be read before the host has finished writing it.
> Load the write index with acquire, pairing with the host's release store.
> This is
> the equivalent of virt_rmb() in the Linux hv_pkt_iter code. No change in
> generated code on x86.
>
> Fixes: 831dba47bd36 ("bus/vmbus: add Hyper-V virtual bus support")
> Cc: [email protected]
>
> Signed-off-by: Stephen Hemminger <[email protected]>
Reviewed-by: Long Li <[email protected]>
> ---
> drivers/bus/vmbus/private.h | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/bus/vmbus/private.h b/drivers/bus/vmbus/private.h index
> 6efac86b77..aca5b534f9 100644
> --- a/drivers/bus/vmbus/private.h
> +++ b/drivers/bus/vmbus/private.h
> @@ -12,6 +12,7 @@
> #include <bus_driver.h>
> #include <bus_vmbus_driver.h>
> #include <rte_log.h>
> +#include <rte_stdatomic.h>
> #include <rte_eal_paging.h>
> #include <rte_vmbus_reg.h>
>
> @@ -130,7 +131,16 @@ vmbus_br_availwrite(const struct vmbus_br *br,
> uint32_t windex) static inline uint32_t vmbus_br_availread(const struct
> vmbus_br *br) {
> - return br->dsize - vmbus_br_availwrite(br, br->vbr->windex);
> + uint32_t windex;
> +
> + /* Pairs with the host's release store of the write index;
> + * ring data must not be read before the index.
> + */
> + windex = rte_atomic_load_explicit(
> + (volatile uint32_t __rte_atomic *)&br->vbr->windex,
> + rte_memory_order_acquire);
> +
> + return br->dsize - vmbus_br_availwrite(br, windex);
> }
>
> int vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int
> iovlen,
> --
> 2.53.0