bnx2x: fix slowpath null crash
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 allocates dma failure. 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. 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>
This commit is contained in:
parent
0c3ce16cb7
commit
442866ff97
|
@ -9332,7 +9332,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 */
|
||||
|
@ -10271,8 +10271,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 allocation failure,
|
||||
* the nic is rebooted again. If open still fails, a 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue