diff mbox series

wifi: mac80211: Allow some cleanup even if sdata-not-in-driver

Message ID 20230308232606.2672652-1-greearb@candelatech.com (mailing list archive)
State Rejected
Delegated to: Johannes Berg
Headers show
Series wifi: mac80211: Allow some cleanup even if sdata-not-in-driver | expand

Commit Message

Ben Greear March 8, 2023, 11:26 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

When ax210 firmware crashes and radio cannot recover, sometimes
use-after-free errors are seen due to txqs not being properly cleanedup
(I think).

Logging shows that the sdata-not-in-driver checks are stopping cleanup
actions from happening.

So, instead warn but allow calls to the driver to clean up objects
even if sdata-not-in-driver is true.

This appears to help this problem, but system is still crashing (perhaps
due to not directly related problems), so this patch needs review before
going upstream.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/driver-ops.c |  5 +++--
 net/mac80211/driver-ops.h | 14 +++++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index a94e281bbb8e..6685c89e87f6 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -105,8 +105,9 @@  void drv_remove_interface(struct ieee80211_local *local,
 {
 	might_sleep();
 
-	if (!check_sdata_in_driver(sdata))
-		return;
+	if (!check_sdata_in_driver(sdata)) {
+		pr_err("drv-remove-interface, sdata-not-in-driver, but will continue in hopes it cleans something up.\n");
+	}
 
 	trace_drv_remove_interface(local, sdata);
 	local->ops->remove_interface(&local->hw, &sdata->vif);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index a8924a6de1ee..81b8886db972 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -513,8 +513,9 @@  static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
 	might_sleep();
 
 	sdata = get_bss_sdata(sdata);
-	if (!check_sdata_in_driver(sdata))
-		return;
+	if (!check_sdata_in_driver(sdata)) {
+		pr_err("drv-sta-pre-rcu-remove, sdata-not-in-driver, but will continue in hopes it cleans something up.\n");
+	}
 
 	trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
 	if (local->ops->sta_pre_rcu_remove)
@@ -632,8 +633,9 @@  static inline void drv_flush(struct ieee80211_local *local,
 
 	might_sleep();
 
-	if (sdata && !check_sdata_in_driver(sdata))
-		return;
+	if (sdata && !check_sdata_in_driver(sdata)) {
+		pr_err("drv_flush, sdata-not-in-driver, but will continue in hopes it cleans something up.\n");
+	}
 
 	trace_drv_flush(local, queues[0], drop);
 	/* NOTE:  Only ath10k might want more queues than fits in 32-bits,
@@ -870,8 +872,10 @@  drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
 {
 	might_sleep();
 
-	if (!check_sdata_in_driver(sdata))
+	if (!check_sdata_in_driver(sdata)) {
+		pr_err("drv-unassing-vif-chantx, sdata-not-in-driver, but will continue in hopes it cleans something up.\n");
 		return;
+	}
 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
 
 	trace_drv_mgd_protect_tdls_discover(local, sdata);