You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/18 06:12:57 UTC

[nuttx] 06/06: Optimize multipe mempool memory space usage

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 632ed0d3a42241fdc7b7a01fa8cd60bf01b3560d
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Wed Nov 23 22:08:13 2022 +0800

    Optimize multipe mempool memory space usage
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 include/nuttx/mm/mempool.h    |  15 ++-
 mm/Kconfig                    |   2 +-
 mm/mempool/mempool.c          |   5 +-
 mm/mempool/mempool_multiple.c | 301 +++++++++++++++++++++++++++++++-----------
 mm/mm_heap/mm.h               |   5 -
 mm/mm_heap/mm_free.c          |   3 +-
 mm/mm_heap/mm_malloc_size.c   |  15 ++-
 mm/mm_heap/mm_realloc.c       |  24 +---
 mm/tlsf/mm_tlsf.c             |  39 ++----
 9 files changed, 264 insertions(+), 145 deletions(-)

diff --git a/include/nuttx/mm/mempool.h b/include/nuttx/mm/mempool.h
index 7b991292f1..7af6558728 100644
--- a/include/nuttx/mm/mempool.h
+++ b/include/nuttx/mm/mempool.h
@@ -354,10 +354,14 @@ FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
  * Input Parameters:
  *   mpool - The handle of multiple memory pool to be used.
  *   blk  - The pointer of memory block.
+ *
+ * Returned Value:
+ *   Zero on success; Negative number mean the block doesn't come from pool.
+ *
  ****************************************************************************/
 
-void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
-                           FAR void *blk);
+int mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
+                          FAR void *blk);
 
 /****************************************************************************
  * Name: mempool_multiple_alloc_size
@@ -370,12 +374,13 @@ void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
  *   blk  - The pointer of memory block.
  *
  * Returned Value:
- *   The size of memory block.
+ *   The size of memory block on success. Negative number mean the block
+ *   doesn't come from pool.
  *
  ****************************************************************************/
 
-size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
-                                   FAR void *blk);
+ssize_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
+                                    FAR void *blk);
 
 /****************************************************************************
  * Name: mempool_multiple_memalign
diff --git a/mm/Kconfig b/mm/Kconfig
index e47eda7d9c..8b572f142b 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -190,7 +190,7 @@ config MM_HEAP_MEMPOOL_THRESHOLD
 
 config MM_HEAP_MEMPOOL_EXPAND
 	int "The expand size for each mempool in multiple mempool"
-	default 1024
+	default 4096
 	depends on MM_HEAP_MEMPOOL_THRESHOLD != 0
 	---help---
 		This size describes the size of each expansion of each memory
diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c
index c64ab8dc2f..d1ee35caf2 100644
--- a/mm/mempool/mempool.c
+++ b/mm/mempool/mempool.c
@@ -38,9 +38,8 @@
 #  define MM_PTR_FMT_WIDTH 19
 #endif
 
-#ifndef ALIGN_UP
-#  define ALIGN_UP(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
-#endif
+#undef  ALIGN_UP
+#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
 
 /****************************************************************************
  * Private Types
diff --git a/mm/mempool/mempool_multiple.c b/mm/mempool/mempool_multiple.c
index 843964d0c8..d03b541f25 100644
--- a/mm/mempool/mempool_multiple.c
+++ b/mm/mempool/mempool_multiple.c
@@ -29,21 +29,36 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define SIZEOF_HEAD sizeof(FAR struct mempool_s *)
-#define MAX(a, b)   ((a) > (b) ? (a) : (b))
-#define MIN(a, b)   ((a) < (b) ? (a) : (b))
-#define ALIGN_BIT   (1 << 1)
+#define MIN(a, b)             ((a) < (b) ? (a) : (b))
+#undef  ALIGN_UP
+#define ALIGN_UP(x, a)        ((((size_t)x) + ((a) - 1)) & (~((a) - 1)))
+#undef  ALIGN_DOWN
+#define ALIGN_DOWN(x, a)      ((size_t)(x) & (~((a) - 1)))
 
-struct mempool_multiple_s
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct mpool_dict_s
 {
-  FAR struct mempool_s *   pools;      /* The memory pool array */
-  size_t                   npools;     /* The number of memory pool array elements */
+  FAR struct mempool_s *pool; /* Record pool when expanding */
+  FAR void             *addr; /* Record expand memary address */
+  size_t                size; /* Record expand memary size */
+};
 
