From 2dc0c9658a207f0817c21f8d6d19f7fe2fb3c792 Mon Sep 17 00:00:00 2001 From: Arunk Khandavalli Date: Thu, 20 Oct 2016 12:37:26 +0530 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_driver_ops.c | 13 ++----------- core/hdd/src/wlan_hdd_main.c | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 57b1ce6954..7861b503b4 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/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); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 505746971f..af549d3ad9 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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);