From b49aa305d697c27e89f0d91e4d3139591e372dff Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Wed, 17 Jan 2018 20:54:15 +0800 Subject: [PATCH] qcacld-3.0: Fix memleak for pm runtime suspend lock For wlan0/p2p0, connect_rpm_ctx is deinit in hdd_cleanup_adapter. In two cases, memleak will be detected. 1 if stop modules is triggered from __hdd_stop turn on/off wifi, wait iface_change_wait_time 2 if stop modules is triggered from wlan_hdd_startup when booting wifi, stay idle, wait iface_change_wait_time As hdd_cleanup_adapter is only happens when rmmod, so it doesn't satisfy LONU memleak detection. Move connect_rpm_ctx from adapter to hdd_context, and init/deinit following with module start/stop. Change-Id: Iaa1934594d5ffcf3b90dd2ad41bba4eb62f71119 CRs-Fixed: 2169828 --- core/hdd/inc/wlan_hdd_main.h | 3 ++- core/hdd/src/wlan_hdd_cfg80211.c | 8 +++---- core/hdd/src/wlan_hdd_main.c | 39 ++++++++------------------------ core/hdd/src/wlan_hdd_power.c | 6 ++--- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 42d67381866f..781940e9299d 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -948,11 +948,13 @@ struct hdd_chan_change_params { /** * struct hdd_runtime_pm_context - context to prevent/allow runtime pm * @dfs: dfs context to prevent/allow runtime pm + * @connect: connect context to prevent/allow runtime pm * * Runtime PM control for underlying activities */ struct hdd_runtime_pm_context { qdf_runtime_lock_t dfs; + qdf_runtime_lock_t connect; }; /** @@ -1212,7 +1214,6 @@ struct hdd_adapter { * channel needs to be moved from the existing 2.4GHz channel. */ uint8_t pre_cac_chan; - struct hdd_connect_pm_context connect_rpm_ctx; /* * Indicate if HO fails during disconnect so that diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index e61a50b14a32..97550d3d4b39 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -16798,8 +16798,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, hdd_conn_set_connection_state(adapter, eConnectionState_Connecting); - qdf_runtime_pm_prevent_suspend(&adapter->connect_rpm_ctx. - connect); + qdf_runtime_pm_prevent_suspend( + &hdd_ctx->runtime_context.connect); hdd_prevent_suspend_timeout(HDD_WAKELOCK_TIMEOUT_CONNECT, WIFI_POWER_EVENT_WAKELOCK_CONNECT); qdf_status = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter), @@ -16817,8 +16817,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, /* change back to NotAssociated */ hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected); - qdf_runtime_pm_allow_suspend(&adapter->connect_rpm_ctx. - connect); + qdf_runtime_pm_allow_suspend( + &hdd_ctx->runtime_context.connect); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 120fc5bfbdde..d0ae4c159850 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1008,6 +1008,7 @@ static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; qdf_runtime_lock_init(&ctx->dfs); + qdf_runtime_lock_init(&ctx->connect); wlan_scan_runtime_pm_init(hdd_ctx->hdd_pdev); } @@ -1023,28 +1024,14 @@ static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; qdf_runtime_lock_deinit(&ctx->dfs); + qdf_runtime_lock_deinit(&ctx->connect); wlan_scan_runtime_pm_deinit(hdd_ctx->hdd_pdev); } -static void hdd_adapter_runtime_suspend_init(struct hdd_adapter *adapter) -{ - struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx; - - qdf_runtime_lock_init(&ctx->connect); -} - -static void hdd_adapter_runtime_suspend_deinit(struct hdd_adapter *adapter) -{ - struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx; - - qdf_runtime_lock_deinit(&ctx->connect); -} #else /* FEATURE_RUNTIME_PM */ static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {} static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {} -static void hdd_adapter_runtime_suspend_init(struct hdd_adapter *adapter) {} -static void hdd_adapter_runtime_suspend_deinit(struct hdd_adapter *adapter) {} #endif /* FEATURE_RUNTIME_PM */ #define INTF_MACADDR_MASK 0x7 @@ -3455,7 +3442,6 @@ static struct hdd_adapter *hdd_alloc_station_adapter(struct hdd_context *hdd_ctx /* set dev's parent to underlying device */ SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); hdd_wmm_init(adapter); - hdd_adapter_runtime_suspend_init(adapter); spin_lock_init(&adapter->pause_map_lock); adapter->start_time = adapter->last_time = qdf_system_ticks(); } @@ -3953,8 +3939,6 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter hdd_debugfs_exit(adapter); - hdd_adapter_runtime_suspend_deinit(adapter); - /* * The adapter is marked as closed. When hdd_wlan_exit() call returns, * the driver is almost closed and cannot handle either control @@ -4415,7 +4399,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio #endif status = hdd_register_interface(adapter, rtnl_held); if (QDF_STATUS_SUCCESS != status) - goto err_deinit_adapter_runtime_pm; + goto err_free_netdev; /* Stop the Interface TX queue. */ hdd_debug("Disabling queues"); @@ -4427,7 +4411,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio if (QDF_NDI_MODE == session_type) { status = hdd_init_nan_data_mode(adapter); if (QDF_STATUS_SUCCESS != status) - goto err_deinit_adapter_runtime_pm; + goto err_free_netdev; } break; @@ -4486,7 +4470,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio adapter->device_mode = session_type; status = hdd_register_interface(adapter, rtnl_held); if (QDF_STATUS_SUCCESS != status) - goto err_deinit_adapter_runtime_pm; + goto err_free_netdev; /* Stop the Interface TX queue. */ hdd_debug("Disabling queues"); @@ -4538,12 +4522,6 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio return adapter; -err_deinit_adapter_runtime_pm: - /* - * For certain error cases that hdd_alloc_station_adapter() - * is used to allocate the adapter. - */ - hdd_adapter_runtime_suspend_deinit(adapter); err_free_netdev: wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); free_netdev(adapter->dev); @@ -5543,6 +5521,9 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, { struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev); struct cfg80211_bss *bss = NULL; + struct hdd_context *hdd_ctx; + + hdd_ctx = WLAN_HDD_GET_CTX(padapter); if (WLAN_STATUS_SUCCESS == status) { struct ieee80211_channel *chan; @@ -5571,7 +5552,7 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, status, gfp, connect_timeout, timeout_reason); } - qdf_runtime_pm_allow_suspend(&padapter->connect_rpm_ctx.connect); + qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); } #else @@ -5587,7 +5568,7 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, cfg80211_connect_result(dev, bssid, req_ie, req_ie_len, resp_ie, resp_ie_len, status, gfp); - qdf_runtime_pm_allow_suspend(&padapter->connect_rpm_ctx.connect); + qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT); } #endif diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index e10fb96b39ec..6c9d9bbb82f4 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1871,7 +1871,7 @@ static void hdd_stop_dhcp_ind(struct hdd_adapter *adapter) adapter->mac_addr.bytes, adapter->session_id); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DHCP); - qdf_runtime_pm_allow_suspend(&adapter->connect_rpm_ctx.connect); + qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect); } /** @@ -1888,7 +1888,7 @@ static void hdd_start_dhcp_ind(struct hdd_adapter *adapter) struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); hdd_debug("DHCP start indicated through power save"); - qdf_runtime_pm_prevent_suspend(&adapter->connect_rpm_ctx.connect); + qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.connect); hdd_prevent_suspend_timeout(HDD_WAKELOCK_TIMEOUT_CONNECT, WIFI_POWER_EVENT_WAKELOCK_DHCP); sme_dhcp_start_ind(hdd_ctx->hHal, adapter->device_mode,