forked from Minki/linux
be2net: Fix invocation of be_close() after be_clear()
In the EEH error recovery path, when a permanent failure occurs, we clean up adapter structure (i.e. destroy queues etc) by calling be_clear() and return PCI_ERS_RESULT_DISCONNECT. After this the stack tries to remove device from bus and calls be_remove() which invokes netdev_unregister()->be_close(). be_close() operating on destroyed queues results in a NULL dereference. This patch fixes this problem by introducing a flag to keep track of the setup state. Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com> Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1a3d0717f6
commit
e1ad8e33d2
@ -374,6 +374,7 @@ enum vf_state {
|
||||
#define BE_FLAGS_NAPI_ENABLED (1 << 9)
|
||||
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)
|
||||
#define BE_FLAGS_VXLAN_OFFLOADS (1 << 12)
|
||||
#define BE_FLAGS_SETUP_DONE (1 << 13)
|
||||
|
||||
#define BE_UC_PMAC_COUNT 30
|
||||
#define BE_VF_UC_PMAC_COUNT 2
|
||||
|
@ -2726,6 +2726,12 @@ static int be_close(struct net_device *netdev)
|
||||
struct be_eq_obj *eqo;
|
||||
int i;
|
||||
|
||||
/* This protection is needed as be_close() may be called even when the
|
||||
* adapter is in cleared state (after eeh perm failure)
|
||||
*/
|
||||
if (!(adapter->flags & BE_FLAGS_SETUP_DONE))
|
||||
return 0;
|
||||
|
||||
be_roce_dev_close(adapter);
|
||||
|
||||
if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
|
||||
@ -3056,6 +3062,7 @@ static int be_clear(struct be_adapter *adapter)
|
||||
be_clear_queues(adapter);
|
||||
|
||||
be_msix_disable(adapter);
|
||||
adapter->flags &= ~BE_FLAGS_SETUP_DONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3560,6 +3567,7 @@ static int be_setup(struct be_adapter *adapter)
|
||||
adapter->phy.fc_autoneg = 1;
|
||||
|
||||
be_schedule_worker(adapter);
|
||||
adapter->flags |= BE_FLAGS_SETUP_DONE;
|
||||
return 0;
|
||||
err:
|
||||
be_clear(adapter);
|
||||
|
Loading…
Reference in New Issue
Block a user