diff --git a/arch/sim/src/sim/sim_heap.c b/arch/sim/src/sim/sim_heap.c index c897ac86bb..b01323575f 100644 --- a/arch/sim/src/sim/sim_heap.c +++ b/arch/sim/src/sim/sim_heap.c @@ -396,11 +396,15 @@ int mm_mallinfo(struct mm_heap_s *heap, struct mallinfo *info) * ****************************************************************************/ -int mm_mallinfo_task(struct mm_heap_s *heap, struct mallinfo_task *info) +struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump) { - info->aordblks = 0; - info->uordblks = 0; - return 0; + struct mallinfo_task info = + { + 0, 0 + }; + + return info; } /**************************************************************************** @@ -411,7 +415,7 @@ int mm_mallinfo_task(struct mm_heap_s *heap, struct mallinfo_task *info) * ****************************************************************************/ -void mm_memdump(struct mm_heap_s *heap, pid_t pid) +void mm_memdump(struct mm_heap_s *heap, const struct mm_memdump_s *dump) { } diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c index f4c1ab03d0..77abb8bd34 100644 --- a/fs/procfs/fs_procfsmeminfo.c +++ b/fs/procfs/fs_procfsmeminfo.c @@ -419,7 +419,8 @@ static ssize_t memdump_read(FAR struct file *filep, FAR char *buffer, #if CONFIG_MM_BACKTRACE >= 0 linesize = procfs_snprintf(procfile->line, MEMINFO_LINELEN, - "usage: \n" + "usage: " + " \n" "on/off backtrace\n" "pid: dump pid allocated node\n"); #else @@ -436,8 +437,20 @@ static ssize_t memdump_read(FAR struct file *filep, FAR char *buffer, "used: dump all allocated node\n" "free: dump all free node\n"); + copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, + &offset); + totalsize += copysize; + +#if CONFIG_MM_BACKTRACE >= 0 + buffer += copysize; + buflen -= copysize; + linesize = procfs_snprintf(procfile->line, MEMINFO_LINELEN, + "The current sequence number %lu\n", g_mm_seqno); + totalsize += procfs_memcpy(procfile->line, linesize, buffer, buflen, &offset); +#endif + filep->f_pos += totalsize; return totalsize; } @@ -453,10 +466,20 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer, { FAR struct procfs_meminfo_entry_s *entry; FAR struct meminfo_file_s *procfile; - pid_t pid = INVALID_PROCESS_ID; + struct mm_memdump_s dump = + { + MM_BACKTRACE_ALLOC_PID, +#if CONFIG_MM_BACKTRACE >= 0 + 0, + ULONG_MAX +#endif + }; + +#if CONFIG_MM_BACKTRACE >= 0 + FAR char *p; +#endif #if CONFIG_MM_BACKTRACE > 0 FAR struct tcb_s *tcb; - FAR char *p; #endif DEBUGASSERT(filep != NULL && buffer != NULL && buflen > 0); @@ -488,8 +511,8 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer, else if ((p = strstr(buffer, "on")) != NULL) { *p = '\0'; - pid = atoi(buffer); - tcb = nxsched_get_tcb(pid); + dump.pid = atoi(buffer); + tcb = nxsched_get_tcb(dump.pid); if (tcb == NULL) { return -EINVAL; @@ -501,8 +524,8 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer, else if ((p = strstr(buffer, "off")) != NULL) { *p = '\0'; - pid = atoi(buffer); - tcb = nxsched_get_tcb(pid); + dump.pid = atoi(buffer); + tcb = nxsched_get_tcb(dump.pid); if (tcb == NULL) { return -EINVAL; @@ -516,11 +539,21 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer, switch (buffer[0]) { case 'u': - pid = MM_BACKTRACE_ALLOC_PID; + dump.pid = MM_BACKTRACE_ALLOC_PID; + +#if CONFIG_MM_BACKTRACE >= 0 + p = (FAR char *)buffer + 4; + goto dump; +#endif break; case 'f': - pid = MM_BACKTRACE_FREE_PID; + dump.pid = MM_BACKTRACE_FREE_PID; + +#if CONFIG_MM_BACKTRACE >= 0 + p = (FAR char *)buffer + 4; + goto dump; +#endif break; #if CONFIG_MM_BACKTRACE >= 0 default: @@ -529,13 +562,26 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer, return buflen; } - pid = atoi(buffer); + dump.pid = strtol(buffer, &p, 0); + if (!isdigit(*(p + 1))) + { + break; + } + +dump: + dump.seqmin = strtoul(p + 1, &p, 0); + if (!isdigit(*(p + 1))) + { + break; + } + + dump.seqmax = strtoul(p + 1, &p, 0); #endif } for (entry = g_procfs_meminfo; entry != NULL; entry = entry->next) { - mm_memdump(entry->heap, pid); + mm_memdump(entry->heap, &dump); } return buflen; diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 10056341d9..44d2293227 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -886,16 +886,20 @@ static ssize_t proc_heap(FAR struct proc_file_s *procfile, size_t copysize; size_t totalsize = 0; struct mallinfo_task info; + struct mm_memdump_s dump; + dump.pid = tcb->pid; + dump.seqmin = 0; + dump.seqmax = ULONG_MAX; #ifdef CONFIG_MM_KERNEL_HEAP if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) { - info = kmm_mallinfo_task(tcb->pid); + info = kmm_mallinfo_task(&dump); } else #endif { - info = mallinfo_task(tcb->pid); + info = mallinfo_task(&dump); } /* Show the heap alloc size */ diff --git a/include/malloc.h b/include/malloc.h index 030738ed0e..5760538a0d 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -52,13 +52,29 @@ struct mallinfo * by free (not in use) chunks. */ }; +struct mm_memdump_s +{ + pid_t pid; /* Process id */ +#if CONFIG_MM_BACKTRACE >= 0 + unsigned long seqmin; /* The minimum sequence */ + unsigned long seqmax; /* The maximum sequence */ +#endif +}; + struct mallinfo_task { - pid_t pid; /* The pid of task */ int aordblks; /* This is the number of allocated (in use) chunks for task */ int uordblks; /* This is the total size of memory occupied for task */ }; +/**************************************************************************** + * Public data + ****************************************************************************/ + +#if CONFIG_MM_BACKTRACE >= 0 +extern unsigned long g_mm_seqno; +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -70,7 +86,7 @@ extern "C" struct mallinfo mallinfo(void); size_t malloc_size(FAR void *ptr); -struct mallinfo_task mallinfo_task(pid_t pid); +struct mallinfo_task mallinfo_task(FAR const struct mm_memdump_s *dump); #if defined(__cplusplus) } diff --git a/include/nuttx/mm/mempool.h b/include/nuttx/mm/mempool.h index aa4bacbb36..cd9338acd3 100644 --- a/include/nuttx/mm/mempool.h +++ b/include/nuttx/mm/mempool.h @@ -118,6 +118,7 @@ struct mempool_backtrace_s { struct list_node node; pid_t pid; + unsigned long seqno; /* The sequence of memory malloc */ # if CONFIG_MM_BACKTRACE > 0 FAR void *backtrace[CONFIG_MM_BACKTRACE]; # endif @@ -229,13 +230,14 @@ int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info); * * Input Parameters: * pool - Address of the memory pool to be used. - * info - The pointer of mempoolinfo. + * dump - The information of what need dump. * * Returned Value: * OK on success; A negated errno value on any failure. ****************************************************************************/ -void mempool_memdump(FAR struct mempool_s *pool, pid_t pid); +void mempool_memdump(FAR struct mempool_s *pool, + FAR const struct mm_memdump_s *dump); /**************************************************************************** * Name: mempool_deinit @@ -257,11 +259,15 @@ int mempool_deinit(FAR struct mempool_s *pool); * * Input Parameters: * pool - Address of the memory pool to be used. - * info - Memory info. + * dump - The information of what need dump. + * + * Returned Value: + * Statistics of memory information based on dump. ****************************************************************************/ -int mempool_info_task(FAR struct mempool_s *pool, - FAR struct mempoolinfo_task *info); +struct mempoolinfo_task +mempool_info_task(FAR struct mempool_s *pool, + FAR const struct mm_memdump_s *dump); /**************************************************************************** * Name: mempool_procfs_register @@ -454,12 +460,12 @@ FAR void *mempool_multiple_memalign(FAR struct mempool_multiple_s *mpool, * * Input Parameters: * mpool - The handle of multiple memory pool to be used. - * pid - The pid of task. + * dump - The information of what need dump. * ****************************************************************************/ void mempool_multiple_memdump(FAR struct mempool_multiple_s *mpool, - pid_t pid); + FAR const struct mm_memdump_s *dump); /**************************************************************************** * Name: mempool_multiple_deinit @@ -489,11 +495,15 @@ void mempool_multiple_info(FAR struct mempool_multiple_s *mpool); * * Input Parameters: * mpool - The handle of multiple memory pool to be used. - * info - Memory info. + * dump - The information of what need dump. + * + * Returned Value: + * Statistics of memory information based on dump. ****************************************************************************/ -void mempool_multiple_info_task(FAR struct mempool_multiple_s *mpool, - FAR struct mempoolinfo_task *info); +struct mempoolinfo_task +mempool_multiple_info_task(FAR struct mempool_multiple_s *mpool, + FAR const struct mm_memdump_s *dump); #undef EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h index 8cd6d49ff0..9468bc3f49 100644 --- a/include/nuttx/mm/mm.h +++ b/include/nuttx/mm/mm.h @@ -107,6 +107,7 @@ ****************************************************************************/ struct mm_heap_s; /* Forward reference */ +struct mm_memdump_s; /**************************************************************************** * Public Data @@ -253,7 +254,7 @@ FAR void *kmm_zalloc(size_t size) malloc_like1(1); /* Functions contained in kmm_memdump.c *************************************/ #ifdef CONFIG_MM_KERNEL_HEAP -void kmm_memdump(pid_t pid); +void kmm_memdump(FAR const struct mm_memdump_s *dump); #endif /* Functions contained in mm_memalign.c *************************************/ @@ -315,21 +316,22 @@ void kmm_extend(FAR void *mem, size_t size, int region); struct mallinfo; /* Forward reference */ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info); struct mallinfo_task; /* Forward reference */ -int mm_mallinfo_task(FAR struct mm_heap_s *heap, - FAR struct mallinfo_task *info); +struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump); /* Functions contained in kmm_mallinfo.c ************************************/ #ifdef CONFIG_MM_KERNEL_HEAP struct mallinfo kmm_mallinfo(void); # if CONFIG_MM_BACKTRACE >= 0 -struct mallinfo_task kmm_mallinfo_task(pid_t pid); +struct mallinfo_task kmm_mallinfo_task(FAR const struct mm_memdump_s *dump); # endif #endif /* Functions contained in mm_memdump.c **************************************/ -void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid); +void mm_memdump(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump); #ifdef CONFIG_DEBUG_MM /* Functions contained in mm_checkcorruption.c ******************************/ @@ -342,7 +344,7 @@ FAR void umm_checkcorruption(void); /* Functions contained in umm_memdump.c *************************************/ -void umm_memdump(pid_t pid); +void umm_memdump(FAR const struct mm_memdump_s *dump); /* Functions contained in kmm_checkcorruption.c *****************************/ diff --git a/mm/kmm_heap/kmm_mallinfo.c b/mm/kmm_heap/kmm_mallinfo.c index 89e4ea4476..c0b17dcbc4 100644 --- a/mm/kmm_heap/kmm_mallinfo.c +++ b/mm/kmm_heap/kmm_mallinfo.c @@ -59,12 +59,8 @@ struct mallinfo kmm_mallinfo(void) * ****************************************************************************/ -struct mallinfo_task kmm_mallinfo_task(pid_t pid) +struct mallinfo_task kmm_mallinfo_task(FAR const struct mm_memdump_s *dump) { - struct mallinfo_task info; - - info.pid = pid; - mm_mallinfo_task(g_kmmheap, &info); - return info; + return mm_mallinfo_task(g_kmmheap, dump); } #endif /* CONFIG_MM_KERNEL_HEAP */ diff --git a/mm/kmm_heap/kmm_memdump.c b/mm/kmm_heap/kmm_memdump.c index e4a0b01998..1eae5e13eb 100644 --- a/mm/kmm_heap/kmm_memdump.c +++ b/mm/kmm_heap/kmm_memdump.c @@ -39,9 +39,9 @@ * ****************************************************************************/ -void kmm_memdump(pid_t pid) +void kmm_memdump(FAR const struct mm_memdump_s *dump) { - mm_memdump(g_kmmheap, pid); + mm_memdump(g_kmmheap, dump); } #endif /* CONFIG_MM_KERNEL_HEAP */ diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c index 7374dbb131..08335c06f4 100644 --- a/mm/mempool/mempool.c +++ b/mm/mempool/mempool.c @@ -89,6 +89,7 @@ static inline void mempool_add_backtrace(FAR struct mempool_s *pool, { list_add_head(&pool->alist, &buf->node); buf->pid = _SCHED_GETTID(); + buf->seqno = g_mm_seqno++; # if CONFIG_MM_BACKTRACE > 0 if (pool->procfs.backtrace) { @@ -396,21 +397,25 @@ int mempool_info(FAR struct mempool_s *pool, FAR struct mempoolinfo_s *info) * Name: mempool_info_task ****************************************************************************/ -int mempool_info_task(FAR struct mempool_s *pool, - FAR struct mempoolinfo_task *info) +struct mempoolinfo_task +mempool_info_task(FAR struct mempool_s *pool, + FAR const struct mm_memdump_s *dump) { irqstate_t flags = spin_lock_irqsave(&pool->lock); + struct mempoolinfo_task info = + { + 0, 0 + }; - DEBUGASSERT(info); - if (info->pid == MM_BACKTRACE_FREE_PID) + if (dump->pid == MM_BACKTRACE_FREE_PID) { size_t count = mempool_queue_lenth(&pool->queue) + mempool_queue_lenth(&pool->iqueue); - info->aordblks += count; - info->uordblks += count * pool->blocksize; + info.aordblks += count; + info.uordblks += count * pool->blocksize; } - else if (info->pid == MM_BACKTRACE_ALLOC_PID) + else if (dump->pid == MM_BACKTRACE_ALLOC_PID) { #if CONFIG_MM_BACKTRACE >= 0 size_t count = list_length(&pool->alist); @@ -418,10 +423,10 @@ int mempool_info_task(FAR struct mempool_s *pool, size_t count = pool->nalloc; #endif - info->aordblks += count; - info->uordblks += count * pool->blocksize; - info->aordblks -= pool->nexpend; - info->uordblks -= pool->totalsize; + info.aordblks += count; + info.uordblks += count * pool->blocksize; + info.aordblks -= pool->nexpend; + info.uordblks -= pool->totalsize; } #if CONFIG_MM_BACKTRACE >= 0 else @@ -431,17 +436,19 @@ int mempool_info_task(FAR struct mempool_s *pool, list_for_every_entry(&pool->alist, buf, struct mempool_backtrace_s, node) { - if (buf->pid == info->pid) + if (buf->pid == dump->pid && + buf->seqno >= dump->seqmin && + buf->seqno <= dump->seqmax) { - info->aordblks++; - info->uordblks += pool->blocksize; + info.aordblks++; + info.uordblks += pool->blocksize; } } } #endif spin_unlock_irqrestore(&pool->lock, flags); - return OK; + return info; } /**************************************************************************** @@ -457,15 +464,16 @@ int mempool_info_task(FAR struct mempool_s *pool, * * Input Parameters: * pool - Address of the memory pool to be used. - * pid - The task of pid. + * dump - The information of what need dump. * * Returned Value: * OK on success; A negated errno value on any failure. ****************************************************************************/ -void mempool_memdump(FAR struct mempool_s *pool, pid_t pid) +void mempool_memdump(FAR struct mempool_s *pool, + FAR const struct mm_memdump_s *dump) { - if (pid == MM_BACKTRACE_FREE_PID) + if (dump->pid == MM_BACKTRACE_FREE_PID) { FAR sq_entry_t *entry; @@ -491,7 +499,9 @@ void mempool_memdump(FAR struct mempool_s *pool, pid_t pid) list_for_every_entry(&pool->alist, buf, struct mempool_backtrace_s, node) { - if (buf->pid == pid || pid == MM_BACKTRACE_ALLOC_PID) + if ((buf->pid == dump->pid || + dump->pid == MM_BACKTRACE_ALLOC_PID) && + buf->seqno >= dump->seqmin && buf->seqno <= dump->seqmax) { # if CONFIG_MM_BACKTRACE > 0 int i; @@ -509,8 +519,9 @@ void mempool_memdump(FAR struct mempool_s *pool, pid_t pid) } # endif - syslog(LOG_INFO, "%6d%12zu%*p%s\n", - (int)buf->pid, pool->blocksize, MM_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n", + (int)buf->pid, pool->blocksize, buf->seqno, + MM_PTR_FMT_WIDTH, ((FAR char *)buf - pool->blocksize), bt); } } diff --git a/mm/mempool/mempool_multiple.c b/mm/mempool/mempool_multiple.c index eea3aa95b8..8004864d26 100644 --- a/mm/mempool/mempool_multiple.c +++ b/mm/mempool/mempool_multiple.c @@ -618,15 +618,25 @@ void mempool_multiple_info(FAR struct mempool_multiple_s *mpool) * Name: mempool_multiple_info_task ****************************************************************************/ -void mempool_multiple_info_task(FAR struct mempool_multiple_s *mpool, - FAR struct mempoolinfo_task *info) +struct mempoolinfo_task +mempool_multiple_info_task(FAR struct mempool_multiple_s *mpool, + FAR const struct mm_memdump_s *dump) { - size_t i; + int i; + struct mempoolinfo_task info; + struct mempoolinfo_task ret = + { + 0, 0 + }; for (i = 0; i < mpool->npools; i++) { - mempool_info_task(mpool->pools + i, info); + info = mempool_info_task(mpool->pools + i, dump); + ret.aordblks += info.aordblks; + ret.uordblks += info.uordblks; } + + return ret; } /**************************************************************************** @@ -642,18 +652,18 @@ void mempool_multiple_info_task(FAR struct mempool_multiple_s *mpool, * * Input Parameters: * mpool - The handle of multiple memory pool to be used. - * pid - The pid of task. + * dump - The information of what need dump. * ****************************************************************************/ void mempool_multiple_memdump(FAR struct mempool_multiple_s *mpool, - pid_t pid) + FAR const struct mm_memdump_s *dump) { size_t i; for (i = 0; i < mpool->npools; i++) { - mempool_memdump(mpool->pools + i, pid); + mempool_memdump(mpool->pools + i, dump); } } diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h index 4cbfdf7f02..b3a438bc75 100644 --- a/mm/mm_heap/mm.h +++ b/mm/mm_heap/mm.h @@ -76,6 +76,7 @@ { \ FAR struct mm_allocnode_s *tmp = (FAR struct mm_allocnode_s *)(ptr); \ tmp->pid = _SCHED_GETTID(); \ + tmp->seqno = g_mm_seqno++; \ } \ while (0) #elif CONFIG_MM_BACKTRACE > 0 @@ -98,6 +99,7 @@ { \ tmp->backtrace[0] = NULL; \ } \ + tmp->seqno = g_mm_seqno++; \ } \ while (0) #else @@ -170,6 +172,7 @@ struct mm_allocnode_s mmsize_t size; /* Size of this chunk */ #if CONFIG_MM_BACKTRACE >= 0 pid_t pid; /* The pid for caller */ + unsigned long seqno; /* The sequence of memory malloc */ # if CONFIG_MM_BACKTRACE > 0 FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */ # endif @@ -184,6 +187,7 @@ struct mm_freenode_s mmsize_t size; /* Size of this chunk */ #if CONFIG_MM_BACKTRACE >= 0 pid_t pid; /* The pid for caller */ + unsigned long seqno; /* The sequence of memory malloc */ # if CONFIG_MM_BACKTRACE > 0 FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */ # endif diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c index 6a6b1c3407..be8546e0e6 100644 --- a/mm/mm_heap/mm_mallinfo.c +++ b/mm/mm_heap/mm_mallinfo.c @@ -32,6 +32,16 @@ #include "mm_heap/mm.h" +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mm_mallinfo_handler_s +{ + FAR const struct mm_memdump_s *dump; + FAR struct mallinfo_task *info; +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -78,7 +88,7 @@ static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg) static void mallinfo_task_handler(FAR struct mm_allocnode_s *node, FAR void *arg) { - FAR struct mallinfo_task *info = arg; + FAR struct mm_mallinfo_handler_s *handle = arg; size_t nodesize = SIZEOF_MM_NODE(node); /* Check if the node corresponds to an allocated memory chunk */ @@ -87,19 +97,22 @@ static void mallinfo_task_handler(FAR struct mm_allocnode_s *node, { DEBUGASSERT(nodesize >= SIZEOF_MM_ALLOCNODE); #if CONFIG_MM_BACKTRACE < 0 - if (info->pid == MM_BACKTRACE_ALLOC_PID) + if (handle->dump->pid == MM_BACKTRACE_ALLOC_PID) #else - if (info->pid == MM_BACKTRACE_ALLOC_PID || node->pid == info->pid) + if ((handle->dump->pid == MM_BACKTRACE_ALLOC_PID || + handle->dump->pid == node->pid) && + node->seqno >= handle->dump->seqmin && + node->seqno <= handle->dump->seqmax) #endif { - info->aordblks++; - info->uordblks += nodesize; + handle->info->aordblks++; + handle->info->uordblks += nodesize; } } - else if (info->pid == MM_BACKTRACE_FREE_PID) + else if (handle->dump->pid == MM_BACKTRACE_FREE_PID) { - info->aordblks++; - info->uordblks += nodesize; + handle->info->aordblks++; + handle->info->uordblks += nodesize; } } @@ -153,18 +166,23 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info) * ****************************************************************************/ -int mm_mallinfo_task(FAR struct mm_heap_s *heap, - FAR struct mallinfo_task *info) +struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump) { - DEBUGASSERT(info); - - info->uordblks = 0; - info->aordblks = 0; + struct mm_mallinfo_handler_s handle; + struct mallinfo_task info = + { + 0, 0 + }; #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 - mempool_multiple_info_task(heap->mm_mpool, info); + + info = mempool_multiple_info_task(heap->mm_mpool, dump); #endif - mm_foreach(heap, mallinfo_task_handler, info); - return OK; + handle.dump = dump; + handle.info = &info; + mm_foreach(heap, mallinfo_task_handler, &handle); + + return info; } diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index 63eb025c7d..1531016dc8 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -79,9 +79,12 @@ static void free_delaylist(FAR struct mm_heap_s *heap) void mm_dump_handler(FAR struct tcb_s *tcb, FAR void *arg) { struct mallinfo_task info; + struct mm_memdump_s dump; - info.pid = tcb->pid; - mm_mallinfo_task(arg, &info); + dump.pid = tcb->pid; + dump.seqmin = 0; + dump.seqmax = ULONG_MAX; + info = mm_mallinfo_task(arg, &dump); mwarn("pid:%5d, used:%10d, nused:%10d\n", tcb->pid, info.uordblks, info.aordblks); } diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c index feb87b5b92..874016cf2a 100644 --- a/mm/mm_heap/mm_memdump.c +++ b/mm/mm_heap/mm_memdump.c @@ -53,16 +53,17 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) { - pid_t pid = *(FAR pid_t *)arg; + FAR const struct mm_memdump_s *dump = arg; size_t nodesize = SIZEOF_MM_NODE(node); if ((node->size & MM_ALLOC_BIT) != 0) { DEBUGASSERT(nodesize >= SIZEOF_MM_ALLOCNODE); #if CONFIG_MM_BACKTRACE < 0 - if (pid == MM_BACKTRACE_ALLOC_PID) + if (dump->pid == MM_BACKTRACE_ALLOC_PID) #else - if (pid == MM_BACKTRACE_ALLOC_PID || node->pid == pid) + if ((dump->pid == MM_BACKTRACE_ALLOC_PID || node->pid == dump->pid) && + node->seqno >= dump->seqmin && node->seqno <= dump->seqmax) #endif { #if CONFIG_MM_BACKTRACE < 0 @@ -86,8 +87,9 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) } # endif - syslog(LOG_INFO, "%6d%12zu%*p%s\n", - (int)node->pid, nodesize, MM_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n", + (int)node->pid, nodesize, node->seqno, + MM_PTR_FMT_WIDTH, ((FAR char *)node + SIZEOF_MM_ALLOCNODE), buf); #endif } @@ -105,7 +107,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) SIZEOF_MM_NODE(fnode->flink) == 0 || SIZEOF_MM_NODE(fnode->flink) >= nodesize); - if (pid <= MM_BACKTRACE_FREE_PID) + if (dump->pid <= MM_BACKTRACE_FREE_PID) { syslog(LOG_INFO, "%12zu%*p\n", nodesize, MM_PTR_FMT_WIDTH, @@ -129,18 +131,19 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) * than or equal to 0, will dump pid allocated node and output backtrace. ****************************************************************************/ -void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) +void mm_memdump(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump) { struct mallinfo_task info; - if (pid >= -1) + if (dump->pid >= -1) { syslog(LOG_INFO, "Dump all used memory node info:\n"); #if CONFIG_MM_BACKTRACE < 0 syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address"); #else - syslog(LOG_INFO, "%6s%12s%*s %s\n", "PID", "Size", MM_PTR_FMT_WIDTH, - "Address", "Backtrace"); + syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence", + MM_PTR_FMT_WIDTH, "Address", "Backtrace"); #endif } else @@ -150,12 +153,12 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) } #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 - mempool_multiple_memdump(heap->mm_mpool, pid); + mempool_multiple_memdump(heap->mm_mpool, dump); #endif - mm_foreach(heap, memdump_handler, &pid); + mm_foreach(heap, memdump_handler, (FAR void *)dump); + + info = mm_mallinfo_task(heap, dump); - info.pid = pid; - mm_mallinfo_task(heap, &info); syslog(LOG_INFO, "%12s%12s\n", "Total Blks", "Total Size"); syslog(LOG_INFO, "%12d%12d\n", info.aordblks, info.uordblks); } diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index 93811f3eef..2a580bae4e 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -110,23 +110,23 @@ struct mm_heap_s #endif }; -struct memdump_info_s -{ - pid_t pid; - int blks; - int size; -}; - #if CONFIG_MM_BACKTRACE >= 0 struct memdump_backtrace_s { pid_t pid; /* The pid for caller */ + unsigned long seqno; /* The sequence of memory malloc */ #if CONFIG_MM_BACKTRACE > 0 FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */ #endif }; #endif +struct mm_mallinfo_handler_s +{ + FAR const struct mm_memdump_s *dump; + FAR struct mallinfo_task *info; +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -145,6 +145,7 @@ static void memdump_backtrace(FAR struct mm_heap_s *heap, # endif dump->pid = _SCHED_GETTID(); + dump->seqno = g_mm_seqno++; # if CONFIG_MM_BACKTRACE > 0 tcb = nxsched_get_tcb(dump->pid); if (heap->mm_procfs.backtrace || @@ -282,27 +283,32 @@ static void mallinfo_task_handler(FAR void *ptr, size_t size, int used, { #if CONFIG_MM_BACKTRACE >= 0 FAR struct memdump_backtrace_s *dump; - FAR struct mallinfo_task *info = user; +#endif + FAR struct mm_mallinfo_handler_s *handler = user; +#if CONFIG_MM_BACKTRACE >= 0 size -= sizeof(struct memdump_backtrace_s); dump = ptr + size; if (used) { #if CONFIG_MM_BACKTRACE < 0 - if (info->pid = MM_BACKTRACE_ALLOC_PID) + if (handler->dump->pid = MM_BACKTRACE_ALLOC_PID) #else - if (info->pid == MM_BACKTRACE_ALLOC_PID || info->pid == dump->pid) + if ((handler->dump->pid == MM_BACKTRACE_ALLOC_PID || + handler->dump->pid == dump->pid) && + dump->seqno >= handler->dump->seqmin && + dump->seqno <= handler->dump->seqmax) #endif { - info->aordblks++; - info->uordblks += size; + handler->info->aordblks++; + handler->info->uordblks += size; } } - else if (info->pid == MM_BACKTRACE_FREE_PID) + else if (handler->dump->pid == MM_BACKTRACE_FREE_PID) { - info->aordblks++; - info->uordblks += size; + handler->info->aordblks++; + handler->info->uordblks += size; } #endif } @@ -393,12 +399,12 @@ static void mm_unlock(FAR struct mm_heap_s *heap) static void memdump_handler(FAR void *ptr, size_t size, int used, FAR void *user) { - pid_t pid = *(FAR pid_t *)user; + FAR const struct mm_memdump_s *dump = user; #if CONFIG_MM_BACKTRACE >= 0 - FAR struct memdump_backtrace_s *dump; + FAR struct memdump_backtrace_s *bt; size -= sizeof(struct memdump_backtrace_s); - dump = ptr + size; + bt = ptr + size; #endif if (used) @@ -406,7 +412,10 @@ static void memdump_handler(FAR void *ptr, size_t size, int used, #if CONFIG_MM_BACKTRACE < 0 if (pid == MM_BACKTRACE_ALLOC_PID) #else - if (pid == MM_BACKTRACE_ALLOC_PID || dump->pid == pid) + if ((dump->pid == MM_BACKTRACE_ALLOC_PID || + bt->pid == dump->pid) && + bt->seqno >= dump->seqmin && + bt->seqno <= dump->seqmax) #endif { #if CONFIG_MM_BACKTRACE < 0 @@ -428,13 +437,13 @@ static void memdump_handler(FAR void *ptr, size_t size, int used, } # endif - syslog(LOG_INFO, "%6d%12zu%*p%s\n", - (int)dump->pid, size, MM_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n", + (int)bt->pid, size, bt->seqno, MM_PTR_FMT_WIDTH, ptr, buf); #endif } } - else if (pid <= MM_BACKTRACE_FREE_PID) + else if (dump->pid <= MM_BACKTRACE_FREE_PID) { syslog(LOG_INFO, "%12zu%*p\n", size, MM_PTR_FMT_WIDTH, ptr); } @@ -877,23 +886,27 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info) return OK; } -int mm_mallinfo_task(FAR struct mm_heap_s *heap, - FAR struct mallinfo_task *info) +struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump) { + struct mm_mallinfo_handler_s handle; + struct mallinfo_task info = + { + 0, 0 + }; + #if CONFIG_MM_REGIONS > 1 int region; #else #define region 0 #endif - DEBUGASSERT(info); - info->uordblks = 0; - info->aordblks = 0; - #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 - mempool_multiple_info_task(heap->mm_mpool, info); + info = mempool_multiple_info_task(heap->mm_mpool, dump); #endif + handle.dump = dump; + handle.info = &info; #if CONFIG_MM_REGIONS > 1 for (region = 0; region < heap->mm_nregions; region++) #endif @@ -902,12 +915,12 @@ int mm_mallinfo_task(FAR struct mm_heap_s *heap, DEBUGVERIFY(mm_lock(heap)); tlsf_walk_pool(heap->mm_heapstart[region], - mallinfo_task_handler, info); + mallinfo_task_handler, &handle); mm_unlock(heap); } #undef region - return OK; + return info; } /**************************************************************************** @@ -921,7 +934,8 @@ int mm_mallinfo_task(FAR struct mm_heap_s *heap, * than or equal to 0, will dump pid allocated node and output backtrace. ****************************************************************************/ -void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) +void mm_memdump(FAR struct mm_heap_s *heap, + FAR const struct mm_memdump_s *dump) { #if CONFIG_MM_REGIONS > 1 int region; @@ -930,14 +944,14 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) #endif struct mallinfo_task info; - if (pid >= MM_BACKTRACE_ALLOC_PID) + if (dump->pid >= MM_BACKTRACE_ALLOC_PID) { syslog(LOG_INFO, "Dump all used memory node info:\n"); #if CONFIG_MM_BACKTRACE < 0 syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address"); #else - syslog(LOG_INFO, "%6s%12s%*s %s\n", "PID", "Size", MM_PTR_FMT_WIDTH, - "Address", "Backtrace"); + syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence", + MM_PTR_FMT_WIDTH, "Address", "Backtrace"); #endif } else @@ -947,7 +961,7 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) } #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0 - mempool_multiple_memdump(heap->mm_mpool, pid); + mempool_multiple_memdump(heap->mm_mpool, dump); #endif #if CONFIG_MM_REGIONS > 1 @@ -956,13 +970,12 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid) { DEBUGVERIFY(mm_lock(heap)); tlsf_walk_pool(heap->mm_heapstart[region], - memdump_handler, &pid); + memdump_handler, (FAR void *)dump); mm_unlock(heap); } #undef region - info.pid = pid; - mm_mallinfo_task(heap, &info); + info = mm_mallinfo_task(heap, dump); syslog(LOG_INFO, "%12s%12s\n", "Total Blks", "Total Size"); syslog(LOG_INFO, "%12d%12d\n", info.aordblks, info.uordblks); } diff --git a/mm/umm_heap/umm_mallinfo.c b/mm/umm_heap/umm_mallinfo.c index 8418d1a853..51c65afa0d 100644 --- a/mm/umm_heap/umm_mallinfo.c +++ b/mm/umm_heap/umm_mallinfo.c @@ -59,11 +59,7 @@ struct mallinfo mallinfo(void) * ****************************************************************************/ -struct mallinfo_task mallinfo_task(pid_t pid) +struct mallinfo_task mallinfo_task(FAR const struct mm_memdump_s *dump) { - struct mallinfo_task info; - - info.pid = pid; - mm_mallinfo_task(USR_HEAP, &info); - return info; + return mm_mallinfo_task(USR_HEAP, dump); } diff --git a/mm/umm_heap/umm_memdump.c b/mm/umm_heap/umm_memdump.c index 539b38d0aa..138d038edd 100644 --- a/mm/umm_heap/umm_memdump.c +++ b/mm/umm_heap/umm_memdump.c @@ -27,6 +27,14 @@ #include "umm_heap/umm_heap.h" +/**************************************************************************** + * Public data + ****************************************************************************/ + +#if CONFIG_MM_BACKTRACE >= 0 +unsigned long g_mm_seqno; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -39,7 +47,7 @@ * ****************************************************************************/ -void umm_memdump(pid_t pid) +void umm_memdump(FAR const struct mm_memdump_s *dump) { - mm_memdump(USR_HEAP, pid); + mm_memdump(USR_HEAP, dump); }