Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754120AbdFSSjP (ORCPT + 2 others); Mon, 19 Jun 2017 14:39:15 -0400 Received: from wtarreau.pck.nerim.net ([62.212.114.60]:52721 "EHLO 1wt.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751639AbdFSSjM (ORCPT ); Mon, 19 Jun 2017 14:39:12 -0400 From: Willy Tarreau To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, linux@roeck-us.net Cc: Benjamin Poirier , "David S . Miller" , Willy Tarreau Subject: [PATCH 3.10 123/268] bna: Add synchronization for tx ring. Date: Mon, 19 Jun 2017 20:30:22 +0200 Message-Id: <1497897167-14556-124-git-send-email-w@1wt.eu> X-Mailer: git-send-email 2.8.0.rc2.1.gbe9624a In-Reply-To: <1497897167-14556-1-git-send-email-w@1wt.eu> References: <1497897167-14556-1-git-send-email-w@1wt.eu> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: From: Benjamin Poirier commit d667f78514c656a6a8bf0b3d6134a7fe5cd4d317 upstream. We received two reports of BUG_ON in bnad_txcmpl_process() where hw_consumer_index appeared to be ahead of producer_index. Out of order write/read of these variables could explain these reports. bnad_start_xmit(), as a producer of tx descriptors, has a few memory barriers sprinkled around writes to producer_index and the device's doorbell but they're not paired with anything in bnad_txcmpl_process(), a consumer. Since we are synchronizing with a device, we must use mandatory barriers, not smp_*. Also, I didn't see the purpose of the last smp_mb() in bnad_start_xmit(). Signed-off-by: Benjamin Poirier Signed-off-by: David S. Miller Signed-off-by: Willy Tarreau --- drivers/net/ethernet/brocade/bna/bnad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 07f7ef0..d18ee75 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -193,6 +193,7 @@ bnad_txcmpl_process(struct bnad *bnad, struct bna_tcb *tcb) return 0; hw_cons = *(tcb->hw_consumer_index); + rmb(); cons = tcb->consumer_index; q_depth = tcb->q_depth; @@ -2903,13 +2904,12 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) BNA_QE_INDX_INC(prod, q_depth); tcb->producer_index = prod; - smp_mb(); + wmb(); if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) return NETDEV_TX_OK; bna_txq_prod_indx_doorbell(tcb); - smp_mb(); return NETDEV_TX_OK; } -- 2.8.0.rc2.1.gbe9624a