Skip to content

Commit

Permalink
os/drivers, os/mm: Modify mm_manage_allocfail to print alignment
Browse files Browse the repository at this point in the history
Modify mm_manage_allocfail API to print alignment value for which
the allocation has failed. Also, print the largest available free
node with the required alignment.

Sample output:

Memalign case
=================================================================
mm_manage_alloc_fail: Allocation failed from user heap.
mm_manage_alloc_fail:  - requested size 524288
mm_manage_alloc_fail:  - requested alignment 131072
mm_manage_alloc_fail:  - caller address = 0x0e16d1c1
mm_manage_alloc_fail:  - largest un-aligned free size : 655344
mm_manage_alloc_fail:  - largest algined free size : 524272
mm_manage_alloc_fail:  - total free size   : 1524896
=================================================================

Malloc case
=================================================================
mm_manage_alloc_fail: Allocation failed from user heap.
mm_manage_alloc_fail:  - requested size 524288
mm_manage_alloc_fail:  - caller address = 0x0e16d1bd
mm_manage_alloc_fail:  - largest free size : 476208
mm_manage_alloc_fail:  - total free size   : 476288
=================================================================

Signed-off-by: Kishore S N <[email protected]>
  • Loading branch information
kishore-sn committed Jan 6, 2025
1 parent 4c258bd commit df50049
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 52 deletions.
2 changes: 1 addition & 1 deletion os/drivers/memory/mminfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static int mminfo_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
#ifdef CONFIG_APP_BINARY_SEPARATION
case MMINFOIOC_MNG_ALLOCFAIL:
/* There is a single heap for user. So start and end indexes of heap are always 0. */
mm_manage_alloc_fail(BASE_HEAP, 0, 0, ((struct mm_alloc_fail_s *)arg)->size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, 0, 0, ((struct mm_alloc_fail_s *)arg)->size, ((struct mm_alloc_fail_s *)arg)->align, USER_HEAP
#if defined(CONFIG_DEBUG_MM_HEAPINFO)
, ((struct mm_alloc_fail_s *)arg)->caller
#endif
Expand Down
26 changes: 14 additions & 12 deletions os/include/tinyara/mm/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ extern struct heapinfo_group_info_s group_info[HEAPINFO_THREAD_NUM];

struct mm_alloc_fail_s {
uint32_t size;
uint32_t align;
#ifdef CONFIG_DEBUG_MM_HEAPINFO
mmaddress_t caller;
#endif
Expand Down Expand Up @@ -690,6 +691,7 @@ 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);
int mm_mallinfo_aligned(FAR struct mm_heap_s *heap, FAR struct mallinfo *info, size_t align);

/* Functions contained in kmm_mallinfo.c ************************************/

Expand Down Expand Up @@ -784,26 +786,26 @@ int mm_check_heap_corruption(struct mm_heap_s *heap);
/* Function to manage the memory allocation failure case. */
#if defined(CONFIG_APP_BINARY_SEPARATION) && !defined(__KERNEL__)
#ifdef CONFIG_DEBUG_MM_HEAPINFO
void mm_ioctl_alloc_fail(size_t size, mmaddress_t caller);
#define mm_manage_alloc_fail(h, b, e, s, t, c) do { \
(void)h; \
(void)b; \
(void)e; \
(void)t; \
mm_ioctl_alloc_fail(s, c); \
} while (0)
void mm_ioctl_alloc_fail(size_t size, size_t align, mmaddress_t caller);
#define mm_manage_alloc_fail(h, b, e, s, a, t, c) do { \
(void)h; \
(void)b; \
(void)e; \
(void)t; \
mm_ioctl_alloc_fail(s, a, c); \
} while (0)
#else
void mm_ioctl_alloc_fail(size_t size);
#define mm_manage_alloc_fail(h, b, e, s, t) do { \
void mm_ioctl_alloc_fail(size_t size, size_t align);
#define mm_manage_alloc_fail(h, b, e, s, a, t) do { \
(void)h; \
(void)b; \
(void)e; \
(void)t; \
mm_ioctl_alloc_fail(s); \
mm_ioctl_alloc_fail(s, a); \
} while (0)
#endif
#else
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, int heap_type
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, size_t align, int heap_type
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, mmaddress_t caller
#endif
Expand Down
4 changes: 2 additions & 2 deletions os/mm/kmm_heap/kmm_calloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void *kheap_calloc(size_t n, size_t elem_size)
}
}

mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, n * elem_size, KERNEL_HEAP
mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, n * elem_size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, retaddr
#endif
Expand Down Expand Up @@ -137,7 +137,7 @@ void *kmm_calloc_at(int heap_index, size_t n, size_t elem_size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, n * elem_size, KERNEL_HEAP
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, n * elem_size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
4 changes: 2 additions & 2 deletions os/mm/kmm_heap/kmm_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static void *kheap_malloc(size_t size)
}
}

mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, KERNEL_HEAP
mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -153,7 +153,7 @@ void *kmm_malloc_at(int heap_index, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, KERNEL_HEAP
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
4 changes: 2 additions & 2 deletions os/mm/kmm_heap/kmm_memalign.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void *kmm_memalign_at(int heap_index, size_t alignment, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, KERNEL_HEAP
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, alignment, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -161,7 +161,7 @@ FAR void *kmm_memalign(size_t alignment, size_t size)
}
}

mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, KERNEL_HEAP
mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, alignment, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
4 changes: 2 additions & 2 deletions os/mm/kmm_heap/kmm_realloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void *kmm_realloc_at(int heap_index, void *oldmem, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, KERNEL_HEAP
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -184,7 +184,7 @@ FAR void *kmm_realloc(FAR void *oldmem, size_t newsize)
}
}

mm_manage_alloc_fail(kheap_new, HEAP_START_IDX, HEAP_END_IDX, newsize, KERNEL_HEAP
mm_manage_alloc_fail(kheap_new, HEAP_START_IDX, HEAP_END_IDX, newsize, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
4 changes: 2 additions & 2 deletions os/mm/kmm_heap/kmm_zalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void *kmm_zalloc_at(int heap_index, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, KERNEL_HEAP
mm_manage_alloc_fail(&kheap[heap_index], heap_index, heap_index, size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -153,7 +153,7 @@ FAR void *kmm_zalloc(size_t size)
return ret;
}
}
mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, KERNEL_HEAP
mm_manage_alloc_fail(kheap, HEAP_START_IDX, HEAP_END_IDX, size, 0, KERNEL_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
39 changes: 34 additions & 5 deletions os/mm/mm_heap/mm_mallinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,21 @@
/****************************************************************************
* Private Functions
****************************************************************************/

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: mm_mallinfo
* Name: mm_mallinfo_aligned
*
* Description:
* mallinfo returns a copy of updated current heap information.
* In this case, the maxordblk will contain the size of largest heap node with
* the requested align value.
*
****************************************************************************/

int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
int mm_mallinfo_aligned(FAR struct mm_heap_s *heap, FAR struct mallinfo *info, size_t align)
{
struct mm_allocnode_s *node;
size_t mxordblk = 0;
Expand Down Expand Up @@ -123,8 +125,22 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
} else {
ordblks++;
fordblks += node->size;
if (node->size > mxordblk) {
mxordblk = node->size;
if (align) {
/* If non zero value is passed for align, then,
* - First, align the node to the align value
* - Check the remain size and update the maxordblk
* - In this case, mxordblk will give the largest free node aligned to the given align value
*/
size_t mask = align - 1;
struct mm_allocnode_s *alignednode = (FAR struct mm_allocnode_s *)(((size_t)node + SIZEOF_MM_ALLOCNODE + mask) & ~mask);
int remsize = node->size - ((uint32_t)alignednode - (uint32_t)node);
if (remsize > 0 && remsize > mxordblk) {
mxordblk = remsize;
}
} else {
if (node->size > mxordblk) {
mxordblk = node->size;
}
}
}
}
Expand Down Expand Up @@ -154,3 +170,16 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
#endif
return OK;
}

/****************************************************************************
* Name: mm_mallinfo
*
* Description:
* mallinfo returns a copy of updated current heap information.
*
****************************************************************************/

int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
{
return mm_mallinfo_aligned(heap, info, 0);
}
29 changes: 21 additions & 8 deletions os/mm/mm_heap/mm_manage_allocfail.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@

#if defined(CONFIG_APP_BINARY_SEPARATION) && !defined(__KERNEL__)
#ifdef CONFIG_DEBUG_MM_HEAPINFO
void mm_ioctl_alloc_fail(size_t size, mmaddress_t caller)
void mm_ioctl_alloc_fail(size_t size, size_t align, mmaddress_t caller)
#else
void mm_ioctl_alloc_fail(size_t size)
void mm_ioctl_alloc_fail(size_t size, size_t align)
#endif
{
#ifdef CONFIG_DEBUG_MM_HEAPINFO
struct mm_alloc_fail_s arg = {size, caller};
struct mm_alloc_fail_s arg = {size, align, caller};
#else
struct mm_alloc_fail_s arg = {size};
struct mm_alloc_fail_s arg = {size, align};
#endif
int mmfd = open(MMINFO_DRVPATH, O_RDWR);
if (mmfd < 0) {
Expand All @@ -84,9 +84,9 @@ void mm_ioctl_alloc_fail(size_t size)
#else

#ifdef CONFIG_DEBUG_MM_HEAPINFO
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, int heap_type, mmaddress_t caller)
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, size_t align, int heap_type, mmaddress_t caller)
#else
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, int heap_type)
void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size_t size, size_t align, int heap_type)
#endif
{
irqstate_t flags = enter_critical_section();
Expand All @@ -105,12 +105,15 @@ void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size
mfdbg("mem leak task creation failed\n");
} else {
int status;
int ret = waitpid(mem_leak, &status, 0);
(void)waitpid(mem_leak, &status, 0);
}
#endif

