Jelajahi Sumber

qcacld-3.0: Protect con mode change with possible race condition

Presently there is a small window where there is a possible race condition
when con mode change happens at the same time as a ssr.

Protect the same by validating the context. Also move the hdd_init
to module_init so that ssr/qdf infrastructure are always present
when the driver is loaded.

Change-Id: Id14ebef7b5bbafaa799752620973ce03ab0bdd8c
CRs-Fixed: 1078405
Arunk Khandavalli 8 tahun lalu
induk
melakukan
2dc0c9658a
2 mengubah file dengan 17 tambahan dan 12 penghapusan
  1. 2 11
      core/hdd/src/wlan_hdd_driver_ops.c
  2. 15 1
      core/hdd/src/wlan_hdd_main.c

+ 2 - 11
core/hdd/src/wlan_hdd_driver_ops.c

@@ -351,15 +351,10 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
 	*/
 	hdd_request_pm_qos(dev, DISABLE_KRAIT_IDLE_PS_VAL);
 
-	if (reinit) {
+	if (reinit)
 		cds_set_recovery_in_progress(true);
-	} else {
-		ret = hdd_init();
-
-		if (ret)
-			goto out;
+	else
 		cds_set_load_in_progress(true);
-	}
 
 	hdd_init_qdf_ctx(dev, bdev, bus_type, (const struct hif_bus_id *)bid);
 
@@ -390,8 +385,6 @@ err_hdd_deinit:
 		cds_set_recovery_in_progress(false);
 	else
 		cds_set_load_in_progress(false);
-	hdd_deinit();
-out:
 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
 	hdd_remove_pm_qos(dev);
 	return ret;
@@ -431,8 +424,6 @@ static void wlan_hdd_remove(struct device *dev)
 		__hdd_wlan_exit();
 	}
 
-	hdd_deinit();
-
 	pr_info("%s: Driver De-initialized\n", WLAN_MODULE_NAME);
 }
 

+ 15 - 1
core/hdd/src/wlan_hdd_main.c

@@ -9050,6 +9050,12 @@ static int __hdd_module_init(void)
 
 	pld_init();
 
+	ret = hdd_init();
+	if (ret) {
+		pr_err("hdd_init failed %x\n", ret);
+		goto err_hdd_init;
+	}
+
 	qdf_wake_lock_create(&wlan_wake_lock, "wlan");
 
 	hdd_set_conparam((uint32_t) con_mode);
@@ -9066,6 +9072,8 @@ static int __hdd_module_init(void)
 	return 0;
 out:
 	qdf_wake_lock_destroy(&wlan_wake_lock);
+	hdd_deinit();
+err_hdd_init:
 	pld_deinit();
 	return ret;
 }
@@ -9108,6 +9116,7 @@ static void __hdd_module_exit(void)
 
 	qdf_wake_lock_destroy(&wlan_wake_lock);
 
+	hdd_deinit();
 	pld_deinit();
 
 	return;
@@ -9425,9 +9434,10 @@ static int hdd_register_req_mode(hdd_context_t *hdd_ctx,
 }
 
 /**
- * con_mode_handler() - Handles module param con_mode change
+ * __con_mode_handler() - Handles module param con_mode change
  * @kmessage: con mode name on which driver to be bring up
  * @kp: The associated kernel parameter
+ * @hdd_ctx: Pointer to the global HDD context
  *
  * This function is invoked when user updates con mode using sys entry,
  * to initialize and bring-up driver in that specific mode.
@@ -9442,6 +9452,10 @@ static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
 	enum tQDF_GLOBAL_CON_MODE curr_mode;
 	enum tQDF_ADAPTER_MODE adapter_mode;
 
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
 	cds_set_load_in_progress(true);
 
 	hdd_info("con_mode handler: %s", kmessage);