bna: Add synchronization for tx ring.
authorBenjamin Poirier <bpoirier@suse.com>
Mon, 7 Nov 2016 09:57:56 +0000 (17:57 +0800)
committerWilly Tarreau <w@1wt.eu>
Tue, 20 Jun 2017 12:04:14 +0000 (14:04 +0200)
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 <bpoirier@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Willy Tarreau <w@1wt.eu>
drivers/net/ethernet/brocade/bna/bnad.c

index 07f7ef05c3f20b00b3b3f287b412deb1ff747b35..d18ee75bdd543449c6128757229aeca96878bb33 100644 (file)
@@ -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;
 }