-  FAR void                *arg;     /* This pointer is used to store the user's
-                                     * private data
-                                     */
-  mempool_multiple_alloc_t alloc;   /* The alloc function for mempool */
-  mempool_multiple_free_t  free;    /* The free function for mempool */
+struct mempool_multiple_s
+{
+  FAR struct mempool_s *   pools;       /* The memory pool array */
+  size_t                   npools;      /* The number of memory pool array elements */
+  size_t                   expandsize;  /* The number not will use it to init erery
+                                         * pool expandsize
+                                         */
+  size_t                   minpoolsize; /* The number is align for each memory pool */
+  FAR void                *arg;         /* This pointer is used to store the user's
+                                         * private data
+                                         */
+  mempool_multiple_alloc_t alloc;       /* The alloc function for mempool */
+  mempool_multiple_free_t  free;        /* The free function for mempool */
 
   /* This delta describes the relationship between the block size of each
    * mempool in multiple mempool by user initialized. It is automatically
@@ -53,6 +68,14 @@ struct mempool_multiple_s
    */
 
   size_t                   delta;
+
+  /* It is used to record the information recorded by the mempool during
+   * expansion, and find the mempool by adding an index
+   */
+
+  size_t                   dict_alloc;
+  size_t                   dict_used;
+  FAR struct mpool_dict_s *dict;
 };
 
 /****************************************************************************
@@ -75,6 +98,11 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
   if (mpool->delta != 0)
     {
       left = mpool->pools[0].blocksize;
+      if (left >= size)
+        {
+          return &mpool->pools[0];
+        }
+
       mid = (size - left + mpool->delta - 1) / mpool->delta;
       return mid < right ? &mpool->pools[mid] : NULL;
     }
@@ -100,6 +128,95 @@ mempool_multiple_find(FAR struct mempool_multiple_s *mpool, size_t size)
   return &mpool->pools[left];
 }
 
+static FAR void *mempool_multiple_alloc_callback(FAR struct mempool_s *pool,
+                                                 size_t size)
+{
+  FAR struct mempool_multiple_s *mpool = pool->priv;
+  FAR void *ret;
+
+  if (mpool->dict_used >= mpool->dict_alloc)
+    {
+      ret = mpool->alloc(mpool->arg, sizeof(uintptr_t),
+                         mpool->dict_alloc *
+                         sizeof(struct mpool_dict_s) * 2);
+      if (ret == NULL)
+        {
+          return NULL;
+        }
+
+      memcpy(ret, mpool->dict,
+             mpool->dict_alloc * sizeof(struct mpool_dict_s));
+      mpool->free(mpool->arg, mpool->dict);
+      mpool->dict = ret;
+      mpool->dict_alloc *= 2;
+    }
+
+  ret = mpool->alloc(mpool->arg, mpool->expandsize,
+                     mpool->minpoolsize + size);
+  if (ret == NULL)
+    {
+      return NULL;
+    }
+
+  mpool->dict[mpool->dict_used].pool = pool;
+  mpool->dict[mpool->dict_used].addr = ret;
+  mpool->dict[mpool->dict_used].size = mpool->minpoolsize + size;
+  *(FAR size_t *)ret = mpool->dict_used++;
+  return (FAR char *)ret + mpool->minpoolsize;
+}
+
+static void mempool_multiple_free_callback(FAR struct mempool_s *pool,
+                                           FAR void *addr)
+{
+  FAR struct mempool_multiple_s *mpool = pool->priv;
+
+  return mpool->free(mpool->arg, (FAR char *)addr - mpool->minpoolsize);
+}
+
+/****************************************************************************
+ * Name: mempool_multiple_get_dict
+ *
+ * Description:
+ *   Obtain the dict through mpool and blk
+ *
+ * Input Parameters:
+ *   mpool - The handle of the multiple memory pool to be used.
+ *   blk   - The pointer of memory block.
+ *
+ * Returned Value:
+ *   Address of the dict to be used or NULL is not find.
+ *
+ ****************************************************************************/
+
+static FAR struct mpool_dict_s *
+mempool_multiple_get_dict(FAR struct mempool_multiple_s *mpool,
+                          FAR void *blk)
+{
+  FAR void *addr;
+  size_t index;
+
+  if (mpool == NULL || blk == NULL)
+    {
+      return NULL;
+    }
+
+  addr = (FAR void *)ALIGN_DOWN(blk, mpool->expandsize);
+
+  index = *(FAR size_t *)addr;
+  if (index >= mpool->dict_used)
+    {
+      return NULL;
+    }
+
+  if (mpool->dict[index].addr != addr ||
+      blk - addr >= mpool->dict[index].size)
+    {
+      return NULL;
+    }
+
+  return &mpool->dict[index];
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -141,9 +258,31 @@ mempool_multiple_init(FAR const char *name,
 {
   FAR struct mempool_multiple_s *mpool;
   FAR struct mempool_s *pools;
+  size_t maxpoolszie;
+  size_t minpoolsize;
   int ret;
   int i;
 
+  if (expandsize & (expandsize - 1))
+    {
+      return NULL;
+    }
+
+  maxpoolszie = poolsize[0];
+  minpoolsize = poolsize[0];
+  for (i = 0; i < npools; i++)
+    {
+      if (maxpoolszie < poolsize[i])
+        {
+          maxpoolszie = poolsize[i];
+        }
+
+      if (minpoolsize > poolsize[i])
+        {
+          minpoolsize = poolsize[i];
+        }
+    }
+
   mpool = alloc(arg, sizeof(uintptr_t), sizeof(struct mempool_multiple_s));
   if (mpool == NULL)
     {
@@ -159,6 +298,8 @@ mempool_multiple_init(FAR const char *name,
 
   mpool->pools = pools;
   mpool->npools = npools;
+  mpool->expandsize = expandsize;
+  mpool->minpoolsize = minpoolsize;
   mpool->alloc = alloc;
   mpool->free = free;
   mpool->arg = arg;
@@ -166,17 +307,16 @@ mempool_multiple_init(FAR const char *name,
   for (i = 0; i < npools; i++)
     {
       pools[i].blocksize = poolsize[i];
-      pools[i].expandsize = expandsize;
+      pools[i].expandsize = expandsize - mpool->minpoolsize;
       pools[i].initialsize = 0;
       pools[i].interruptsize = 0;
+      pools[i].priv = mpool;
+      pools[i].alloc = mempool_multiple_alloc_callback;
+      pools[i].free = mempool_multiple_free_callback;
+
       ret = mempool_init(pools + i, name);
       if (ret < 0)
         {
-          while (--i >= 0)
-            {
-              mempool_deinit(pools + i);
-            }
-
           goto err_with_pools;
         }
 
@@ -195,9 +335,23 @@ mempool_multiple_init(FAR const char *name,
         }
     }
 
+  mpool->dict_alloc = maxpoolszie / sizeof(struct mpool_dict_s) + 1;
+  mpool->dict_used = 0;
+  mpool->dict = alloc(arg, sizeof(uintptr_t),
+                      mpool->dict_alloc * sizeof(struct mpool_dict_s));
+  if (mpool->dict == NULL)
+    {
+      goto err_with_pools;
+    }
+
   return mpool;
 
 err_with_pools:
+  while (--i >= 0)
+    {
+      mempool_deinit(pools + i);
+    }
+
   free(arg, pools);
 err_with_mpool:
   free(arg, mpool);
@@ -225,22 +379,28 @@ err_with_mpool:
 FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
                                  size_t size)
 {
-  FAR struct mempool_s *end = mpool->pools + mpool->npools;
+  FAR struct mempool_s *end;
   FAR struct mempool_s *pool;
 
-  pool = mempool_multiple_find(mpool, size + SIZEOF_HEAD);
+  if (size < 1)
+    {
+      return NULL;
+    }
+
+  pool = mempool_multiple_find(mpool, size);
   if (pool == NULL)
     {
       return NULL;
     }
 
+  end = mpool->pools + mpool->npools;
   do
     {
       FAR void *blk = mempool_alloc(pool);
-      if (blk != NULL)
+
+      if (blk)
         {
-          *(FAR struct mempool_s **)blk = pool;
-          return (FAR char *)blk + SIZEOF_HEAD;
+          return blk;
         }
     }
   while (++pool < end);
@@ -267,33 +427,30 @@ FAR void *mempool_multiple_alloc(FAR struct mempool_multiple_s *mpool,
 FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
                                    FAR void *oldblk, size_t size)
 {
+  FAR struct mpool_dict_s *dict;
   FAR void *blk;
 
+  if (oldblk == NULL)
+    {
+      return mempool_multiple_alloc(mpool, size);
+    }
+
   if (size < 1)
     {
       mempool_multiple_free(mpool, oldblk);
       return NULL;
     }
 
+  dict = mempool_multiple_get_dict(mpool, oldblk);
+  if (dict == NULL)
+    {
+      return NULL;
+    }
+
   blk = mempool_multiple_alloc(mpool, size);
   if (blk != NULL && oldblk != NULL)
     {
-      FAR struct mempool_s *oldpool;
-
-      oldpool = *(FAR struct mempool_s **)
-                ((FAR char *)oldblk - SIZEOF_HEAD);
-      if ((uintptr_t)oldpool & ALIGN_BIT)
-        {
-          oldpool = (FAR struct mempool_s *)
-                    ((uintptr_t)oldpool & ~ALIGN_BIT);
-          size = MIN(size, oldpool->blocksize -
-                     *(FAR size_t *)((FAR char *)oldblk - 2 * SIZEOF_HEAD));
-        }
-      else
-        {
-          size = MIN(size, oldpool->blocksize - SIZEOF_HEAD);
-        }
-
+      size = MIN(size, dict->pool->blocksize);
       memcpy(blk, oldblk, size);
       mempool_multiple_free(mpool, oldblk);
     }
@@ -311,25 +468,28 @@ FAR void *mempool_multiple_realloc(FAR struct mempool_multiple_s *mpool,
  * Input Parameters:
  *   mpool - The handle of multiple memory pool to be used.
  *   blk  - The pointer of memory block.
+ *
+ * Returned Value:
+ *   Zero on success; Negative number on any failure.
+ *
  ****************************************************************************/
 
-void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
-                           FAR void *blk)
+int mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
+                          FAR void *blk)
 {
-  FAR struct mempool_s *pool;
-  FAR char *mem;
-
-  DEBUGASSERT(mpool != NULL && blk != NULL);
+  FAR struct mpool_dict_s *dict;
 
-  mem = (FAR char *)blk - SIZEOF_HEAD;
-  pool = *(FAR struct mempool_s **)mem;
-  if ((uintptr_t)pool & ALIGN_BIT)
+  dict = mempool_multiple_get_dict(mpool, blk);
+  if (dict == NULL)
     {
-      pool = (FAR struct mempool_s *)((uintptr_t)pool & ~ALIGN_BIT);
-      mem = (FAR char *)blk - *(FAR size_t *)(mem - SIZEOF_HEAD);
+      return -EINVAL;
     }
 
-  mempool_free(pool, mem);
+  blk = (FAR char *)blk - (((FAR char *)blk -
+                           ((FAR char *)dict->addr + mpool->minpoolsize)) %
+                           dict->pool->blocksize);
+  mempool_free(dict->pool, blk);
+  return 0;
 }
 
 /****************************************************************************
@@ -343,29 +503,24 @@ void mempool_multiple_free(FAR struct mempool_multiple_s *mpool,
  *   blk  - The pointer of memory block.
  *
  * Returned Value:
- *   The size of memory block.
+ *   The size of memory block on success. Negative number on any failure.
  *
  ****************************************************************************/
 
-size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
-                                   FAR void *blk)
+ssize_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
+                                    FAR void *blk)
 {
-  FAR struct mempool_s *pool;
-  FAR char *mem;
+  FAR struct mpool_dict_s *dict;
 
   DEBUGASSERT(blk != NULL);
 
-  mem = (FAR char *)blk - SIZEOF_HEAD;
-  pool = *(FAR struct mempool_s **)mem;
-  if ((uintptr_t)pool & ALIGN_BIT)
+  dict = mempool_multiple_get_dict(mpool, blk);
+  if (dict == NULL)
     {
-      pool = (FAR struct mempool_s *)((uintptr_t)pool & ~ALIGN_BIT);
-      return pool->blocksize - *(FAR size_t *)(mem - SIZEOF_HEAD);
-    }
-  else
-    {
-      return pool->blocksize - SIZEOF_HEAD;
+      return -EINVAL;
     }
+
+  return dict->pool->blocksize;
 }
 
 /****************************************************************************
@@ -398,31 +553,24 @@ size_t mempool_multiple_alloc_size(FAR struct mempool_multiple_s *mpool,
 FAR void *mempool_multiple_memalign(FAR struct mempool_multiple_s *mpool,
                                     size_t alignment, size_t size)
 {
-  FAR struct mempool_s *end = mpool->pools + mpool->npools;
+  FAR struct mempool_s *end;
   FAR struct mempool_s *pool;
 
   DEBUGASSERT((alignment & (alignment - 1)) == 0);
 
-  pool = mempool_multiple_find(mpool, size + alignment + 2 * SIZEOF_HEAD);
+  pool = mempool_multiple_find(mpool, size + alignment);
   if (pool == NULL)
     {
       return NULL;
     }
 
+  end = mpool->pools + mpool->npools;
   do
     {
       FAR char *blk = mempool_alloc(pool);
       if (blk != NULL)
         {
-          FAR char *mem;
-
-          mem = blk + 2 * SIZEOF_HEAD;
-          mem = (FAR char *)(((uintptr_t)mem + alignment - 1) &
-                             ~(alignment - 1));
-          *(FAR uintptr_t *)(mem - SIZEOF_HEAD) =
-                                                 (uintptr_t)pool | ALIGN_BIT;
-          *(FAR size_t *)(mem - 2 * SIZEOF_HEAD) = mem - blk;
-          return mem;
+          return (FAR void *)ALIGN_UP(blk, alignment);
         }
     }
   while (++pool < end);
@@ -495,6 +643,7 @@ void mempool_multiple_deinit(FAR struct mempool_multiple_s *mpool)
       DEBUGVERIFY(mempool_deinit(mpool->pools + i));
     }
 
+  mpool->free(mpool->arg, mpool->dict);
   mpool->free(mpool->arg, mpool->pools);
   mpool->free(mpool->arg, mpool);
 }
diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index 3b1d60d3a5..958b3f3008 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -134,11 +134,6 @@
 
 #define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
 
-#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-#  define MM_IS_FROM_MEMPOOL(mem) \
-  ((*((FAR mmsize_t *)mem - 1) & MM_ALLOC_BIT) == 0)
-#endif
-
 /****************************************************************************
  * Public Types
  ****************************************************************************/
diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c
index ba6d06269b..cef44775a2 100644
--- a/mm/mm_heap/mm_free.c
+++ b/mm/mm_heap/mm_free.c
@@ -83,9 +83,8 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
     }
 
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(mem))
+  if (mempool_multiple_free(heap->mm_mpool, mem) >= 0)
     {
-      mempool_multiple_free(heap->mm_mpool, mem);
       return;
     }
 #endif
diff --git a/mm/mm_heap/mm_malloc_size.c b/mm/mm_heap/mm_malloc_size.c
index 987635780e..96eb27c4e6 100644
--- a/mm/mm_heap/mm_malloc_size.c
+++ b/mm/mm_heap/mm_malloc_size.c
@@ -38,6 +38,14 @@
 size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
 {
   FAR struct mm_freenode_s *node;
+#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
+  ssize_t size = mempool_multiple_alloc_size(heap->mm_mpool, mem);
+
+  if (size >= 0)
+    {
+      return size;
+    }
+#endif
 
   /* Protect against attempts to query a NULL reference */
 
@@ -46,13 +54,6 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
       return 0;
     }
 
-#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(mem))
-    {
-      return mempool_multiple_alloc_size(heap->mm_mpool, mem);
-    }
-#endif
-
   /* Map the memory chunk into a free node */
 
   node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE);
diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c
index b423c190df..85239783b4 100644
--- a/mm/mm_heap/mm_realloc.c
+++ b/mm/mm_heap/mm_realloc.c
@@ -95,30 +95,18 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
     }
 
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(oldmem))
+  newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
+  if (newmem != NULL)
     {
-      newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
-      if (newmem != NULL)
-        {
-          return newmem;
-        }
-
-      newmem = mm_malloc(heap, size);
-      if (newmem != NULL)
-        {
-          memcpy(newmem, oldmem,
-                 mempool_multiple_alloc_size(heap->mm_mpool, oldmem));
-          mempool_multiple_free(heap->mm_mpool, oldmem);
-        }
-
       return newmem;
     }
