qcacld-3.0: fix might sleep crashed issue from invalid context
Currently host driver processing link layer status event is under protection of spin lock, it disabled preempt. Now function wma_unified_radio_tx_mem_free to free memory in wma tries to get mutex lock, this cause issue about sleeping function called from invalid context. Fix the issue to spin unlock before memory free. BUG: sleeping function called from invalid context at kernel/locking/mutex.c:937 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 256, name: kworker/u16:3 Preemption disabled at: Call trace: ___might_sleep+0x20c/0x210 __might_sleep+0x50/0x88 __mutex_lock_common+0x6c/0xe20 mutex_lock_nested+0x2c/0x38 qdf_mutex_acquire+0xa8/0x2bc [wlan] wma_unified_radio_tx_mem_free+0x34/0xe0 [wlan] sme_radio_tx_mem_free+0x24/0x50 [wlan] wlan_hdd_cfg80211_link_layer_stats_callback+0x6c4/0x750 [wlan] wma_unified_link_iface_stats_event_handler+0x32c/0x364 [wlan] __wmi_control_rx+0x46c/0x560 [wlan] wmi_rx_event_work+0x224/0x390 [wlan] Change-Id: I3d36b755f2221492d65cc0b891c1f35ee0204bbc CRs-Fixed: 3044009
This commit is contained in:

committed by
Madan Koyyalamudi

parent
9d10a6024d
commit
66d0a8d7b9
@@ -1302,8 +1302,12 @@ static void hdd_process_ll_stats(tSirLLStatsResults *results,
|
||||
struct hdd_ll_stats *stats = NULL;
|
||||
size_t stat_size = 0;
|
||||
|
||||
if (!(priv->request_bitmap & results->paramId))
|
||||
qdf_spin_lock(&priv->ll_stats_lock);
|
||||
|
||||
if (!(priv->request_bitmap & results->paramId)) {
|
||||
qdf_spin_unlock(&priv->ll_stats_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (results->paramId & WMI_LINK_STATS_RADIO) {
|
||||
struct wifi_radio_stats *rs_results, *stat_result;
|
||||
@@ -1439,14 +1443,18 @@ static void hdd_process_ll_stats(tSirLLStatsResults *results,
|
||||
|
||||
if (!priv->request_bitmap) {
|
||||
exit:
|
||||
qdf_spin_unlock(&priv->ll_stats_lock);
|
||||
|
||||
/* Thread which invokes this function has allocated memory in
|
||||
* WMA for radio stats, that memory should be freed from the
|
||||
* same thread to avoid any race conditions between two threads
|
||||
*/
|
||||
sme_radio_tx_mem_free();
|
||||
osif_request_complete(request);
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_spin_unlock(&priv->ll_stats_lock);
|
||||
}
|
||||
|
||||
static void hdd_debugfs_process_ll_stats(struct hdd_adapter *adapter,
|
||||
@@ -1544,10 +1552,7 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle,
|
||||
if (results->rspId == DEBUGFS_LLSTATS_REQID) {
|
||||
hdd_debugfs_process_ll_stats(adapter, results, request);
|
||||
} else {
|
||||
qdf_spin_lock(&priv->ll_stats_lock);
|
||||
if (priv->request_bitmap)
|
||||
hdd_process_ll_stats(results, request);
|
||||
qdf_spin_unlock(&priv->ll_stats_lock);
|
||||
hdd_process_ll_stats(results, request);
|
||||
}
|
||||
|
||||
osif_request_put(request);
|
||||
|
Reference in New Issue
Block a user