diff options
author | Kalesh AP <kalesh.purayil@emulex.com> | 2014-04-14 06:42:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-14 13:41:37 -0400 |
commit | e1ad8e33d2e57ca64d9862b63d986fc296a7b876 (patch) | |
tree | 37889e4b5e71892beadcd3fcff25da9033d81c3a | |
parent | 1a3d0717f68345730ae939b74b952200fb165f45 (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.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 8 |
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; |
3564 | err: | 3572 | err: |
3565 | be_clear(adapter); | 3573 | be_clear(adapter); |