-  else
+  else if (size <= CONFIG_MM_HEAP_MEMPOOL_THRESHOLD ||
+           mempool_multiple_alloc_size(heap->mm_mpool, oldmem) >= 0)
     {
-      newmem = mempool_multiple_alloc(heap->mm_mpool, size);
+      newmem = mm_malloc(heap, size);
       if (newmem != NULL)
         {
-          memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));
+          memcpy(newmem, oldmem, size);
           mm_free(heap, oldmem);
           return newmem;
         }
diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c
index 6b90456148..0bd36e20dc 100644
--- a/mm/tlsf/mm_tlsf.c
+++ b/mm/tlsf/mm_tlsf.c
@@ -56,12 +56,6 @@
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
-#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-#  define MM_MPOOL_BIT (1 << 0)
-#  define MM_IS_FROM_MEMPOOL(mem) \
-          ((*((FAR size_t *)(mem) - 1)) & MM_MPOOL_BIT) == 0
-#endif
-
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
 #  define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
 #endif
@@ -654,9 +648,8 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
     }
 
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(mem))
+  if (mempool_multiple_free(heap->mm_mpool, mem) >= 0)
     {
-      mempool_multiple_free(heap->mm_mpool, mem);
       return;
     }
 #endif
@@ -954,9 +947,10 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
 size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
 {
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(mem))
+  ssize_t size = mempool_multiple_alloc_size(heap->mm_mpool, mem);
+  if (size >= 0)
     {
-      return mempool_multiple_alloc_size(heap->mm_mpool, mem);
+      return size;
     }
 #endif
 
@@ -1113,29 +1107,18 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
     }
 
 #if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD != 0
-  if (MM_IS_FROM_MEMPOOL(oldmem))
+  newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
+  if (newmem != NULL)
     {
-      newmem = mempool_multiple_realloc(heap->mm_mpool, oldmem, size);
-      if (newmem != NULL)
-        {
-          return newmem;
-        }
-
-      newmem = mm_malloc(heap, size);
-      if (newmem != NULL)
-        {
-          memcpy(newmem, oldmem, size);
-          mempool_multiple_free(heap->mm_mpool, oldmem);
-        }
-
       return newmem;
     }
-  else
+  else if (size <= CONFIG_MM_HEAP_MEMPOOL_THRESHOLD ||
+           mempool_multiple_alloc_size(heap->mm_mpool, oldmem) >= 0)
     {
-      newmem = mempool_multiple_alloc(heap->mm_mpool, size);
-      if (newmem != NULL)
+      newmem = mm_malloc(heap, size);
+      if (newmem != 0)
         {
-          memcpy(newmem, oldmem, MIN(size, mm_malloc_size(heap, oldmem)));
+          memcpy(newmem, oldmem, size);
           mm_free(heap, oldmem);
           return newmem;
         }