From b5a6124fde72cf2d488df4ea6b268b85334e6652 Mon Sep 17 00:00:00 2001 From: Visweswara Tanuku Date: Tue, 26 Mar 2019 12:24:13 +0530 Subject: [PATCH] qcacld-3.0: Avoid timer leak when psoc idle timeout happens in HL In HL when psoc idle timeout is triggered, timer leak is detected and host triggers panic. When driver is loaded, upon device probe tx flow control timer is initialized. When there is no activity on interface psoc idle timeout is triggered and later during hdd_wlan_stop_modules host triggers panic since tx flow control timer still exists. tx flow control timer is deregistered in hdd_stop_adapter function which is not executed during hdd_wlan_stop_modules. Move tx flow control timer registration from hdd_open_adapter to hdd_start_adapter function to avoid timer leak and panic Change-Id: Id3677d09441e23f1e9e36cdf77e956d6871c46ec CRs-Fixed: 2415146 --- core/hdd/src/wlan_hdd_cfg80211.c | 4 +++- core/hdd/src/wlan_hdd_hostapd.c | 4 ++++ core/hdd/src/wlan_hdd_main.c | 21 ++++++++++++++++----- core/hdd/src/wlan_hdd_nan_datapath.c | 1 + 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 4136aee35c75..471658b6d69e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14227,8 +14227,10 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, if (hdd_is_client_mode(adapter->device_mode)) { if (hdd_is_client_mode(new_mode)) { - if (new_mode == QDF_IBSS_MODE) + if (new_mode == QDF_IBSS_MODE) { + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); + } errno = hdd_change_adapter_mode(adapter, new_mode); if (errno) { diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index b3e996da46c0..58a4adcfd773 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1869,6 +1869,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, hdd_softap_tx_resume_cb, hdd_tx_flow_control_is_pause); + hdd_register_hl_netdev_fc_timer( + adapter, + hdd_tx_resume_timer_expired_handler); + /* @@@ need wep logic here to set privacy bit */ qdf_status = hdd_softap_register_bc_sta(adapter, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index ac6f0f589f79..340c29ff0f98 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5229,9 +5229,6 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio hdd_err("Interface %s wow debug_fs init failed", netdev_name(adapter->dev)); - hdd_register_hl_netdev_fc_timer(adapter, - hdd_tx_resume_timer_expired_handler); - hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev), session_type); @@ -5447,6 +5444,8 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, if (QDF_IS_STATUS_ERROR(status)) hdd_err("Cannot flush PMKIDCache"); + hdd_deregister_hl_netdev_fc_timer(adapter); + hdd_deregister_tx_flow_control(adapter); #ifdef WLAN_OPEN_SOURCE @@ -5488,6 +5487,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, case QDF_MONITOR_MODE: wlan_hdd_scan_abort(adapter); + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); hdd_vdev_destroy(adapter); break; @@ -5522,6 +5522,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, if (adapter->device_mode == QDF_P2P_GO_MODE) wlan_hdd_cleanup_remain_on_channel_ctx(adapter); + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); hdd_destroy_acs_timer(adapter); @@ -5623,6 +5624,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), cds_get_context(QDF_MODULE_ID_TXRX), sta_ctx->conn_info.sta_id[0]); + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); hdd_vdev_destroy(adapter); break; @@ -5630,8 +5632,6 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, break; } - hdd_deregister_hl_netdev_fc_timer(adapter); - if (adapter->scan_info.default_scan_ies) { qdf_mem_free(adapter->scan_info.default_scan_ies); adapter->scan_info.default_scan_ies = NULL; @@ -5863,6 +5863,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) hdd_stop_tsf_sync(adapter); hdd_softap_deinit_tx_rx(adapter); + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); /* Destroy vdev which will be recreated during reinit. */ @@ -6616,6 +6617,10 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) hdd_tx_resume_cb, hdd_tx_flow_control_is_pause); + hdd_register_hl_netdev_fc_timer( + adapter, + hdd_tx_resume_timer_expired_handler); + hdd_lpass_notify_start(hdd_ctx, adapter); hdd_nud_ignore_tracking(adapter, false); break; @@ -9623,6 +9628,9 @@ int hdd_start_station_adapter(struct hdd_adapter *adapter) hdd_tx_resume_cb, hdd_tx_flow_control_is_pause); + hdd_register_hl_netdev_fc_timer(adapter, + hdd_tx_resume_timer_expired_handler); + hdd_exit(); return 0; @@ -9693,6 +9701,9 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) hdd_softap_tx_resume_cb, hdd_tx_flow_control_is_pause); + hdd_register_hl_netdev_fc_timer(adapter, + hdd_tx_resume_timer_expired_handler); + hdd_exit(); return 0; } diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c index 2f9950ae72a2..ee76d6a4900b 100644 --- a/core/hdd/src/wlan_hdd_nan_datapath.c +++ b/core/hdd/src/wlan_hdd_nan_datapath.c @@ -90,6 +90,7 @@ static int hdd_close_ndi(struct hdd_adapter *adapter) #ifdef WLAN_OPEN_SOURCE cancel_work_sync(&adapter->ipv4_notifier_work); #endif + hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); #ifdef WLAN_NS_OFFLOAD