From 46b0fb5f0c6db667b089d1e3fe416df489dc52de Mon Sep 17 00:00:00 2001 From: Nisha Menon Date: Wed, 6 May 2020 16:05:25 -0700 Subject: [PATCH] qcacld-3.0: Add node to sysfs to print wlan mem usage The wlan_mem_stats node will print the DMA, SKB and heap memory allocated in the wlan host driver. This is applicable to perf and defconfig builds. File path to new node is: /sys/kernel/wifi/wlan/wlan_mem_stats Change-Id: Ic05423d362de1ef07a3ecbdd6408a7226e2a3c2f CRs-Fixed: 2680360 --- Kbuild | 4 ++ configs/default_defconfig | 1 + core/hdd/src/wlan_hdd_sysfs.c | 3 + core/hdd/src/wlan_hdd_sysfs_mem_stats.c | 89 +++++++++++++++++++++++++ core/hdd/src/wlan_hdd_sysfs_mem_stats.h | 62 +++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 core/hdd/src/wlan_hdd_sysfs_mem_stats.c create mode 100644 core/hdd/src/wlan_hdd_sysfs_mem_stats.h diff --git a/Kbuild b/Kbuild index 53e9c47541..3aa4d47be8 100644 --- a/Kbuild +++ b/Kbuild @@ -279,6 +279,9 @@ endif ifeq ($(CONFIG_FEATURE_UNIT_TEST_SUSPEND), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_suspend_resume.o endif +ifeq ($(CONFIG_WLAN_SYSFS_MEM_STATS), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_mem_stats.o +endif HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_unit_test.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_modify_acl.o ifeq ($(CONFIG_WLAN_SYSFS_CONNECT_INFO), y) @@ -2613,6 +2616,7 @@ cppflags-$(CONFIG_WLAN_GET_TEMP) += -DCONFIG_WLAN_GET_TEMP cppflags-$(CONFIG_WLAN_THERMAL_CFG) += -DCONFIG_WLAN_THERMAL_CFG cppflags-$(CONFIG_FEATURE_UNIT_TEST_SUSPEND) += -DWLAN_SUSPEND_RESUME_TEST cppflags-$(CONFIG_FEATURE_WLM_STATS) += -DFEATURE_WLM_STATS +cppflags-$(CONFIG_WLAN_SYSFS_MEM_STATS) += -DCONFIG_WLAN_SYSFS_MEM_STATS cppflags-$(CONFIG_WLAN_SYSFS_DCM) += -DWLAN_SYSFS_DCM cppflags-$(CONFIG_WLAN_SYSFS_HE_BSS_COLOR) += -DWLAN_SYSFS_HE_BSS_COLOR cppflags-$(CONFIG_WLAN_SYSFS_GET_STA_INFO) += -DWLAN_SYSFS_GET_STA_INFO diff --git a/configs/default_defconfig b/configs/default_defconfig index f520dbc6fa..1e8f2dbe34 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -178,6 +178,7 @@ ifeq ($(CONFIG_WLAN_SYSFS), y) CONFIG_WLAN_SYSFS_GET_STA_INFO := y CONFIG_WLAN_SYSFS_GET_CHANNEL := y CONFIG_WLAN_SET_FW_MODE_CFG := y + CONFIG_WLAN_SYSFS_MEM_STATS := y CONFIG_WLAN_REASSOC := y CONFIG_WLAN_SYSFS_CONNECT_INFO := y CONFIG_WLAN_SCAN_DISABLE := y diff --git a/core/hdd/src/wlan_hdd_sysfs.c b/core/hdd/src/wlan_hdd_sysfs.c index 67376ae08e..88fa3e22f5 100644 --- a/core/hdd/src/wlan_hdd_sysfs.c +++ b/core/hdd/src/wlan_hdd_sysfs.c @@ -41,6 +41,7 @@ #include "wlan_hdd_sysfs_get_channel.h" #include #include +#include #include "wlan_hdd_sysfs_crash_inject.h" #include "wlan_hdd_sysfs_suspend_resume.h" #include "wlan_hdd_sysfs_unit_test.h" @@ -767,6 +768,7 @@ void hdd_create_sysfs_files(struct hdd_context *hdd_ctx) { hdd_sysfs_create_driver_root_obj(); hdd_sysfs_create_version_interface(hdd_ctx->psoc); + hdd_sysfs_mem_stats_create(wlan_kobject); if (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) { hdd_sysfs_create_powerstats_interface(); hdd_sysfs_set_fw_mode_cfg_create(driver_kobject); @@ -799,6 +801,7 @@ void hdd_destroy_sysfs_files(void) hdd_sysfs_set_fw_mode_cfg_destroy(driver_kobject); hdd_sysfs_destroy_powerstats_interface(); } + hdd_sysfs_mem_stats_destroy(wlan_kobject); hdd_sysfs_destroy_version_interface(); hdd_sysfs_destroy_driver_root_obj(); } diff --git a/core/hdd/src/wlan_hdd_sysfs_mem_stats.c b/core/hdd/src/wlan_hdd_sysfs_mem_stats.c new file mode 100644 index 0000000000..87e1771af7 --- /dev/null +++ b/core/hdd/src/wlan_hdd_sysfs_mem_stats.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_hdd_sysfs_mem_stats.c + * + * Implementation to add sysfs node wlan_mem_stats + * + */ + +#include +#include "osif_psoc_sync.h" +#include +#include +#include + +static ssize_t __hdd_wlan_mem_stats_show(char *buf) +{ + return scnprintf(buf, PAGE_SIZE, + "DMA = %u | Kmalloc = %u | SKB = %u\n", + qdf_dma_mem_stats_read(), + qdf_heap_mem_stats_read(), + qdf_skb_mem_stats_read()); +} + +static ssize_t hdd_wlan_mem_stats_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + struct osif_psoc_sync *psoc_sync; + ssize_t length; + int errno; + + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + + errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); + if (errno) + return errno; + + length = __hdd_wlan_mem_stats_show(buf); + + osif_psoc_sync_op_stop(psoc_sync); + + return length; +} + +static struct kobj_attribute mem_stats_attribute = + __ATTR(wlan_mem_stats, 0440, hdd_wlan_mem_stats_show, NULL); + +int hdd_sysfs_mem_stats_create(struct kobject *wlan_kobject) +{ + int error; + + if (!wlan_kobject) { + hdd_err("Could not get wlan kobject!"); + return -EINVAL; + } + error = sysfs_create_file(wlan_kobject, &mem_stats_attribute.attr); + if (error) + hdd_err("Failed to create sysfs file wlan_mem_stats"); + + return error; +} + +void hdd_sysfs_mem_stats_destroy(struct kobject *wlan_kobject) +{ + if (!wlan_kobject) + hdd_err("Could not get wlan kobject!"); + sysfs_remove_file(wlan_kobject, &mem_stats_attribute.attr); +} + diff --git a/core/hdd/src/wlan_hdd_sysfs_mem_stats.h b/core/hdd/src/wlan_hdd_sysfs_mem_stats.h new file mode 100644 index 0000000000..46127543ab --- /dev/null +++ b/core/hdd/src/wlan_hdd_sysfs_mem_stats.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_hdd_sysfs_mem_stats.h + * + * Implementation to add sysfs node wlan_mem_stats + */ + +#ifndef _WLAN_HDD_SYSFS_MEM_STATS +#define _WLAN_HDD_SYSFS_MEM_STATS + +#if defined(WLAN_SYSFS) && defined(CONFIG_WLAN_SYSFS_MEM_STATS) +/** + * hdd_sysfs_mem_stats_create() - Function to create + * wlan_mem_stats sysfs node to capture host driver memory usage + * @wlan_kobject: sysfs wlan kobject + * + * file path: /sys/kernel/wifi/wlan/wlan_mem_stats + * + * usage: cat /sys/kernel/wifi/wlan/wlan_mem_stats + * + * Return: 0 on success and errno on failure + */ +int hdd_sysfs_mem_stats_create(struct kobject *wlan_kobject); + +/** + * hdd_sysfs_mem_stats_destroy() - API to destroy + * wlan_mem_stats + * + * Return: none + */ +void hdd_sysfs_mem_stats_destroy(struct kobject *wlan_kobject); +#else +static inline int +hdd_sysfs_mem_stats_create(struct kobject *wlan_kobject) +{ + return 0; +} + +static inline void +hdd_sysfs_mem_stats_destroy(struct kobject *wlan_kobject) +{ +} +#endif /* WLAN_SYSFS && CONFIG_WLAN_SYSFS_MEM_STATS */ +#endif /* _WLAN_HDD_SYSFS_MEM_STATS */ +