> 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

Reply via email to