diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index b791636f50..8f6d757995 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -831,7 +831,7 @@ static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req, skb = cfg80211_vendor_event_alloc(req->wdev->wiphy, req->wdev, SCAN_DONE_EVENT_BUF_SIZE + 4 + NLMSG_HDRLEN, QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX, - GFP_KERNEL); + GFP_ATOMIC); if (!skb) { cfg80211_err("skb alloc failed"); @@ -877,7 +877,7 @@ static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req, if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) goto nla_put_failure; - cfg80211_vendor_event(skb, GFP_KERNEL); + cfg80211_vendor_event(skb, GFP_ATOMIC); qdf_mem_free(req); return; @@ -1737,7 +1737,7 @@ wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy, data.boottime_ns = bss->boottime_ns; data.signal = bss->rssi; return cfg80211_inform_bss_frame_data(wiphy, &data, bss->mgmt, - bss->frame_len, GFP_KERNEL); + bss->frame_len, GFP_ATOMIC); } #else struct cfg80211_bss * @@ -1747,7 +1747,7 @@ wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy, { return cfg80211_inform_bss_frame(wiphy, bss->chan, bss->mgmt, bss->frame_len, - bss->rssi, GFP_KERNEL); + bss->rssi, GFP_ATOMIC); } #endif @@ -1781,7 +1781,7 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, wiphy = pdev_ospriv->wiphy; bss_data.frame_len = wlan_get_frame_len(scan_params); - bss_data.mgmt = qdf_mem_malloc(bss_data.frame_len); + bss_data.mgmt = qdf_mem_malloc_atomic(bss_data.frame_len); if (!bss_data.mgmt) { cfg80211_err("mem alloc failed"); return; diff --git a/qdf/inc/qdf_mem.h b/qdf/inc/qdf_mem.h index 87d927dfbc..cbbc1891c9 100644 --- a/qdf/inc/qdf_mem.h +++ b/qdf/inc/qdf_mem.h @@ -93,6 +93,7 @@ void qdf_mem_exit(void); * @file: File name of the call site * @line: Line number of the call site * @caller: Address of the caller function + * @flag: GFP flag * * This function will dynamicallly allocate the specified number of bytes of * memory and add it to the qdf tracking list to check for memory leaks and @@ -101,11 +102,13 @@ void qdf_mem_exit(void); * Return: A valid memory location on success, or NULL on failure */ void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line, - void *caller); + void *caller, uint32_t flag); #define qdf_mem_malloc(size) \ - qdf_mem_malloc_debug(size, __FILE__, __LINE__, QDF_RET_IP) + qdf_mem_malloc_debug(size, __FILE__, __LINE__, QDF_RET_IP, 0) +#define qdf_mem_malloc_atomic(size) \ + qdf_mem_malloc_debug(size, __FILE__, __LINE__, QDF_RET_IP, GFP_ATOMIC) /** * qdf_mem_free_debug() - debug version of qdf_mem_free * @ptr: Pointer to the starting address of the memory to be freed. @@ -196,6 +199,7 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, __FILE__, __LINE__) #else void *qdf_mem_malloc(qdf_size_t size); +void *qdf_mem_malloc_atomic(qdf_size_t size); /** * qdf_mem_free() - free QDF memory diff --git a/qdf/linux/src/qdf_mem.c b/qdf/linux/src/qdf_mem.c index 7b2183f28e..a57c9de3b3 100644 --- a/qdf/linux/src/qdf_mem.c +++ b/qdf/linux/src/qdf_mem.c @@ -1061,7 +1061,7 @@ static void qdf_mem_debug_exit(void) } void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line, - void *caller) + void *caller, uint32_t flag) { QDF_STATUS status; enum qdf_debug_domain current_domain = qdf_debug_domain_get(); @@ -1079,8 +1079,11 @@ void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line, if (ptr) return ptr; + if (!flag) + flag = qdf_mem_malloc_flags(); + start = qdf_mc_timer_get_system_time(); - header = kzalloc(size + QDF_MEM_DEBUG_SIZE, qdf_mem_malloc_flags()); + header = kzalloc(size + QDF_MEM_DEBUG_SIZE, flag); duration = qdf_mc_timer_get_system_time() - start; if (duration > QDF_MEM_WARN_THRESHOLD) @@ -1193,6 +1196,37 @@ void *qdf_mem_malloc(size_t size) } qdf_export_symbol(qdf_mem_malloc); +/** + * qdf_mem_malloc_atomic() - allocation QDF memory atomically + * @size: Number of bytes of memory to allocate. + * + * This function will dynamicallly allocate the specified number of bytes of + * memory. + * + * Return: + * Upon successful allocate, returns a non-NULL pointer to the allocated + * memory. If this function is unable to allocate the amount of memory + * specified (for any reason) it returns NULL. + */ +void *qdf_mem_malloc_atomic(size_t size) +{ + void *ptr; + + ptr = qdf_mem_prealloc_get(size); + if (ptr) + return ptr; + + ptr = kzalloc(size, GFP_ATOMIC); + if (!ptr) + return NULL; + + qdf_mem_kmalloc_inc(ksize(ptr)); + + return ptr; +} + +qdf_export_symbol(qdf_mem_malloc_atomic); + /** * qdf_mem_free() - free QDF memory * @ptr: Pointer to the starting address of the memory to be free'd. diff --git a/umac/scan/core/src/wlan_scan_11d.c b/umac/scan/core/src/wlan_scan_11d.c index 3497be2634..dd1f48cb1c 100644 --- a/umac/scan/core/src/wlan_scan_11d.c +++ b/umac/scan/core/src/wlan_scan_11d.c @@ -236,7 +236,7 @@ QDF_STATUS scm_11d_cc_db_init(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_INVAL; } - cc_db = (struct scan_country_code_db *)qdf_mem_malloc( + cc_db = (struct scan_country_code_db *)qdf_mem_malloc_atomic( sizeof(struct scan_country_code_db) * WLAN_UMAC_MAX_PDEVS); if (!cc_db) { scm_err("alloc country code db error"); diff --git a/umac/scan/core/src/wlan_scan_cache_db.c b/umac/scan/core/src/wlan_scan_cache_db.c index 3c66642167..9e1f4d65f7 100644 --- a/umac/scan/core/src/wlan_scan_cache_db.c +++ b/umac/scan/core/src/wlan_scan_cache_db.c @@ -442,7 +442,8 @@ static void scm_update_alt_wcn_ie(struct scan_cache_entry *from, if (!dst->alt_wcn_ie.ptr) { /* allocate this additional buffer for alternate WCN IE */ - dst->alt_wcn_ie.ptr = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); + dst->alt_wcn_ie.ptr = + qdf_mem_malloc_atomic(WLAN_MAX_IE_LEN + 2); if (!dst->alt_wcn_ie.ptr) { scm_err("failed to allocate memory"); return; @@ -927,7 +928,7 @@ scm_scan_apply_filter_get_entry(struct wlan_objmgr_psoc *psoc, if (!match) return QDF_STATUS_SUCCESS; - scan_node = qdf_mem_malloc(sizeof(*scan_node)); + scan_node = qdf_mem_malloc_atomic(sizeof(*scan_node)); if (!scan_node) return QDF_STATUS_E_NOMEM; @@ -1042,7 +1043,7 @@ qdf_list_t *scm_get_scan_result(struct wlan_objmgr_pdev *pdev, return NULL; } - tmp_list = qdf_mem_malloc(sizeof(*tmp_list)); + tmp_list = qdf_mem_malloc_atomic(sizeof(*tmp_list)); if (!tmp_list) { scm_err("failed tp allocate scan_result"); return NULL; diff --git a/umac/scan/core/src/wlan_scan_main.c b/umac/scan/core/src/wlan_scan_main.c index a4d2d3f960..e8fc4db6af 100644 --- a/umac/scan/core/src/wlan_scan_main.c +++ b/umac/scan/core/src/wlan_scan_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -29,7 +29,7 @@ QDF_STATUS wlan_scan_psoc_created_notification(struct wlan_objmgr_psoc *psoc, struct wlan_scan_obj *scan_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; - scan_obj = qdf_mem_malloc(sizeof(struct wlan_scan_obj)); + scan_obj = qdf_mem_malloc_atomic(sizeof(struct wlan_scan_obj)); if (scan_obj == NULL) { scm_err("Failed to allocate memory"); return QDF_STATUS_E_NOMEM; @@ -78,7 +78,7 @@ QDF_STATUS wlan_scan_vdev_created_notification(struct wlan_objmgr_vdev *vdev, struct scan_vdev_obj *scan_vdev_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; - scan_vdev_obj = qdf_mem_malloc(sizeof(struct scan_vdev_obj)); + scan_vdev_obj = qdf_mem_malloc_atomic(sizeof(struct scan_vdev_obj)); if (scan_vdev_obj == NULL) { scm_err("Failed to allocate memory"); return QDF_STATUS_E_NOMEM; diff --git a/umac/scan/core/src/wlan_scan_manager.c b/umac/scan/core/src/wlan_scan_manager.c index 6537782822..3bbe50564d 100644 --- a/umac/scan/core/src/wlan_scan_manager.c +++ b/umac/scan/core/src/wlan_scan_manager.c @@ -151,7 +151,7 @@ static void scm_scan_post_event(struct wlan_objmgr_vdev *vdev, event->vdev_id, event->type, event->reason, event->chan_freq, event->requester, event->scan_id); - listeners = qdf_mem_malloc(sizeof(*listeners)); + listeners = qdf_mem_malloc_atomic(sizeof(*listeners)); if (!listeners) { scm_warn("couldn't allocate listeners list"); return; diff --git a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h index 47ae06b779..394e4fbc50 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h @@ -596,7 +596,7 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry, struct ie_list *ie_lst; new_entry->raw_frame.ptr = - qdf_mem_malloc(scan_entry->raw_frame.len); + qdf_mem_malloc_atomic(scan_entry->raw_frame.len); if (!new_entry->raw_frame.ptr) return QDF_STATUS_E_NOMEM; @@ -677,7 +677,7 @@ util_scan_copy_cache_entry(struct scan_cache_entry *scan_entry) return NULL; new_entry = - qdf_mem_malloc(sizeof(*scan_entry)); + qdf_mem_malloc_atomic(sizeof(*scan_entry)); if (!new_entry) return NULL; @@ -686,7 +686,7 @@ util_scan_copy_cache_entry(struct scan_cache_entry *scan_entry) if (scan_entry->alt_wcn_ie.ptr) { new_entry->alt_wcn_ie.ptr = - qdf_mem_malloc(scan_entry->alt_wcn_ie.len); + qdf_mem_malloc_atomic(scan_entry->alt_wcn_ie.len); if (!new_entry->alt_wcn_ie.ptr) { qdf_mem_free(new_entry); return NULL; diff --git a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c index 4321f6ed27..5b18317862 100644 --- a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c @@ -266,7 +266,7 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, qdf_nbuf_free(buf); return QDF_STATUS_E_INVAL; } - bcn = qdf_mem_malloc(sizeof(*bcn)); + bcn = qdf_mem_malloc_atomic(sizeof(*bcn)); if (!bcn) { scm_err("Failed to allocate memory for bcn"); @@ -274,7 +274,7 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_NOMEM; } bcn->rx_data = - qdf_mem_malloc(sizeof(*rx_param)); + qdf_mem_malloc_atomic(sizeof(*rx_param)); if (!bcn->rx_data) { scm_err("Failed to allocate memory for rx_data"); qdf_mem_free(bcn); diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index f7cd91e4c8..449ef02a1c 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -1635,14 +1635,15 @@ ucfg_scan_init_chanlist_params(struct scan_start_request *req, * too much time to complete. */ if (pdev && !num_chans && ucfg_scan_get_wide_band_scan(pdev)) { - reg_chan_list = qdf_mem_malloc(NUM_CHANNELS * + reg_chan_list = qdf_mem_malloc_atomic(NUM_CHANNELS * sizeof(struct regulatory_channel)); if (!reg_chan_list) { scm_err("Couldn't allocate reg_chan_list memory"); status = QDF_STATUS_E_NOMEM; goto end; } - scan_freqs = qdf_mem_malloc(sizeof(uint32_t) * max_chans); + scan_freqs = + qdf_mem_malloc_atomic(sizeof(uint32_t) * max_chans); if (!scan_freqs) { scm_err("Couldn't allocate scan_freqs memory"); status = QDF_STATUS_E_NOMEM; @@ -1897,7 +1898,7 @@ ucfg_scan_cancel_pdev_scan(struct wlan_objmgr_pdev *pdev) QDF_STATUS status; struct wlan_objmgr_vdev *vdev; - req = qdf_mem_malloc(sizeof(*req)); + req = qdf_mem_malloc_atomic(sizeof(*req)); if (!req) { scm_err("Failed to allocate memory"); return QDF_STATUS_E_NOMEM; diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 79834820b0..4e129f11de 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -831,21 +831,21 @@ util_scan_unpack_beacon_frame(struct wlan_objmgr_pdev *pdev, uint8_t *frame, qdf_list_t *scan_list; struct scan_cache_node *scan_node; - scan_list = qdf_mem_malloc(sizeof(*scan_list)); + scan_list = qdf_mem_malloc_atomic(sizeof(*scan_list)); if (!scan_list) { scm_err("failed to allocate scan_list"); return NULL; } qdf_list_create(scan_list, MAX_SCAN_CACHE_SIZE); - scan_entry = qdf_mem_malloc(sizeof(*scan_entry)); + scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry)); if (!scan_entry) { scm_err("failed to allocate memory for scan_entry"); qdf_mem_free(scan_list); return NULL; } scan_entry->raw_frame.ptr = - qdf_mem_malloc(frame_len); + qdf_mem_malloc_atomic(frame_len); if (!scan_entry->raw_frame.ptr) { scm_err("failed to allocate memory for frame"); qdf_mem_free(scan_entry); @@ -960,7 +960,7 @@ util_scan_unpack_beacon_frame(struct wlan_objmgr_pdev *pdev, uint8_t *frame, if (qbss_load) scan_entry->qbss_chan_load = qbss_load->qbss_chan_load; - scan_node = qdf_mem_malloc(sizeof(*scan_node)); + scan_node = qdf_mem_malloc_atomic(sizeof(*scan_node)); if (!scan_node) { qdf_mem_free(scan_entry->raw_frame.ptr); qdf_mem_free(scan_entry);