mfdbg("Allocation failed from %s heap.\n", (heap_type == KERNEL_HEAP) ? KERNEL_STR : USER_STR);
mfdbg(" - requested size %u\n", size);
if (align) {
mfdbg(" - requested alignment %u\n", align);
}
#ifdef CONFIG_DEBUG_MM_HEAPINFO
mfdbg(" - caller address = 0x%08x\n", caller);
#endif
Expand All @@ -120,7 +123,17 @@ void mm_manage_alloc_fail(struct mm_heap_s *heap, int startidx, int endidx, size
for (int idx = startidx; idx <= endidx; idx++) {
mm_mallinfo(&heap[idx], &info);
}
mfdbg(" - largest free size : %d\n", info.mxordblk);

if (align) {
mfdbg(" - largest un-aligned free size : %d\n", info.mxordblk);
memset(&info, 0, sizeof(struct mallinfo));
for (int idx = startidx; idx <= endidx; idx++) {
mm_mallinfo_aligned(&heap[idx], &info, align);
}
mfdbg(" - largest algined free size : %d\n", info.mxordblk);
} else {
mfdbg(" - largest free size : %d\n", info.mxordblk);
}
mfdbg(" - total free size : %d\n", info.fordblks);

#ifdef CONFIG_MM_ASSERT_ON_FAIL
Expand Down
6 changes: 3 additions & 3 deletions os/mm/umm_heap/umm_calloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void *calloc_at(int heap_index, size_t n, size_t elem_size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, n * elem_size, USER_HEAP
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, n * elem_size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -148,7 +148,7 @@ static void *heap_calloc(size_t n, size_t elem_size, int s, int e)
return ret;
}
}
mm_manage_alloc_fail(BASE_HEAP, s, e, n * elem_size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, s, e, n * elem_size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -186,7 +186,7 @@ FAR void *calloc(size_t n, size_t elem_size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, n * elem_size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, n * elem_size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
6 changes: 3 additions & 3 deletions os/mm/umm_heap/umm_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void *malloc_at(int heap_index, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, USER_HEAP
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -169,7 +169,7 @@ static void *heap_malloc(size_t size, int s, int e)
}
}

mm_manage_alloc_fail(BASE_HEAP, s, e, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, s, e, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -242,7 +242,7 @@ FAR void *malloc(size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
6 changes: 3 additions & 3 deletions os/mm/umm_heap/umm_memalign.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void *memalign_at(int heap_index, size_t alignment, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, USER_HEAP
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, alignment, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -152,7 +152,7 @@ FAR void *memalign(size_t alignment, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, alignment, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand All @@ -173,7 +173,7 @@ FAR void *memalign(size_t alignment, size_t size)
}
}

mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, alignment, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
6 changes: 3 additions & 3 deletions os/mm/umm_heap/umm_realloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void *realloc_at(int heap_index, void *oldmem, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, USER_HEAP
mm_manage_alloc_fail(&BASE_HEAP[heap_index], heap_index, heap_index, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -159,7 +159,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
#endif
);
if (ret == NULL) {
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down Expand Up @@ -204,7 +204,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
}
}

mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, USER_HEAP
mm_manage_alloc_fail(BASE_HEAP, HEAP_START_IDX, HEAP_END_IDX, size, 0, USER_HEAP
#ifdef CONFIG_DEBUG_MM_HEAPINFO
, caller_retaddr
#endif
Expand Down
Loading

0 comments on commit df50049

Please sign in to comment.