diff --git a/qdf/inc/qdf_mem.h b/qdf/inc/qdf_mem.h index ab5e0bdf5d..8eac979a15 100644 --- a/qdf/inc/qdf_mem.h +++ b/qdf/inc/qdf_mem.h @@ -76,33 +76,23 @@ struct qdf_mem_multi_page_t { /* Preprocessor definitions and constants */ typedef __qdf_mempool_t qdf_mempool_t; -#ifdef MEMORY_DEBUG -void qdf_mem_clean(void); +/** + * qdf_mem_init() - Initialize QDF memory module + * + * Return: None + * + */ void qdf_mem_init(void); +/** + * qdf_mem_exit() - Exit QDF memory module + * + * Return: None + * + */ void qdf_mem_exit(void); -#else -/** - * qdf_mem_init() - initialize qdf memory debug functionality - * - * Return: none - */ -static inline void qdf_mem_init(void) -{ -} - -/** - * qdf_mem_exit() - exit qdf memory debug functionality - * - * Return: none - */ -static inline void qdf_mem_exit(void) -{ -} -#endif - #ifdef MEMORY_DEBUG #define qdf_mem_malloc(size) \ qdf_mem_malloc_debug(size, __FILE__, __LINE__) diff --git a/qdf/linux/src/qdf_mem.c b/qdf/linux/src/qdf_mem.c index e8541a54e1..823a568af6 100644 --- a/qdf/linux/src/qdf_mem.c +++ b/qdf/linux/src/qdf_mem.c @@ -93,7 +93,14 @@ u_int8_t prealloc_disabled = 1; qdf_declare_param(prealloc_disabled, byte); EXPORT_SYMBOL(prealloc_disabled); -#if defined WLAN_DEBUGFS && defined MEMORY_DEBUG + + + + +#if defined WLAN_DEBUGFS + +/* Debugfs root directory for qdf_mem */ +static struct dentry *qdf_mem_debugfs_root; /** * struct __qdf_mem_stat - qdf memory statistics @@ -105,33 +112,6 @@ static struct __qdf_mem_stat { qdf_atomic_t dma; } qdf_mem_stat; - -/** - * struct __qdf_mem_info - memory statistics - * @file_name: the file which allocated memory - * @line_num: the line at which allocation happened - * @size: the size of allocation - * @count: how many allocations of same type - * - */ -struct __qdf_mem_info { - char *file_name; - unsigned int line_num; - unsigned int size; - unsigned int count; -}; - -/* Debugfs root directory for qdf_mem */ -static struct dentry *qdf_mem_debugfs_root; - -/* - * A table to identify duplicates in close proximity. The table depth defines - * the proximity scope. A deeper table takes more time. Chose any optimum value. - * - */ -#define QDF_MEM_STAT_TABLE_SIZE 4 -static struct __qdf_mem_info qdf_mem_info_table[QDF_MEM_STAT_TABLE_SIZE]; - static inline void qdf_mem_kmalloc_inc(qdf_size_t size) { qdf_atomic_add(size, &qdf_mem_stat.kmalloc); @@ -152,6 +132,32 @@ static inline void qdf_mem_dma_dec(qdf_size_t size) qdf_atomic_sub(size, &qdf_mem_stat.dma); } +#ifdef MEMORY_DEBUG +/** + * struct __qdf_mem_info - memory statistics + * @file_name: the file which allocated memory + * @line_num: the line at which allocation happened + * @size: the size of allocation + * @count: how many allocations of same type + * + */ +struct __qdf_mem_info { + char *file_name; + unsigned int line_num; + unsigned int size; + unsigned int count; +}; + + +/* + * A table to identify duplicates in close proximity. The table depth defines + * the proximity scope. A deeper table takes more time. Chose any optimum value. + * + */ +#define QDF_MEM_STAT_TABLE_SIZE 4 +static struct __qdf_mem_info qdf_mem_info_table[QDF_MEM_STAT_TABLE_SIZE]; + + /** * qdf_mem_info_table_init() - initialize the stat table @@ -423,11 +429,46 @@ static const struct file_operations fops_qdf_mem_debugfs = { .release = seq_release, }; -/** - * qdf_mem_debugfs_init() - initialize routine - * - * Return: QDF_STATUS - */ +static QDF_STATUS qdf_mem_debug_debugfs_init(void) +{ + if (!qdf_mem_debugfs_root) + return QDF_STATUS_E_FAILURE; + + debugfs_create_file("list", + S_IRUSR | S_IWUSR, + qdf_mem_debugfs_root, + NULL, + &fops_qdf_mem_debugfs); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS qdf_mem_debug_debugfs_exit(void) +{ + return QDF_STATUS_SUCCESS; +} + +#else /* MEMORY_DEBUG */ + +static QDF_STATUS qdf_mem_debug_debugfs_init(void) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS qdf_mem_debug_debugfs_exit(void) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +#endif /* MEMORY_DEBUG */ + + +static void qdf_mem_debugfs_exit(void) +{ + debugfs_remove_recursive(qdf_mem_debugfs_root); + qdf_mem_debugfs_root = NULL; +} + static QDF_STATUS qdf_mem_debugfs_init(void) { struct dentry *qdf_debugfs_root = qdf_debugfs_get_root(); @@ -440,11 +481,6 @@ static QDF_STATUS qdf_mem_debugfs_init(void) if (!qdf_mem_debugfs_root) return QDF_STATUS_E_FAILURE; - debugfs_create_file("list", - S_IRUSR | S_IWUSR, - qdf_mem_debugfs_root, - NULL, - &fops_qdf_mem_debugfs); debugfs_create_atomic_t("kmalloc", S_IRUSR | S_IWUSR, @@ -459,26 +495,13 @@ static QDF_STATUS qdf_mem_debugfs_init(void) return QDF_STATUS_SUCCESS; } - -/** - * qdf_mem_debugfs_exit() - cleanup routine - * - * Return: None - */ -static void qdf_mem_debugfs_exit(void) -{ - debugfs_remove_recursive(qdf_mem_debugfs_root); - qdf_mem_debugfs_root = NULL; -} - -#else /* WLAN_DEBUGFS && MEMORY_DEBUG */ +#else /* WLAN_DEBUGFS */ static inline void qdf_mem_kmalloc_inc(qdf_size_t size) {} static inline void qdf_mem_dma_inc(qdf_size_t size) {} static inline void qdf_mem_kmalloc_dec(qdf_size_t size) {} static inline void qdf_mem_dma_dec(qdf_size_t size) {} -#ifdef MEMORY_DEBUG static QDF_STATUS qdf_mem_debugfs_init(void) { @@ -486,9 +509,23 @@ static QDF_STATUS qdf_mem_debugfs_init(void) } static void qdf_mem_debugfs_exit(void) {} -#endif -#endif /* WLAN_DEBUGFS && MEMORY_DEBUG */ +static QDF_STATUS qdf_mem_debug_debugfs_init(void) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS qdf_mem_debug_debugfs_init(void) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static QDF_STATUS qdf_mem_debug_debugfs_exit(void) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +#endif /* WLAN_DEBUGFS */ /** * __qdf_mempool_init() - Create and initialize memory pool @@ -764,27 +801,26 @@ static inline bool qdf_mem_prealloc_put(void *ptr) #ifdef MEMORY_DEBUG /** - * qdf_mem_init() - initialize qdf memory debug functionality + * qdf_mem_debug_init() - initialize qdf memory debug functionality * * Return: none */ -void qdf_mem_init(void) +static void qdf_mem_debug_init(void) { /* Initalizing the list with maximum size of 60000 */ qdf_list_create(&qdf_mem_list, 60000); qdf_spinlock_create(&qdf_mem_list_lock); qdf_net_buf_debug_init(); - qdf_mem_debugfs_init(); return; } -EXPORT_SYMBOL(qdf_mem_init); /** - * qdf_mem_clean() - display memory leak debug info and free leaked pointers + * qdf_mem_debug_clean() - display memory leak debug info and free leaked + * pointers * * Return: none */ -void qdf_mem_clean(void) +static void qdf_mem_debug_clean(void) { uint32_t list_size; list_size = qdf_list_size(&qdf_mem_list); @@ -848,21 +884,18 @@ void qdf_mem_clean(void) #endif } } -EXPORT_SYMBOL(qdf_mem_clean); /** - * qdf_mem_exit() - exit qdf memory debug functionality + * qdf_mem_debug_exit() - exit qdf memory debug functionality * * Return: none */ -void qdf_mem_exit(void) +static void qdf_mem_debug_exit(void) { - qdf_mem_debugfs_exit(); qdf_net_buf_debug_exit(); - qdf_mem_clean(); + qdf_mem_debug_clean(); qdf_list_destroy(&qdf_mem_list); } -EXPORT_SYMBOL(qdf_mem_exit); /** * qdf_mem_malloc_debug() - debug version of QDF memory allocation API @@ -925,7 +958,7 @@ void *qdf_mem_malloc_debug(size_t size, mem_struct->line_num = line_num; mem_struct->size = size; qdf_atomic_inc(&mem_struct->in_use); - qdf_mem_kmalloc_inc(size); + qdf_mem_kmalloc_inc(ksize(mem_struct)); qdf_mem_copy(&mem_struct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); @@ -1052,7 +1085,7 @@ void qdf_mem_free(void *ptr) list_del_init(&mem_struct->node); qdf_mem_list.count--; qdf_spin_unlock_irqrestore(&qdf_mem_list_lock); - qdf_mem_kmalloc_dec(mem_struct->size); + qdf_mem_kmalloc_dec(ksize(mem_struct)); kfree(mem_struct); return; @@ -1096,6 +1129,9 @@ error: } EXPORT_SYMBOL(qdf_mem_free); #else +static void qdf_mem_debug_init(void) {} + +static void qdf_mem_debug_exit(void) {} /** * qdf_mem_malloc() - allocation QDF memory @@ -1121,7 +1157,13 @@ void *qdf_mem_malloc(size_t size) if (in_interrupt() || irqs_disabled() || in_atomic()) flags = GFP_ATOMIC; - return kzalloc(size, flags); + mem = kzalloc(size, flags); + + if (mem) + qdf_mem_kmalloc_inc(ksize(mem)); + + return mem; + } EXPORT_SYMBOL(qdf_mem_malloc); @@ -1141,6 +1183,8 @@ void qdf_mem_free(void *ptr) if (qdf_mem_prealloc_put(ptr)) return; + qdf_mem_kmalloc_dec(ksize(ptr)); + kfree(ptr); } EXPORT_SYMBOL(qdf_mem_free); @@ -1483,6 +1527,8 @@ void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, qdf_size_t size, * of different size" warning on some platforms */ BUILD_BUG_ON(sizeof(*phy_addr) < sizeof(vaddr)); + if (vaddr) + qdf_mem_dma_inc(ksize(vaddr)); return vaddr; } @@ -1555,6 +1601,7 @@ inline void qdf_mem_free_consistent(qdf_device_t osdev, void *dev, qdf_dma_addr_t phy_addr, qdf_dma_context_t memctx) { + qdf_mem_dma_dec(ksize(vaddr)); qdf_mem_free(vaddr); return; } @@ -1612,3 +1659,19 @@ void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, dma_sync_single_for_cpu(osdev->dev, bus_addr, size, direction); } EXPORT_SYMBOL(qdf_mem_dma_sync_single_for_cpu); + +void qdf_mem_init(void) +{ + qdf_mem_debug_init(); + qdf_mem_debugfs_init(); + qdf_mem_debug_debugfs_init(); +} +EXPORT_SYMBOL(qdf_mem_init); + +void qdf_mem_exit(void) +{ + qdf_mem_debug_debugfs_exit(); + qdf_mem_debugfs_exit(); + qdf_mem_debug_exit(); +} +EXPORT_SYMBOL(qdf_mem_exit);