From 49d1b4198f5e9df0b2b860cc66c2a929b88ae1c8 Mon Sep 17 00:00:00 2001 From: yinshengkai Date: Wed, 24 Jan 2024 23:33:02 +0800 Subject: [PATCH] mm: add memory pressure notification support Add mm_heap_free interface to pass remaining memory to memory pressure Signed-off-by: yinshengkai --- arch/sim/src/sim/sim_heap.c | 12 ++++++++++++ fs/procfs/fs_procfspressure.c | 22 ++++++++++++++-------- include/nuttx/mm/mm.h | 2 ++ mm/mm_heap/mm_mallinfo.c | 13 +++++++++++++ mm/tlsf/mm_tlsf.c | 13 +++++++++++++ mm/umm_heap/umm_calloc.c | 13 ++++++++++++- mm/umm_heap/umm_malloc.c | 4 ++++ mm/umm_heap/umm_memalign.c | 4 ++++ mm/umm_heap/umm_realloc.c | 4 ++++ mm/umm_heap/umm_zalloc.c | 4 ++++ 10 files changed, 82 insertions(+), 9 deletions(-) diff --git a/arch/sim/src/sim/sim_heap.c b/arch/sim/src/sim/sim_heap.c index f37eb36183..8257af7a6d 100644 --- a/arch/sim/src/sim/sim_heap.c +++ b/arch/sim/src/sim/sim_heap.c @@ -611,6 +611,18 @@ void up_allocate_heap(void **heap_start, size_t *heap_size) *heap_size = 0; } +/**************************************************************************** + * Name: mm_heapfree + * + * Description: + * Return the total free size (in bytes) in the heap + * + ****************************************************************************/ + +size_t mm_heapfree(struct mm_heap_s *heap) +{ + return SIZE_MAX; +} #else /* CONFIG_MM_CUSTOMIZE_MANAGER */ void up_allocate_heap(void **heap_start, size_t *heap_size) diff --git a/fs/procfs/fs_procfspressure.c b/fs/procfs/fs_procfspressure.c index fa9f2c4bc5..9b2dd582cb 100644 --- a/fs/procfs/fs_procfspressure.c +++ b/fs/procfs/fs_procfspressure.c @@ -159,19 +159,25 @@ static ssize_t pressure_read(FAR struct file *filep, FAR char *buffer, { char buf[128]; uint32_t flags; + size_t remain; + off_t offset; ssize_t ret; - flags = spin_lock_irqsave(&g_pressure_lock); - ret = procfs_snprintf(buf, sizeof(buf), "remaining %zu\n", - g_remaining); + flags = spin_lock_irqsave(&g_pressure_lock); + remain = g_remaining; spin_unlock_irqrestore(&g_pressure_lock, flags); + ret = procfs_snprintf(buf, sizeof(buf), "remaining %zu\n", remain); + if (ret > buflen) { return -ENOMEM; } - memcpy(buffer, buf, ret); + offset = filep->f_pos; + ret = procfs_memcpy(buf, ret, buffer, buflen, &offset); + + filep->f_pos += ret; return ret; } @@ -216,9 +222,9 @@ static ssize_t pressure_write(FAR struct file *filep, FAR const char *buffer, /* We should trigger the first event immediately */ - priv->lasttick = CLOCK_MAX; + priv->lasttick = CLOCK_MAX; priv->threshold = threshold; - priv->interval = interval; + priv->interval = interval; spin_unlock_irqrestore(&g_pressure_lock, flags); return buflen; } @@ -365,7 +371,7 @@ static int pressure_rewinddir(FAR struct fs_dirent_s *dir) FAR struct procfs_dir_priv_s *level; DEBUGASSERT(dir); - level = (FAR struct procfs_dir_priv_s *)dir; + level = (FAR struct procfs_dir_priv_s *)dir; level->index = 0; return OK; } @@ -411,7 +417,7 @@ void mm_notify_pressure(size_t remaining) FAR dq_entry_t *tmp; uint32_t flags; - flags = spin_lock_irqsave(&g_pressure_lock); + flags = spin_lock_irqsave(&g_pressure_lock); g_remaining = remaining; dq_for_every_safe(&g_pressure_memory_queue, entry, tmp) { diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h index 05149705ee..0f434afa3c 100644 --- a/include/nuttx/mm/mm.h +++ b/include/nuttx/mm/mm.h @@ -389,6 +389,8 @@ struct mallinfo mm_mallinfo(FAR struct mm_heap_s *heap); struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, FAR const struct malltask *task); +size_t mm_heapfree(FAR struct mm_heap_s *heap); + /* Functions contained in kmm_mallinfo.c ************************************/ #ifdef CONFIG_MM_KERNEL_HEAP diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c index 693909202a..90d643ace8 100644 --- a/mm/mm_heap/mm_mallinfo.c +++ b/mm/mm_heap/mm_mallinfo.c @@ -187,3 +187,16 @@ struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap, return info; } + +/**************************************************************************** + * Name: mm_heapfree + * + * Description: + * Return the total free size (in bytes) in the heap + * + ****************************************************************************/ + +size_t mm_heapfree(FAR struct mm_heap_s *heap) +{ + return heap->mm_heapsize - heap->mm_curused; +} diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index 98f2566bf9..cbb212b688 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -1463,3 +1463,16 @@ void mm_free_delaylist(FAR struct mm_heap_s *heap) free_delaylist(heap, true); } } + +/**************************************************************************** + * Name: mm_heapfree + * + * Description: + * Return the total free size (in bytes) in the heap + * + ****************************************************************************/ + +size_t mm_heapfree(FAR struct mm_heap_s *heap) +{ + return heap->mm_heapsize - heap->mm_curused; +} diff --git a/mm/umm_heap/umm_calloc.c b/mm/umm_heap/umm_calloc.c index 66205b3d00..ee698d1f51 100644 --- a/mm/umm_heap/umm_calloc.c +++ b/mm/umm_heap/umm_calloc.c @@ -70,6 +70,17 @@ FAR void *calloc(size_t n, size_t elem_size) #else /* Use mm_calloc() because it implements the clear */ - return mm_calloc(USR_HEAP, n, elem_size); + FAR void *mem = mm_calloc(USR_HEAP, n, elem_size); + + if (mem == NULL) + { + set_errno(ENOMEM); + } + else + { + mm_notify_pressure(mm_heapfree(USR_HEAP)); + } + + return mem; #endif } diff --git a/mm/umm_heap/umm_malloc.c b/mm/umm_heap/umm_malloc.c index 9727596b40..3fa63eb59a 100644 --- a/mm/umm_heap/umm_malloc.c +++ b/mm/umm_heap/umm_malloc.c @@ -66,6 +66,10 @@ FAR void *malloc(size_t size) { set_errno(ENOMEM); } + else + { + mm_notify_pressure(mm_heapfree(USR_HEAP)); + } return ret; #endif diff --git a/mm/umm_heap/umm_memalign.c b/mm/umm_heap/umm_memalign.c index c5d9236e12..9338bb6abf 100644 --- a/mm/umm_heap/umm_memalign.c +++ b/mm/umm_heap/umm_memalign.c @@ -93,6 +93,10 @@ FAR void *memalign(size_t alignment, size_t size) { set_errno(ENOMEM); } + else + { + mm_notify_pressure(mm_heapfree(USR_HEAP)); + } return ret; #endif diff --git a/mm/umm_heap/umm_realloc.c b/mm/umm_heap/umm_realloc.c index 80580f8b93..d31b8de7a0 100644 --- a/mm/umm_heap/umm_realloc.c +++ b/mm/umm_heap/umm_realloc.c @@ -95,6 +95,10 @@ FAR void *realloc(FAR void *oldmem, size_t size) { set_errno(ENOMEM); } + else + { + mm_notify_pressure(mm_heapfree(USR_HEAP)); + } return ret; #endif diff --git a/mm/umm_heap/umm_zalloc.c b/mm/umm_heap/umm_zalloc.c index 7aa95e853f..69ec6a2c9d 100644 --- a/mm/umm_heap/umm_zalloc.c +++ b/mm/umm_heap/umm_zalloc.c @@ -72,6 +72,10 @@ FAR void *zalloc(size_t size) { set_errno(ENOMEM); } + else + { + mm_notify_pressure(mm_heapfree(USR_HEAP)); + } return ret; #endif