aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalesh AP <kalesh.purayil@emulex.com>2014-04-14 06:42:41 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-14 13:41:37 -0400
commite1ad8e33d2e57ca64d9862b63d986fc296a7b876 (patch)
tree37889e4b5e71892beadcd3fcff25da9033d81c3a
parent1a3d0717f68345730ae939b74b952200fb165f45 (diff)
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>
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c8
2 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 8ccaa2520dc3..97db5a7179df 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -374,6 +374,7 @@ enum vf_state {
374#define BE_FLAGS_NAPI_ENABLED (1 << 9) 374#define BE_FLAGS_NAPI_ENABLED (1 << 9)
375#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11) 375#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)
376#define BE_FLAGS_VXLAN_OFFLOADS (1 << 12) 376#define BE_FLAGS_VXLAN_OFFLOADS (1 << 12)
377#define BE_FLAGS_SETUP_DONE (1 << 13)
377 378
378#define BE_UC_PMAC_COUNT 30 379#define BE_UC_PMAC_COUNT 30
379#define BE_VF_UC_PMAC_COUNT 2 380#define BE_VF_UC_PMAC_COUNT 2
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 80f754d7cf65..a18645407d21 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2726,6 +2726,12 @@ static int be_close(struct net_device *netdev)
2726 struct be_eq_obj *eqo; 2726 struct be_eq_obj *eqo;
2727 int i; 2727 int i;
2728 2728
2729 /* This protection is needed as be_close() may be called even when the
2730 * adapter is in cleared state (after eeh perm failure)
2731 */
2732 if (!(adapter->flags & BE_FLAGS_SETUP_DONE))
2733 return 0;
2734
2729 be_roce_dev_close(adapter); 2735 be_roce_dev_close(adapter);
2730 2736
2731 if (adapter->flags & BE_FLAGS_NAPI_ENABLED) { 2737 if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
@@ -3056,6 +3062,7 @@ static int be_clear(struct be_adapter *adapter)
3056 be_clear_queues(adapter); 3062 be_clear_queues(adapter);
3057 3063
3058 be_msix_disable(adapter); 3064 be_msix_disable(adapter);
3065 adapter->flags &= ~BE_FLAGS_SETUP_DONE;
3059 return 0; 3066 return 0;
3060} 3067}
3061 3068
@@ -3560,6 +3567,7 @@ static int be_setup(struct be_adapter *adapter)
3560 adapter->phy.fc_autoneg = 1; 3567 adapter->phy.fc_autoneg = 1;
3561 3568
3562 be_schedule_worker(adapter); 3569 be_schedule_worker(adapter);
3570 adapter->flags |= BE_FLAGS_SETUP_DONE;
3563 return 0; 3571 return 0;
3564err: 3572err:
3565 be_clear(adapter); 3573 be_clear(adapter);