Pārlūkot izejas kodu

qcacld-3.0: Flush delayed acs work during SSR

There are two issue in the driver during SSR:
1. Currently in driver if SSR happens in SAP mode and during
re-probe if any pending acs delayed work is scheduled, it
results in NULL pointer access at sap_init_dfs_channel_nol_list
api as pdev is not initialized yet.
2. disconnection_status_lock is not getting initialized for
SAP interface and this is getting used inside
hdd_set_disconnect_status api which is getting invoked
for all interfaces at reset all adapters during SSR
shutdown, which results in uninitialized lock access.

To address these issue below measures are taken care:
1. Add SSR protection for pending acs and flush
   pending acs delayed work during SSR shutdown.
2. During SSR shutdown don't invoke hdd_set_disconnect_status
   api for SAP interface.

Change-Id: I5181deffed28ecbc5708f970c9ca7f8ad2241011
CRs-fixed: 2379280
Ashish Kumar Dhanotiya 6 gadi atpakaļ
vecāks
revīzija
dc3900f053
2 mainītis faili ar 23 papildinājumiem un 7 dzēšanām
  1. 6 4
      core/hdd/src/wlan_hdd_cfg80211.c
  2. 17 3
      core/hdd/src/wlan_hdd_main.c

+ 6 - 4
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1787,10 +1787,10 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter)
 		return -EINVAL;
 	}
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	if (!hdd_ctx) {
-		hdd_err("hdd_ctx is NULL");
-		return -EINVAL;
-	}
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
 	sap_config = &adapter->session.ap.sap_config;
 	if (!sap_config) {
 		hdd_err("SAP config is NULL");
@@ -2959,7 +2959,9 @@ static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work)
 	struct hdd_adapter *adapter = container_of(work, struct hdd_adapter,
 						   acs_pending_work.work);
 
+	cds_ssr_protect(__func__);
 	wlan_hdd_cfg80211_start_acs(adapter);
+	cds_ssr_unprotect(__func__);
 	clear_bit(ACS_PENDING, &adapter->event_flags);
 }
 

+ 17 - 3
core/hdd/src/wlan_hdd_main.c

@@ -5800,10 +5800,19 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
 			wlan_hdd_netif_queue_control(adapter,
 						     WLAN_STOP_ALL_NETIF_QUEUE,
 						     WLAN_CONTROL_PATH);
+			if (test_bit(ACS_PENDING, &adapter->event_flags)) {
+				cds_flush_delayed_work(
+						&adapter->acs_pending_work);
+				clear_bit(ACS_PENDING, &adapter->event_flags);
+			}
+
 			if (test_bit(SOFTAP_BSS_STARTED,
-						&adapter->event_flags))
+						&adapter->event_flags)) {
 				hdd_sap_indicate_disconnect_for_sta(adapter);
-			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+				clear_bit(SOFTAP_BSS_STARTED,
+					  &adapter->event_flags);
+			}
+
 		} else {
 			wlan_hdd_netif_queue_control(adapter,
 					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
@@ -5869,7 +5878,12 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
 		hdd_nud_ignore_tracking(adapter, true);
 		hdd_nud_reset_tracking(adapter);
 		hdd_nud_flush_work(adapter);
-		hdd_set_disconnect_status(adapter, false);
+
+		if (adapter->device_mode != QDF_SAP_MODE &&
+		    adapter->device_mode != QDF_P2P_GO_MODE &&
+		    adapter->device_mode != QDF_FTM_MODE)
+			hdd_set_disconnect_status(adapter, false);
+
 		hdd_stop_tsf_sync(adapter);
 
 		hdd_softap_deinit_tx_rx(adapter);