diff --git a/qdf/inc/qdf_mem.h b/qdf/inc/qdf_mem.h index c0cbfeb60c..d0545cc178 100644 --- a/qdf/inc/qdf_mem.h +++ b/qdf/inc/qdf_mem.h @@ -101,6 +101,7 @@ void qdf_mem_exit(void); * @size: Number of bytes of memory to allocate. * @file: File name of the call site * @line: Line number of the call site + * @caller: Address of the caller function * * 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 @@ -108,10 +109,11 @@ 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 *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line, + void *caller); #define qdf_mem_malloc(size) \ - qdf_mem_malloc_debug(size, __FILE__, __LINE__) + qdf_mem_malloc_debug(size, __FILE__, __LINE__, QDF_RET_IP) /** * qdf_mem_free_debug() - debug version of qdf_mem_free @@ -167,16 +169,18 @@ void qdf_mem_check_for_leaks(void); * @paddr: Physical address * @file: file name of the call site * @line: line numbe rof the call site + * @caller: Address of the caller function * * Return: pointer of allocated memory or null if memory alloc fails */ void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev, qdf_size_t size, qdf_dma_addr_t *paddr, - const char *file, uint32_t line); + const char *file, uint32_t line, + void *caller); #define qdf_mem_alloc_consistent(osdev, dev, size, paddr) \ qdf_mem_alloc_consistent_debug(osdev, dev, size, paddr, \ - __FILE__, __LINE__) + __FILE__, __LINE__, QDF_RET_IP) /** * qdf_mem_free_consistent_debug() - free consistent qdf memory diff --git a/qdf/linux/src/i_qdf_mem.h b/qdf/linux/src/i_qdf_mem.h index 63b066b7a9..f664e08b5a 100644 --- a/qdf/linux/src/i_qdf_mem.h +++ b/qdf/linux/src/i_qdf_mem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -66,6 +66,7 @@ #define vfree(buf) #define pci_alloc_consistent(dev, size, paddr) NULL #define __qdf_mempool_t void* +#define QDF_RET_IP NULL #endif /* __KERNEL__ */ #include @@ -205,6 +206,7 @@ int __qdf_mempool_init(qdf_device_t osdev, __qdf_mempool_t *pool, int pool_cnt, void __qdf_mempool_destroy(qdf_device_t osdev, __qdf_mempool_t pool); void *__qdf_mempool_alloc(qdf_device_t osdev, __qdf_mempool_t pool); void __qdf_mempool_free(qdf_device_t osdev, __qdf_mempool_t pool, void *buf); +#define QDF_RET_IP ((void *)_RET_IP_) #define __qdf_mempool_elem_size(_pool) ((_pool)->elem_size) #endif diff --git a/qdf/linux/src/qdf_mem.c b/qdf/linux/src/qdf_mem.c index ac5b1f5679..7938380093 100644 --- a/qdf/linux/src/qdf_mem.c +++ b/qdf/linux/src/qdf_mem.c @@ -89,6 +89,7 @@ static inline qdf_list_t *qdf_mem_dma_list(enum qdf_debug_domain domain) * @file: name of the file the allocation was made from * @line: line number of the file the allocation was made from * @size: size of the allocation in bytes + * @caller: Caller of the function for which memory is allocated * @header: a known value, used to detect out-of-bounds access */ struct qdf_mem_header { @@ -98,6 +99,7 @@ struct qdf_mem_header { const char *file; uint32_t line; uint32_t size; + void *caller; uint64_t header; }; @@ -142,7 +144,7 @@ static void qdf_mem_trailer_init(struct qdf_mem_header *header) } static void qdf_mem_header_init(struct qdf_mem_header *header, qdf_size_t size, - const char *file, uint32_t line) + const char *file, uint32_t line, void *caller) { QDF_BUG(header); if (!header) @@ -153,6 +155,7 @@ static void qdf_mem_header_init(struct qdf_mem_header *header, qdf_size_t size, header->file = file; header->line = line; header->size = size; + header->caller = caller; header->header = WLAN_MEM_HEADER; } @@ -357,6 +360,7 @@ static int seq_printf_printer(void *priv, const char *fmt, ...) * @file: the file which allocated memory * @line: the line at which allocation happened * @size: the size of allocation + * @caller: Address of the caller function * @count: how many allocations of same type * */ @@ -364,6 +368,7 @@ struct __qdf_mem_info { const char *file; uint32_t line; uint32_t size; + void *caller; uint32_t count; }; @@ -385,7 +390,7 @@ static void qdf_mem_domain_print_header(qdf_abstract_print print, { print(print_priv, "--------------------------------------------------------------"); - print(print_priv, " count size total filename"); + print(print_priv, " count size total filename caller"); print(print_priv, "--------------------------------------------------------------"); } @@ -409,12 +414,12 @@ static void qdf_mem_meta_table_print(struct __qdf_mem_info *table, break; print(print_priv, - "%6u x %5u = %7uB @ %s:%u", + "%6u x %5u = %7uB @ %s:%u %pS", table[i].count, table[i].size, table[i].count * table[i].size, kbasename(table[i].file), - table[i].line); + table[i].line, table[i].caller); } } @@ -436,12 +441,14 @@ static bool qdf_mem_meta_table_insert(struct __qdf_mem_info *table, table[i].line = meta->line; table[i].size = meta->size; table[i].count = 1; + table[i].caller = meta->caller; break; } if (table[i].file == meta->file && table[i].line == meta->line && - table[i].size == meta->size) { + table[i].size == meta->size && + table[i].caller == meta->caller) { table[i].count++; break; } @@ -1035,7 +1042,8 @@ static void qdf_mem_debug_exit(void) qdf_spinlock_destroy(&qdf_mem_dma_list_lock); } -void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line) +void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line, + void *caller) { QDF_STATUS status; enum qdf_debug_domain current_domain = qdf_debug_domain_get(); @@ -1066,7 +1074,7 @@ void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line) return NULL; } - qdf_mem_header_init(header, size, file, line); + qdf_mem_header_init(header, size, file, line, caller); qdf_mem_trailer_init(header); ptr = qdf_mem_get_ptr(header); @@ -1586,7 +1594,8 @@ qdf_mem_dma_free(void *dev, qdf_size_t size, void *vaddr, qdf_dma_addr_t paddr) #ifdef MEMORY_DEBUG void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev, qdf_size_t size, qdf_dma_addr_t *paddr, - const char *file, uint32_t line) + const char *file, uint32_t line, + void *caller) { QDF_STATUS status; enum qdf_debug_domain current_domain = qdf_debug_domain_get(); @@ -1613,7 +1622,7 @@ void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev, * Prefix the header into DMA buffer causes SMMU faults, so * do not prefix header into the DMA buffers */ - qdf_mem_header_init(header, size, file, line); + qdf_mem_header_init(header, size, file, line, caller); qdf_spin_lock_irqsave(&qdf_mem_dma_list_lock); status = qdf_list_insert_front(mem_list, &header->node);