diff --git a/include/nuttx/mm/mempool.h b/include/nuttx/mm/mempool.h
new file mode 100644
index 0000000000..6075f324d3
--- /dev/null
+++ b/include/nuttx/mm/mempool.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * include/nuttx/mm/mempool.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_MM_MEMPOOL_H
+#define __INCLUDE_NUTTX_MM_MEMPOOL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <queue.h>
+#include <sys/types.h>
+
+#include <nuttx/spinlock.h>
+#include <nuttx/semaphore.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This structure describes memory buffer pool */
+
+struct mempool_s
+{
+  sq_queue_t list;       /* The free block list in normal mempool */
+  sq_queue_t ilist;      /* The free block list in interrupt mempool */
+  sq_queue_t elist;      /* The expand block list for normal mempool */
+  size_t     bsize;      /* The size for every block in mempool */
+  size_t     ninterrupt; /* The number of block in interrupt mempool */
+  size_t     nexpand;    /* The number of expand block every time for mempool */
+  size_t     nused;      /* The number of used block in mempool */
+  spinlock_t lock;       /* The protect lock to mempool */
+  sem_t      wait;       /* The semaphore of waiter get free block */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: mempool_init
+ *
+ * Description:
+ *   Initialize a memory pool.
+ *
+ * Input Parameters:
+ *   pool       - Address of the memory pool to be used.
+ *   bsize      - The block size of memory blocks in pool.
+ *   ninitial   - The initial count of memory blocks in pool.
+ *   nexpand    - The increment count of memory blocks in pool.
+ *                If there is not enough memory blocks and it isn't zero,
+ *                mempool_alloc will alloc nexpand memory blocks.
+ *   ninterrupt - The block count of memory blocks in pool for interrupt
+ *                context. These blocks only can use in interrupt context.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int mempool_init(FAR struct mempool_s *pool, size_t bsize, size_t ninitial,
+                 size_t nexpand, size_t ninterrupt);
+
+/****************************************************************************
+ * Name: mempool_alloc
+ *
+ * Description:
+ *   Allocate an block from a specific memory pool.
+ *
+ *   If there isn't enough memory blocks, This function will expand memory
+ *   pool if nexpand isn't zero.
+ *
+ * Input Parameters:
+ *   pool - Address of the memory pool to be used.
+ *
+ * Returned Value:
+ *   The pointer to the allocated block on success; NULL on any failure.
+ *
+ ****************************************************************************/
+
+FAR void *mempool_alloc(FAR struct mempool_s *pool);
+
+/****************************************************************************
+ * Name: mempool_free
+ *
+ * Description:
+ *   Release an memory block to the pool.
+ *
+ * Input Parameters:
+ *   pool - Address of the memory pool to be used.
+ *   blk  - The pointer of memory block.
+ ****************************************************************************/
+
+void mempool_free(FAR struct mempool_s *pool, FAR void *blk);
+
+/****************************************************************************
+ * Name: mempool_deinit
+ *
+ * Description:
+ *   Deallocate a memory pool.
+ *
+ * Input Parameters:
+ *   pool    - Address of the memory pool to be used.
+ ****************************************************************************/
+
+int mempool_deinit(FAR struct mempool_s *pool);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/mm/Kconfig b/mm/Kconfig
index 49499f2ac7..c8c6df5f65 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -165,19 +165,19 @@ config MM_SHM
 		Build in support for the shared memory interfaces shmget(), shmat(),
 		shmctl(), and shmdt().
 
-config MM_FILL_ALLOCATIONS
-	bool "Fill allocations with debug value"
-	default n
-	---help---
-		Fill all malloc() allocations with 0xAA. This helps
-		detecting uninitialized variable errors.
-
 config MM_CIRCBUF
 	bool "Circular buffer support"
 	default n
 	---help---
 		Build in support for the circular buffer management.
 
+config MM_MEMPOOL
+	bool "Enable memory buffer pool"
+	default n
+	---help---
+		Memory buffer pool support. Such pools are mostly used
+		for guaranteed, deadlock-free memory allocations.
+
 config MM_KASAN
 	bool "Kernel Address Sanitizer"
 	default n
@@ -186,6 +186,13 @@ config MM_KASAN
 		bugs in native code. After turn on this option, Please
 		add -fsanitize=kernel-address to CFLAGS/CXXFLAGS too.
 
+config MM_FILL_ALLOCATIONS
+	bool "Fill allocations with debug value"
+	default n
+	---help---
+		Fill all malloc() allocations with 0xAA. This helps
+		detecting uninitialized variable errors.
+
 config MM_BACKTRACE
 	int "The depth of backtrace"
 	default -1
diff --git a/mm/Makefile b/mm/Makefile
index c34f5e1ba6..5e3d11c902 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -29,6 +29,7 @@ include mm_gran/Make.defs
 include shm/Make.defs
 include iob/Make.defs
 include circbuf/Make.defs
+include mempool/Make.defs
 include kasan/Make.defs
 
 BINDIR ?= bin
diff --git a/mm/mempool/Make.defs b/mm/mempool/Make.defs
new file mode 100644
index 0000000000..cda9195fed
--- /dev/null
+++ b/mm/mempool/Make.defs
@@ -0,0 +1,30 @@
+############################################################################
+# mm/mempool/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Memory buffer pool management
+
+ifeq ($(CONFIG_MM_MEMPOOL),y)
+CSRCS += mempool.c
+
+# Add the memory buffer pool directory to the build
+
+DEPPATH += --dep-path mempool
+VPATH += :mempool
+endif
diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c
new file mode 100644
index 0000000000..5076556518
--- /dev/null
+++ b/mm/mempool/mempool.c
@@ -0,0 +1,261 @@
+/****************************************************************************
+ * mm/mempool/mempool.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdbool.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mm/mempool.h>
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline void mempool_add_list(FAR sq_queue_t *list, FAR void *base,
+                                    size_t nblks, size_t bsize)
+{
+  while (nblks-- > 0)
+    {
+      sq_addfirst(((FAR sq_entry_t *)((FAR char *)base + bsize * nblks)),
+                  list);
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mempool_init
+ *
+ * Description:
+ *   Initialize a memory pool.
+ *
+ * Input Parameters:
+ *   pool       - Address of the memory pool to be used.
+ *   bsize      - The block size of memory blocks in pool.
+ *   ninitial   - The initial count of memory blocks in pool.
+ *   nexpand    - The increment count of memory blocks in pool.
+ *                If there is not enough memory blocks and it isn't zero,
+ *                mempool_alloc will alloc nexpand memory blocks.
+ *   ninterrupt - The block count of memory blocks in pool for interrupt
+ *                context. These blocks only can use in interrupt context.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int mempool_init(FAR struct mempool_s *pool, size_t bsize, size_t ninitial,
+                 size_t nexpand, size_t ninterrupt)
+{
+  size_t count = ninitial + ninterrupt;
+
+  if (pool == NULL || bsize == 0)
+    {
+      return -EINVAL;
+    }
+
+  pool->nused = 0;
+  pool->bsize = bsize;
+  pool->nexpand = nexpand;
+  pool->ninterrupt = ninterrupt;
+  sq_init(&pool->list);
+  sq_init(&pool->ilist);
+  sq_init(&pool->elist);
+  if (count != 0)
+    {
+      FAR sq_entry_t *base;
+
+      base = kmm_malloc(sizeof(*base) + bsize * count);
+      if (base == NULL)
+        {
+          return -ENOMEM;
+        }
+
+      sq_addfirst(base, &pool->elist);
+      mempool_add_list(&pool->ilist, base + 1, ninterrupt, bsize);
+      mempool_add_list(&pool->list, (FAR char *)(base + 1) +
+                                    ninterrupt * bsize, ninitial, bsize);
+    }
+
+  nxsem_init(&pool->wait, 0, 0);
+  nxsem_set_protocol(&pool->wait, SEM_PRIO_NONE);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: mempool_alloc
+ *
+ * Description:
+ *   Allocate an block from a specific memory pool.
+ *
+ *   If there isn't enough memory blocks, This function will expand memory
+ *   pool if nexpand isn't zero.
+ *
+ * Input Parameters:
+ *   pool - Address of the memory pool to be used.
+ *
+ * Returned Value:
+ *   The pointer to the allocated block on success; NULL on any failure.
+ *
+ ****************************************************************************/
+
+FAR void *mempool_alloc(FAR struct mempool_s *pool)
+{
+  FAR sq_entry_t *blk;
+  irqstate_t flags;
+
+  if (pool == NULL)
+    {
+      return NULL;
+    }
+
+retry:
+  flags = spin_lock_irqsave(&pool->lock);
+  blk = sq_remfirst(&pool->list);
+  if (blk == NULL)
+    {
+      if (up_interrupt_context())
+        {
+          blk = sq_remfirst(&pool->ilist);
+          if (blk == NULL)
+            {
+              goto out_with_lock;
+            }
+        }
+      else
+        {
+          spin_unlock_irqrestore(&pool->lock, flags);
+          if (pool->nexpand != 0)
+            {
+              blk = kmm_malloc(sizeof(*blk) + pool->bsize * pool->nexpand);
+              if (blk == NULL)
+                {
+                  return NULL;
+                }
+
+              flags = spin_lock_irqsave(&pool->lock);
+              sq_addlast(blk, &pool->elist);
+              mempool_add_list(&pool->list, blk + 1, pool->nexpand,
+                               pool->bsize);
+              blk = sq_remfirst(&pool->list);
+            }
+          else if (nxsem_wait_uninterruptible(&pool->wait) < 0)
+            {
+              return NULL;
+            }
+          else
+            {
+              goto retry;
+            }
+        }
+    }
+
+  pool->nused++;
+
+out_with_lock:
+  spin_unlock_irqrestore(&pool->lock, flags);
+  return blk;
+}
+
+/****************************************************************************
+ * Name: mempool_free
+ *
+ * Description:
+ *   Release an memory block to the pool.
+ *
+ * Input Parameters:
+ *   pool - Address of the memory pool to be used.
+ *   blk  - The pointer of memory block.
+ ****************************************************************************/
+
+void mempool_free(FAR struct mempool_s *pool, FAR void *blk)
+{
+  irqstate_t flags;
+  FAR char *base;
+
+  if (blk == NULL || pool == NULL)
+    {
+      return;
+    }
+
+  flags = spin_lock_irqsave(&pool->lock);
+  base = (FAR char *)(sq_peek(&pool->elist) + 1);
+  if (pool->ninterrupt && (FAR char *)blk >= base &&
+      (FAR char *)blk < base + pool->ninterrupt * pool->bsize)
+    {
+      sq_addfirst(blk, &pool->ilist);
+    }
+  else
+    {
+      sq_addfirst(blk, &pool->list);
+    }
+
+  pool->nused--;
+  spin_unlock_irqrestore(&pool->lock, flags);
+  if (pool->nexpand == 0)
+    {
+      int semcount;
+
+      nxsem_get_value(&pool->wait, &semcount);
+      if (semcount < 1)
+        {
+          nxsem_post(&pool->wait);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: mempool_deinit
+ *
+ * Description:
+ *   Deallocate a memory pool.
+ *
+ * Input Parameters:
+ *   pool    - Address of the memory pool to be used.
+ ****************************************************************************/
+
+int mempool_deinit(FAR struct mempool_s *pool)
+{
+  FAR sq_entry_t *blk;
+
+  if (pool == NULL)
+    {
+      return -EINVAL;
+    }
+
+  if (pool->nused != 0)
+    {
+      return -EBUSY;
+    }
+
+  while ((blk = sq_remfirst(&pool->elist)) != NULL)
+    {
+      kmm_free(blk);
+    }
+
+  nxsem_destroy(&pool->wait);
+  return 0;
+}