qcacmn: Support to disable the memory debug at load time

Disable the mem_debug when qdf argument mem_debug_disabled=1 is passed
through uci command "uci set wireless.qcawifi.mem_debug_disabled=1".

CRs-Fixed: 2572159
Change-Id: I6ab5e1f28ce4c58d46c7467bac3853054f4cf56c
This commit is contained in:
Shwetha G K
2019-11-22 14:51:52 +05:30
committed by nshrivas
부모 44de5a5d45
커밋 21378e0c93
4개의 변경된 파일252개의 추가작업 그리고 84개의 파일을 삭제

파일 보기

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-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
@@ -440,4 +440,61 @@ __qdf_mem_set_dma_pa(qdf_device_t osdev,
{
mem_info->pa = dma_pa;
}
/**
* __qdf_mem_alloc_consistent() - allocates consistent qdf memory
* @osdev: OS device handle
* @dev: Pointer to device handle
* @size: Size to be allocated
* @paddr: Physical address
* @func: Function name of the call site
* @line: line numbe rof the call site
*
* Return: pointer of allocated memory or null if memory alloc fails
*/
void *__qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, qdf_dma_addr_t *paddr,
const char *func, uint32_t line);
/**
* __qdf_mem_malloc() - allocates QDF memory
* @size: Number of bytes of memory to allocate.
*
* @func: Function name of the call site
* @line: line numbe rof the call site
*
* 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(qdf_size_t size, const char *func, uint32_t line);
/**
* __qdf_mem_free() - free QDF memory
* @ptr: Pointer to the starting address of the memory to be freed.
*
* This function will free the memory pointed to by 'ptr'.
* Return: None
*/
void __qdf_mem_free(void *ptr);
/**
* __qdf_mem_free_consistent() - free consistent qdf memory
* @osdev: OS device handle
* @dev: Pointer to device handle
* @size: Size to be allocated
* @vaddr: virtual address
* @paddr: Physical address
* @memctx: Pointer to DMA context
*
* Return: none
*/
void __qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, void *vaddr,
qdf_dma_addr_t paddr, qdf_dma_context_t memctx);
#endif /* __I_QDF_MEM_H */

