note: add memory tracing event support

Record all memory allocation and release, save to ram, used to analyze memory allocation rate and memory usage
Its absolute value is not trustworthy because the memory will be allocated in thread A and released in thread B

 netinit-5   [0]   0.105984392: tracing_mark_write: C|5|Heap Usage|96|free: heap: 0x606000000020 size:24, address: 0x603000000370
 netinit-5   [0]   0.105996874: tracing_mark_write: C|5|Heap Usage|24|free: heap: 0x606000000020 size:72, address: 0x6070000008e0
nsh_main-4   [0]   3.825169408: tracing_mark_write: C|4|Heap Usage|2177665|free: heap: 0x606000000020 size:424, address: 0x614000000840
nsh_main-4   [0]   3.825228525: tracing_mark_write: C|4|Heap Usage|14977|free: heap: 0x606000000020 size:2162688, address: 0x7f80a639f800
nsh_main-4   [0]   3.825298789: tracing_mark_write: C|4|Heap Usage|15189|malloc: heap: 0x606000000020 size:20, address: 0x6030000003a0

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
yinshengkai
2023-11-14 15:50:52 +08:00
committed by Xiang Xiao
parent 9762ddee6e
commit 79eab8783f
11 changed files with 271 additions and 57 deletions
+32 -17
View File
@@ -42,6 +42,7 @@
#include <nuttx/mm/mm.h>
#include <nuttx/mm/kasan.h>
#include <nuttx/mm/mempool.h>
#include <nuttx/sched_note.h>
#include "tlsf/tlsf.h"
@@ -492,15 +493,16 @@ static void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem,
{
if (mm_lock(heap) == 0)
{
size_t size = mm_malloc_size(heap, mem);
#ifdef CONFIG_MM_FILL_ALLOCATIONS
memset(mem, MM_FREE_MAGIC, mm_malloc_size(heap, mem));
memset(mem, MM_FREE_MAGIC, size);
#endif
kasan_poison(mem, mm_malloc_size(heap, mem));
kasan_poison(mem, size);
/* Update heap statistics */
heap->mm_curused -= mm_malloc_size(heap, mem);
heap->mm_curused -= size;
/* Pass, return to the tlsf pool */
@@ -510,6 +512,7 @@ static void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem,
}
else
{
sched_note_heap(false, heap, mem, size);
tlsf_free(heap->mm_tlsf, mem);
}
@@ -1134,6 +1137,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
{
size_t nodesize;
FAR void *ret;
/* In case of zero-length allocations allocate the minimum size object */
@@ -1168,7 +1172,8 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
ret = tlsf_malloc(heap->mm_tlsf, size);
#endif
heap->mm_curused += mm_malloc_size(heap, ret);
nodesize = mm_malloc_size(heap, ret);
heap->mm_curused += nodesize;
if (heap->mm_curused > heap->mm_maxused)
{
heap->mm_maxused = heap->mm_curused;
@@ -1179,11 +1184,13 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
if (ret)
{
#if CONFIG_MM_BACKTRACE >= 0
FAR struct memdump_backtrace_s *buf = ret + mm_malloc_size(heap, ret);
FAR struct memdump_backtrace_s *buf = ret + nodesize;
memdump_backtrace(heap, buf);
#endif
ret = kasan_unpoison(ret, mm_malloc_size(heap, ret));
ret = kasan_unpoison(ret, nodesize);
sched_note_heap(true, heap, ret, nodesize);
#ifdef CONFIG_MM_FILL_ALLOCATIONS
memset(ret, 0xaa, nodesize);
@@ -1218,6 +1225,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
size_t size)
{
size_t nodesize;
FAR void *ret;
#ifdef CONFIG_MM_HEAP_MEMPOOL
@@ -1245,7 +1253,8 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
ret = tlsf_memalign(heap->mm_tlsf, alignment, size);
#endif
heap->mm_curused += mm_malloc_size(heap, ret);
nodesize = mm_malloc_size(heap, ret);
heap->mm_curused += nodesize;
if (heap->mm_curused > heap->mm_maxused)
{
heap->mm_maxused = heap->mm_curused;
@@ -1256,11 +1265,12 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
if (ret)
{
#if CONFIG_MM_BACKTRACE >= 0
FAR struct memdump_backtrace_s *buf = ret + mm_malloc_size(heap, ret);
FAR struct memdump_backtrace_s *buf = ret + nodesize;
memdump_backtrace(heap, buf);
#endif
ret = kasan_unpoison(ret, mm_malloc_size(heap, ret));
ret = kasan_unpoison(ret, nodesize);
sched_note_heap(true, heap, ret, nodesize);
}
#if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0
@@ -1302,6 +1312,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
size_t size)
{
FAR void *newmem;
size_t oldsize;
size_t newsize;
/* If oldmem is NULL, then realloc is equivalent to malloc */
@@ -1361,7 +1373,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
/* Allocate from the tlsf pool */
DEBUGVERIFY(mm_lock(heap));
heap->mm_curused -= mm_malloc_size(heap, oldmem);
oldsize = mm_malloc_size(heap, oldmem);
heap->mm_curused -= oldsize;
#if CONFIG_MM_BACKTRACE >= 0
newmem = tlsf_realloc(heap->mm_tlsf, oldmem, size +
sizeof(struct memdump_backtrace_s));
@@ -1369,7 +1382,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
newmem = tlsf_realloc(heap->mm_tlsf, oldmem, size);
#endif
heap->mm_curused += mm_malloc_size(heap, newmem ? newmem : oldmem);
newsize = mm_malloc_size(heap, newmem);
heap->mm_curused += newmem ? newsize : oldsize;
if (heap->mm_curused > heap->mm_maxused)
{
heap->mm_maxused = heap->mm_curused;
@@ -1377,20 +1391,21 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
mm_unlock(heap);
#if CONFIG_MM_BACKTRACE >= 0
if (newmem)
{
FAR struct memdump_backtrace_s *buf =
newmem + mm_malloc_size(heap, newmem);
#if CONFIG_MM_BACKTRACE >= 0
FAR struct memdump_backtrace_s *buf = newmem + newsize;
memdump_backtrace(heap, buf);
}
#endif
sched_note_heap(false, heap, oldmem, oldsize);
sched_note_heap(true, heap, newmem, newsize);
}
#if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0
/* Try again after free delay list */
if (newmem == NULL && free_delaylist(heap, true))
else if (free_delaylist(heap, true))
{
return mm_realloc(heap, oldmem, size);
}