diff options
| author | Mahesh Kumar Kalikot Veetil <mkalikot@codeaurora.org> | 2016-11-02 12:46:40 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-01-06 20:50:09 -0800 |
| commit | 30a464d795dccdd7a6edca3fec52ca10e083aea2 (patch) | |
| tree | e0f29115c96f961d2c54a8a3cb8ff2a227bad286 | |
| parent | 9fc2e07576b62f10961c0ecd59d2665d5088be26 (diff) | |
qcacld-3.0: Fix a memory leak in wlan_init_sysfs()
Free the memory allocated for the global variable wlan_loader. Also
properly unlink the kobject from the parent and free the memory
resources in cleanup path. Cleanup the function wlan_boot_cb().
Change-Id: I16e558c894980cbad531231ecda6fb093cf162e5
CRs-Fixed: 1085823
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index a305be9eb11d..ff46d574d0ec 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -9350,50 +9350,73 @@ static void __hdd_module_exit(void) * Return: 'count' on success or a negative error code in case of failure */ static ssize_t wlan_boot_cb(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, - size_t count) + struct kobj_attribute *attr, + const char *buf, + size_t count) { - int ret = 0; - if (wlan_loader->loaded_state) { - pr_info("Wlan driver already initialized"); - return 0; + pr_err("%s: wlan driver already initialized\n", __func__); + return -EALREADY; } - - pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME, - QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR); - if (__hdd_module_init()) { - pr_err("%s: Failed to register handler\n", __func__); - ret = -EINVAL; - } else - wlan_loader->loaded_state = MODULE_INITIALIZED; + pr_err("%s: wlan driver initialization failed\n", __func__); + return -EIO; + } + + wlan_loader->loaded_state = MODULE_INITIALIZED; return count; } /** + * hdd_sysfs_cleanup() - cleanup sysfs + * + * Return: None + * + */ +static void hdd_sysfs_cleanup(void) +{ + + /* remove from group */ + if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) + sysfs_remove_group(wlan_loader->boot_wlan_obj, + wlan_loader->attr_group); + + /* unlink the object from parent */ + kobject_del(wlan_loader->boot_wlan_obj); + + /* free the object */ + kobject_put(wlan_loader->boot_wlan_obj); + + kfree(wlan_loader->attr_group); + kfree(wlan_loader); + + wlan_loader = NULL; +} + +/** * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is * ready * * This is creates the syfs entry boot_wlan. Which shall be invoked * when the filesystem is ready. * + * QDF API cannot be used here since this function is called even before + * initializing WLAN driver. + * * Return: 0 for success, errno on failure */ static int wlan_init_sysfs(void) { - int ret = -EINVAL; + int ret = -ENOMEM; wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); if (!wlan_loader) { pr_err("%s: memory alloc failed\n", __func__); - ret = -ENOMEM; - return ret; + return -ENOMEM; } wlan_loader->boot_wlan_obj = NULL; @@ -9401,7 +9424,6 @@ static int wlan_init_sysfs(void) GFP_KERNEL); if (!wlan_loader->attr_group) { pr_err("%s: malloc attr_group failed\n", __func__); - ret = -ENOMEM; goto error_return; } @@ -9412,7 +9434,6 @@ static int wlan_init_sysfs(void) kernel_kobj); if (!wlan_loader->boot_wlan_obj) { pr_err("%s: sysfs create and add failed\n", __func__); - ret = -ENOMEM; goto error_return; } @@ -9426,11 +9447,7 @@ static int wlan_init_sysfs(void) return 0; error_return: - - if (wlan_loader->boot_wlan_obj) { - kobject_del(wlan_loader->boot_wlan_obj); - wlan_loader->boot_wlan_obj = NULL; - } + hdd_sysfs_cleanup(); return ret; } @@ -9442,23 +9459,16 @@ error_return: */ static int wlan_deinit_sysfs(void) { - if (!wlan_loader) { hdd_alert("wlan loader context is Null!"); return -EINVAL; } - if (wlan_loader->boot_wlan_obj) { - sysfs_remove_group(wlan_loader->boot_wlan_obj, - wlan_loader->attr_group); - kobject_del(wlan_loader->boot_wlan_obj); - wlan_loader->boot_wlan_obj = NULL; - } - + hdd_sysfs_cleanup(); return 0; } -#endif +#endif /* MODULE */ #ifdef MODULE /** |