파일 보기

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-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
@@ -43,6 +43,13 @@
#include <net/cnss_prealloc.h>
#endif
#if defined(MEMORY_DEBUG) || defined(NBUF_MEMORY_DEBUG)
static bool mem_debug_disabled;
qdf_declare_param(mem_debug_disabled, bool);
qdf_export_symbol(mem_debug_disabled);
static bool is_initial_mem_debug_disabled;
#endif
/* Preprocessor Definitions and Constants */
#define QDF_MEM_MAX_MALLOC (4096 * 1024) /* 4 Mega Bytes */
#define QDF_MEM_WARN_THRESHOLD 300 /* ms */
@@ -571,6 +578,9 @@ static const struct file_operations fops_qdf_mem_debugfs = {
static QDF_STATUS qdf_mem_debug_debugfs_init(void)
{
if (is_initial_mem_debug_disabled)
return QDF_STATUS_SUCCESS;
if (!qdf_mem_debugfs_root)
return QDF_STATUS_E_FAILURE;
@@ -893,6 +903,15 @@ static int qdf_mem_malloc_flags(void)
/* External Function implementation */
#ifdef MEMORY_DEBUG
/**
* qdf_mem_debug_config_get() - Get the user configuration of mem_debug_disabled
*
* Return: value of mem_debug_disabled qdf module argument
*/
bool qdf_mem_debug_config_get(void)
{
return mem_debug_disabled;
}
/**
* qdf_mem_debug_init() - initialize qdf memory debug functionality
@@ -903,6 +922,11 @@ static void qdf_mem_debug_init(void)
{
int i;
is_initial_mem_debug_disabled = qdf_mem_debug_config_get();
if (is_initial_mem_debug_disabled)
return;
/* Initalizing the list with maximum size of 60000 */
for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i)
qdf_list_create(&qdf_mem_domains[i], 60000);
@@ -918,6 +942,9 @@ static uint32_t
qdf_mem_domain_check_for_leaks(enum qdf_debug_domain domain,
qdf_list_t *mem_list)
{
if (is_initial_mem_debug_disabled)
return 0;
if (qdf_list_empty(mem_list))
return 0;
@@ -933,6 +960,9 @@ static void qdf_mem_domain_set_check_for_leaks(qdf_list_t *domains)
uint32_t leak_count = 0;
int i;
if (is_initial_mem_debug_disabled)
return;
/* detect and print leaks */
for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i)
leak_count += qdf_mem_domain_check_for_leaks(i, domains + i);
@@ -951,6 +981,9 @@ static void qdf_mem_debug_exit(void)
{
int i;
if (is_initial_mem_debug_disabled)
return;
/* mem */
qdf_mem_domain_set_check_for_leaks(qdf_mem_domains);
for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i)
@@ -975,6 +1008,9 @@ void *qdf_mem_malloc_debug(size_t size, const char *func, uint32_t line,
void *ptr;
unsigned long start, duration;
if (is_initial_mem_debug_disabled)
return __qdf_mem_malloc(size, func, line);
if (!size || size > QDF_MEM_MAX_MALLOC) {
qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line);
return NULL;
@@ -1022,6 +1058,11 @@ void qdf_mem_free_debug(void *ptr, const char *func, uint32_t line)
struct qdf_mem_header *header;
enum qdf_mem_validation_bitmap error_bitmap;
if (is_initial_mem_debug_disabled) {
__qdf_mem_free(ptr);
return;
}
/* freeing a null pointer is valid */
if (qdf_unlikely(!ptr))
return;
@@ -1062,6 +1103,9 @@ void qdf_mem_check_for_leaks(void)
qdf_list_t *dma_list = qdf_mem_dma_list(current_domain);
uint32_t leaks_count = 0;
if (is_initial_mem_debug_disabled)
return;
leaks_count += qdf_mem_domain_check_for_leaks(current_domain, mem_list);
leaks_count += qdf_mem_domain_check_for_leaks(current_domain, dma_list);
@@ -1232,33 +1276,6 @@ static void qdf_mem_debug_init(void) {}
static void qdf_mem_debug_exit(void) {}
void *qdf_mem_malloc_fl(size_t size, const char *func, uint32_t line)
{
void *ptr;
if (!size || size > QDF_MEM_MAX_MALLOC) {
qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func,
line);
return NULL;
}
ptr = qdf_mem_prealloc_get(size);
if (ptr)
return ptr;
ptr = kzalloc(size, qdf_mem_malloc_flags());
if (!ptr) {
qdf_nofl_err("Failed to malloc %zuB @ %s:%d",
size, func, line);
return NULL;
}
qdf_mem_kmalloc_inc(ksize(ptr));
return ptr;
}
qdf_export_symbol(qdf_mem_malloc_fl);
void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line)
{
void *ptr;
@@ -1280,29 +1297,6 @@ void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line)
}
qdf_export_symbol(qdf_mem_malloc_atomic_fl);
/**
* qdf_mem_free() - free QDF memory
* @ptr: Pointer to the starting address of the memory to be free'd.
*
* This function will free the memory pointed to by 'ptr'.
*
* Return: None
*/
void qdf_mem_free(void *ptr)
{
if (!ptr)
return;
if (qdf_mem_prealloc_put(ptr))
return;
qdf_mem_kmalloc_dec(ksize(ptr));
kfree(ptr);
}
qdf_export_symbol(qdf_mem_free);
/**
* qdf_mem_multi_pages_alloc() - allocate large size of kernel memory
* @osdev: OS device handle pointer
@@ -1444,6 +1438,46 @@ void qdf_mem_multi_pages_free(qdf_device_t osdev,
qdf_export_symbol(qdf_mem_multi_pages_free);
#endif
void __qdf_mem_free(void *ptr)
{
if (!ptr)
return;
if (qdf_mem_prealloc_put(ptr))
return;
qdf_mem_kmalloc_dec(ksize(ptr));
kfree(ptr);
}
qdf_export_symbol(__qdf_mem_free);
void *__qdf_mem_malloc(size_t size, const char *func, uint32_t line)
{
void *ptr;
if (!size || size > QDF_MEM_MAX_MALLOC) {
qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func,
line);
return NULL;
}
ptr = qdf_mem_prealloc_get(size);
if (ptr)
return ptr;
ptr = kzalloc(size, qdf_mem_malloc_flags());
if (!ptr)
return NULL;
qdf_mem_kmalloc_inc(ksize(ptr));
return ptr;
}
qdf_export_symbol(__qdf_mem_malloc);
void *qdf_aligned_malloc_fl(uint32_t *size,
void **vaddr_unaligned,
qdf_dma_addr_t *paddr_unaligned,
@@ -1797,6 +1831,11 @@ void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev,
struct qdf_mem_header *header;
void *vaddr;
if (is_initial_mem_debug_disabled)
return __qdf_mem_alloc_consistent(osdev, dev,
size, paddr,
func, line);
if (!size || size > QDF_MEM_MAX_MALLOC) {
qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line);
return NULL;
@@ -1840,6 +1879,14 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev,
struct qdf_mem_header *header;
enum qdf_mem_validation_bitmap error_bitmap;
if (is_initial_mem_debug_disabled) {
__qdf_mem_free_consistent(
osdev, dev,
size, vaddr,
paddr, memctx);
return;
}
/* freeing a null pointer is valid */
if (qdf_unlikely(!vaddr))
return;
@@ -1867,31 +1914,39 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev,
qdf_mem_dma_free(dev, size + QDF_DMA_MEM_DEBUG_SIZE, vaddr, paddr);
}
qdf_export_symbol(qdf_mem_free_consistent_debug);
#endif /* MEMORY_DEBUG */
#else
void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, qdf_dma_addr_t *paddr)
void __qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, void *vaddr,
qdf_dma_addr_t paddr, qdf_dma_context_t memctx)
{
void *vaddr = qdf_mem_dma_alloc(osdev, dev, size, paddr);
qdf_mem_dma_dec(size);
qdf_mem_dma_free(dev, size, vaddr, paddr);
}
qdf_export_symbol(__qdf_mem_free_consistent);
void *__qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, qdf_dma_addr_t *paddr,
const char *func, uint32_t line)
{
void *vaddr;
if (!size || size > QDF_MEM_MAX_MALLOC) {
qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d",
size, func, line);
return NULL;
}
vaddr = qdf_mem_dma_alloc(osdev, dev, size, paddr);
if (vaddr)
qdf_mem_dma_inc(size);
return vaddr;
}
qdf_export_symbol(qdf_mem_alloc_consistent);
void qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
qdf_size_t size, void *vaddr,
qdf_dma_addr_t paddr, qdf_dma_context_t memctx)
{
qdf_mem_dma_dec(size);
qdf_mem_dma_free(dev, size, vaddr, paddr);
}
qdf_export_symbol(qdf_mem_free_consistent);
#endif /* MEMORY_DEBUG */
qdf_export_symbol(__qdf_mem_alloc_consistent);
void *qdf_aligned_mem_alloc_consistent_fl(
qdf_device_t osdev, uint32_t *size,

파일 보기

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-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
@@ -113,6 +113,10 @@ static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX];
static qdf_atomic_t nbuf_count;
#endif
#if defined(NBUF_MEMORY_DEBUG)
static bool is_initial_mem_debug_disabled;
#endif
/**
* qdf_nbuf_tx_desc_count_display() - Displays the packet counter
*
@@ -616,6 +620,9 @@ qdf_nbuf_track_map(qdf_nbuf_t nbuf, const char *func, uint32_t line)
{
QDF_STATUS status;
if (is_initial_mem_debug_disabled)
return QDF_STATUS_SUCCESS;
status = qdf_tracker_track(&qdf_nbuf_map_tracker, nbuf, func, line);
if (QDF_IS_STATUS_ERROR(status))
return status;
@@ -628,6 +635,9 @@ qdf_nbuf_track_map(qdf_nbuf_t nbuf, const char *func, uint32_t line)
static void
qdf_nbuf_untrack_map(qdf_nbuf_t nbuf, const char *func, uint32_t line)
{
if (is_initial_mem_debug_disabled)
return;
qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_UNMAP);
qdf_tracker_untrack(&qdf_nbuf_map_tracker, nbuf, func, line);
}
@@ -2325,6 +2335,11 @@ void qdf_net_buf_debug_init(void)
{
uint32_t i;
is_initial_mem_debug_disabled = qdf_mem_debug_config_get();
if (is_initial_mem_debug_disabled)
return;
qdf_atomic_set(&qdf_nbuf_history_index, -1);
qdf_nbuf_map_tracking_init();
@@ -2354,6 +2369,9 @@ void qdf_net_buf_debug_exit(void)
QDF_NBUF_TRACK *p_node;
QDF_NBUF_TRACK *p_prev;
if (is_initial_mem_debug_disabled)
return;
for (i = 0; i < QDF_NET_BUF_TRACK_MAX_SIZE; i++) {
spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag);
p_node = gp_qdf_net_buf_track_tbl[i];
@@ -2433,6 +2451,9 @@ void qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf, size_t size,
QDF_NBUF_TRACK *p_node;
QDF_NBUF_TRACK *new_node;
if (is_initial_mem_debug_disabled)
return;
new_node = qdf_nbuf_track_alloc();
i = qdf_net_buf_debug_hash(net_buf);
@@ -2473,6 +2494,9 @@ void qdf_net_buf_debug_update_node(qdf_nbuf_t net_buf, const char *func_name,
unsigned long irq_flag;
QDF_NBUF_TRACK *p_node;
if (is_initial_mem_debug_disabled)
return;
i = qdf_net_buf_debug_hash(net_buf);
spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag);
@@ -2502,6 +2526,9 @@ void qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf)
unsigned long irq_flag;
QDF_NBUF_TRACK *p_prev;
if (is_initial_mem_debug_disabled)
return;
i = qdf_net_buf_debug_hash(net_buf);
spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag);
@@ -2547,6 +2574,9 @@ void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf,
{
qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf);
if (is_initial_mem_debug_disabled)
return;
while (ext_list) {
/*
* Take care to add if it is Jumbo packet connected using
@@ -2576,6 +2606,9 @@ void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf)
{
qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf);
if (is_initial_mem_debug_disabled)
return;
while (ext_list) {
/*
* Take care to free if it is Jumbo packet connected using
@@ -2607,6 +2640,11 @@ qdf_nbuf_t qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size,
{
qdf_nbuf_t nbuf;
if (is_initial_mem_debug_disabled)
return __qdf_nbuf_alloc(osdev, size,
reserve, align,
prio, func, line);
nbuf = __qdf_nbuf_alloc(osdev, size, reserve, align, prio, func, line);
/* Store SKB in internal QDF tracking table */
@@ -2628,6 +2666,9 @@ void qdf_nbuf_free_debug(qdf_nbuf_t nbuf, const char *func, uint32_t line)
if (qdf_unlikely(!nbuf))
return;
if (is_initial_mem_debug_disabled)
goto free_buf;
if (qdf_nbuf_get_users(nbuf) > 1)
goto free_buf;
@@ -2656,6 +2697,9 @@ qdf_nbuf_t qdf_nbuf_clone_debug(qdf_nbuf_t buf, const char *func, uint32_t line)
{
qdf_nbuf_t cloned_buf = __qdf_nbuf_clone(buf);
if (is_initial_mem_debug_disabled)
return cloned_buf;
if (qdf_unlikely(!cloned_buf))
return NULL;
@@ -2671,6 +2715,9 @@ qdf_nbuf_t qdf_nbuf_copy_debug(qdf_nbuf_t buf, const char *func, uint32_t line)
{
qdf_nbuf_t copied_buf = __qdf_nbuf_copy(buf);
if (is_initial_mem_debug_disabled)
return copied_buf;
if (qdf_unlikely(!copied_buf))
return NULL;
@@ -2691,6 +2738,9 @@ qdf_nbuf_copy_expand_debug(qdf_nbuf_t buf, int headroom, int tailroom,
if (qdf_unlikely(!copied_buf))
return NULL;
if (is_initial_mem_debug_disabled)
return copied_buf;
/* Store SKB in internal QDF tracking table */
qdf_net_buf_debug_add_node(copied_buf, 0, func, line);
qdf_nbuf_history_add(copied_buf, func, line,