]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnxt_en: Implement missing tx timeout reset logic.
authorMichael Chan <mchan@broadcom.com>
Thu, 10 Dec 2015 00:35:44 +0000 (19:35 -0500)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 7 Jul 2016 00:36:37 +0000 (17:36 -0700)
Orabug: 23221795

The reset logic calls bnxt_close_nic() and bnxt_open_nic() under rtnl_lock
from bnxt_sp_task.  BNXT_STATE_IN_SP_TASK must be cleared before calling
bnxt_close_nic() to avoid deadlock.

v2: Fixed white space error.  Thanks Dave.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 028de140ffdf481d4948de663b33dae78e1e9cc8)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index e1874196666b96bb19d29a102d21db796e487e14..07781ab40762d1ad1f0c3fbfbcfc5546cd14014f 100644 (file)
@@ -5048,8 +5048,10 @@ static void bnxt_dbg_dump_states(struct bnxt *bp)
 static void bnxt_reset_task(struct bnxt *bp)
 {
        bnxt_dbg_dump_states(bp);
-       if (netif_running(bp->dev))
-               bnxt_tx_disable(bp); /* prevent tx timout again */
+       if (netif_running(bp->dev)) {
+               bnxt_close_nic(bp, false, false);
+               bnxt_open_nic(bp, false, false);
+       }
 }
 
 static void bnxt_tx_timeout(struct net_device *dev)
@@ -5128,8 +5130,16 @@ static void bnxt_sp_task(struct work_struct *work)
                bnxt_hwrm_tunnel_dst_port_free(
                        bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
        }
-       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
+       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) {
+               /* bnxt_reset_task() calls bnxt_close_nic() which waits
+                * for BNXT_STATE_IN_SP_TASK to clear.
+                */
+               clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+               rtnl_lock();
                bnxt_reset_task(bp);
+               set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+               rtnl_unlock();
+       }
 
        smp_mb__before_atomic();
        clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);