From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anssi Hannula Subject: [PATCH 3/3] net: macb: add missing barriers when reading buffers Date: Fri, 30 Nov 2018 20:21:37 +0200 Message-ID: <20181130182137.27974-4-anssi.hannula@bitwise.fi> References: <20181130182137.27974-1-anssi.hannula@bitwise.fi> Cc: netdev@vger.kernel.org To: Nicolas Ferre , "David S. Miller" Return-path: Received: from mail.bitwise.fi ([109.204.228.163]:52832 "EHLO mail.bitwise.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725754AbeLAFcq (ORCPT ); Sat, 1 Dec 2018 00:32:46 -0500 In-Reply-To: <20181130182137.27974-1-anssi.hannula@bitwise.fi> Sender: netdev-owner@vger.kernel.org List-ID: When reading buffer descriptors on RX or on TX completion, an RX_USED/TX_USED bit is checked first to ensure that the descriptor has been populated. However, there are no memory barriers to ensure that the data protected by the RX_USED/TX_USED bit is up-to-date with respect to that bit. Fix that by adding DMA read memory barriers on those paths. I did not observe any actual issues caused by these being missing, though. Tested on a ZynqMP based system. Signed-off-by: Anssi Hannula Fixes: 89e5785fc8a6 ("[PATCH] Atmel MACB ethernet driver") Cc: Nicolas Ferre --- drivers/net/ethernet/cadence/macb_main.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 430b7a0f5436..c93baa8621d5 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -861,6 +861,11 @@ static void macb_tx_interrupt(struct macb_queue *queue) /* First, update TX stats if needed */ if (skb) { + /* Ensure all of desc is at least as up-to-date + * as ctrl (TX_USED bit) + */ + dma_rmb(); + if (gem_ptp_do_txstamp(queue, skb, desc) == 0) { /* skb now belongs to timestamp buffer * and will be removed later @@ -1000,12 +1005,16 @@ static int gem_rx(struct macb_queue *queue, int budget) rmb(); rxused = (desc->addr & MACB_BIT(RX_USED)) ? true : false; - addr = macb_get_addr(bp, desc); - ctrl = desc->ctrl; if (!rxused) break; + /* Ensure other data is at least as up-to-date as rxused */ + dma_rmb(); + + addr = macb_get_addr(bp, desc); + ctrl = desc->ctrl; + queue->rx_tail++; count++; @@ -1180,11 +1189,14 @@ static int macb_rx(struct macb_queue *queue, int budget) /* Make hw descriptor updates visible to CPU */ rmb(); - ctrl = desc->ctrl; - if (!(desc->addr & MACB_BIT(RX_USED))) break; + /* Ensure other data is at least as up-to-date as addr */ + dma_rmb(); + + ctrl = desc->ctrl; + if (ctrl & MACB_BIT(RX_SOF)) { if (first_frag != -1) discard_partial_frame(queue, first_frag, tail); -- 2.17.2