Search Linux Wireless

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Greear <greearb@xxxxxxxxxxxxxxx>

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@xxxxxxxxxxxxxxx>
---
 net/mac80211/driver-ops.c |  5 +++--
 net/mac80211/driver-ops.h | 14 +++++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

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);
-- 
2.39.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux