Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1ad8e33 authored by Kalesh AP's avatar Kalesh AP Committed by David S. Miller
Browse files

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: default avatarKalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a3d0717
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+8 −0
Original line number Diff line number Diff line
@@ -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);