]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnx2x: fix slowpath null crash
authorZhu Yanjun <yanjun.zhu@oracle.com>
Sat, 11 Nov 2017 15:42:03 +0000 (10:42 -0500)
committerChuck Anderson <chuck.anderson@oracle.com>
Mon, 11 Dec 2017 04:45:56 +0000 (20:45 -0800)
Backport: upstream 442866ff9743d51957685cecaa722a7fd47b02e2

When "NETDEV WATCHDOG: em4 (bnx2x): transmit queue 2 timed out" occurs,
BNX2X_SP_RTNL_TX_TIMEOUT is set. In the function bnx2x_sp_rtnl_task,
bnx2x_nic_unload and bnx2x_nic_load are executed to shutdown and open
NIC. In the function bnx2x_nic_load, bnx2x_alloc_mem fails to allocate
dma memory. The message "bnx2x: [bnx2x_alloc_mem:8399(em4)]Can't
allocate memory" pops out. The variable slowpath is set to NULL.
When shutdown the NIC, the function bnx2x_nic_unload is called. In
the function bnx2x_nic_unload, the following functions are executed.
bnx2x_chip_cleanup
    bnx2x_set_storm_rx_mode
        bnx2x_set_q_rx_mode
            bnx2x_set_q_rx_mode
                bnx2x_config_rx_mode
                    bnx2x_set_rx_mode_e2
In the function bnx2x_set_rx_mode_e2, the variable slowpath is operated.
Then the crash occurs.
To fix this crash, the variable slowpath is checked. And in the function
bnx2x_sp_rtnl_task, after dma memory allocation fails, another shutdown
and open NIC is executed.

Orabug: 27041078

[Correct the typos in the short log and comments]

CC: Joe Jin <joe.jin@oracle.com>
CC: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Acked-by: Ariel Elior <aelior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Reviewed-by: Ethan Zhao <ethan.zhao@oracle.com>
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

index a401e3dbe711950f97d5a60625218611dd6241a5..c51e5970e6d5a09d2e2a13e6dd7dc4fde690186f 100644 (file)
@@ -9333,7 +9333,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link)
        /* Schedule the rx_mode command */
        if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state))
                set_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state);
-       else
+       else if (bp->slowpath)
                bnx2x_set_storm_rx_mode(bp);
 
        /* Cleanup multicast configuration */
@@ -10224,8 +10224,15 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
                smp_mb();
 
                bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
-               bnx2x_nic_load(bp, LOAD_NORMAL);
-
+               /* When ret value shows failure of dma memory allocation,
+                * the nic is rebooted again. If open still fails, an error
+                * message to notify the user.
+                */
+               if (bnx2x_nic_load(bp, LOAD_NORMAL) == -ENOMEM) {
+                       bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
+                       if (bnx2x_nic_load(bp, LOAD_NORMAL))
+                               BNX2X_ERR("Open the NIC fails again!\n");
+               }
                rtnl_unlock();
                return;
        }