qcacmn: Add mem stats for perf builds
Add memory allocation statistics for perf builds where MEMORY_DEBUG is not enabled. Part of this effort, re-structure some of the QDF memory APIs. Memory stats shows real size allocated. Change-Id: I1e8fe0f4080ea186b8bfa0ce0438b4a06dde5a66 CRs-Fixed: 2045476
This commit is contained in:

committed by
snandini

parent
1ff1f2ef82
commit
e4f8f0e015
@@ -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__)
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user