From eaa33eee78969e868de87d836dfe01652d841d10 Mon Sep 17 00:00:00 2001 From: hqu Date: Thu, 4 May 2017 17:56:35 +0800 Subject: [PATCH] qcacld-3.0: Flush scan_block_work when receive NETDEV_GOING_DOWN notifier qcacld-2.0 to qcacld-3.0 propagation In some case, scan_block_work will be scheduled, but NETDEV_DOWN will come before scan_block_work executed, it will lead to crash. Because in this case it will call ___cfg80211_scan_done to free scan request in cfg80211_netdev_notifier_call firstly, but it will access scan request in wlan_hdd_cfg80211_scan_block_cb afterwards, so it will crash. Add flush scan_block_work process when receive NETDEV_GOING_DOWN notifier. Change-Id: Iada4b907f5fb03871406904340e21b6cdf89306f CRs-Fixed: 2034794 --- core/hdd/src/wlan_hdd_main.c | 3 +++ core/hdd/src/wlan_hdd_scan.c | 12 +----------- core/hdd/src/wlan_hdd_scan.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 4e1cc509a6..25b7746868 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -441,6 +441,7 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID, adapter->sessionId, INVALID_SCAN_ID, true); } else { + cds_flush_work(&adapter->scan_block_work); hdd_debug("Scan is not Pending from user"); } break; @@ -3751,6 +3752,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type, return NULL; } + INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); + cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter); mutex_init(&cfgState->remain_on_chan_ctx_lock); diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 5970ad1f50..13ee8b6f76 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1378,13 +1378,7 @@ static bool wlan_hdd_sap_skip_scan_check(hdd_context_t *hdd_ctx, } #endif -/** - * wlan_hdd_cfg80211_scan_block_cb() - scan block work handler - * @work: Pointer to work - * - * Return: none - */ -static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) +void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) { hdd_adapter_t *adapter = container_of(work, hdd_adapter_t, scan_block_work); @@ -1600,8 +1594,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, pAdapter->request = request; pAdapter->scan_source = source; - INIT_WORK(&pAdapter->scan_block_work, - wlan_hdd_cfg80211_scan_block_cb); schedule_work(&pAdapter->scan_block_work); return 0; } @@ -1675,8 +1667,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, hdd_debug("sap scan skipped"); pAdapter->request = request; pAdapter->scan_source = source; - INIT_WORK(&pAdapter->scan_block_work, - wlan_hdd_cfg80211_scan_block_cb); schedule_work(&pAdapter->scan_block_work); return 0; } diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h index 38f42b0a69..e5b3f6e910 100644 --- a/core/hdd/src/wlan_hdd_scan.h +++ b/core/hdd/src/wlan_hdd_scan.h @@ -109,5 +109,15 @@ int wlan_hdd_vendor_abort_scan( void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev); #endif + +/** + * wlan_hdd_cfg80211_scan_block_cb() - scan block work handler + * @work: Pointer to work + * + * This function is used to do scan block work handler + * + * Return: none + */ +void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work); #endif /* end #if !defined(WLAN_HDD_SCAN_H) */