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


The following commit(s) were added to refs/heads/master by this push:
     new 946ed96926 fs: add fs_heap, support shm/tmpfs/pseudofile with indepent 
heap
946ed96926 is described below

commit 946ed969262f7227681788b75f84d872aa3e04f9
Author: buxiasen <[email protected]>
AuthorDate: Fri Jun 14 11:56:13 2024 +0800

    fs: add fs_heap, support shm/tmpfs/pseudofile with indepent heap
    
    For some case, need large files from tmpfs or shmfs, will lead to high
    pressure on memory fragments, add an optional fs_heap with independent
    heap will benifit for memory fragments issue.
    
    Signed-off-by: buxiasen <[email protected]>
---
 fs/CMakeLists.txt      |  2 +-
 fs/Kconfig             |  8 ++++++
 fs/Makefile            |  2 +-
 fs/fs_heap.c           | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/fs_heap.h           | 50 ++++++++++++++++++++++++++++++++++++++
 fs/fs_initialize.c     |  3 +++
 fs/shm/shmfs_alloc.c   |  5 ++--
 fs/tmpfs/fs_tmpfs.c    | 55 ++++++++++++++++++++---------------------
 fs/vfs/fs_pseudofile.c | 17 +++++++------
 9 files changed, 169 insertions(+), 39 deletions(-)

diff --git a/fs/CMakeLists.txt b/fs/CMakeLists.txt
index cc876d4c17..ef2401dbec 100644
--- a/fs/CMakeLists.txt
+++ b/fs/CMakeLists.txt
@@ -17,7 +17,7 @@
 # the License.
 #
 # 
##############################################################################
-nuttx_add_kernel_library(fs fs_initialize.c)
+nuttx_add_kernel_library(fs fs_initialize.c fs_heap.c)
 nuttx_add_subdirectory()
 target_include_directories(fs PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
                                       ${NUTTX_DIR}/sched)
diff --git a/fs/Kconfig b/fs/Kconfig
index 3485a1878d..b34ffa4325 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -111,6 +111,14 @@ config SENDFILE_BUFSIZE
        ---help---
                Size of the I/O buffer to allocate in sendfile().  Default: 512b
 
+config FS_HEAPSIZE
+       int "Independent heap bytes used by shm/tmpfs/pseudofile"
+       default 0
+       depends on FS_SHMFS || FS_TMPFS || PSEUDOFS_FILE
+       ---help---
+               Support for shm/tmpfs/fs_pseudofile.c ram based fs memory.
+               default 0 to use kmm directly. independent heap disabled
+
 source "fs/vfs/Kconfig"
 source "fs/aio/Kconfig"
 source "fs/semaphore/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index d18a339973..050ec8d743 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -20,7 +20,7 @@
 
 include $(TOPDIR)/Make.defs
 
-CSRCS = fs_initialize.c
+CSRCS = fs_initialize.c fs_heap.c
 
 include inode/Make.defs
 include vfs/Make.defs
diff --git a/fs/fs_heap.c b/fs/fs_heap.c
new file mode 100644
index 0000000000..1de10e3fb1
--- /dev/null
+++ b/fs/fs_heap.c
@@ -0,0 +1,66 @@
+/****************************************************************************
+ * fs/fs_heap.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 "fs_heap.h"
+
+#if defined(CONFIG_FS_HEAPSIZE) && CONFIG_FS_HEAPSIZE > 0
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static FAR struct mm_heap_s *g_fs_heap;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void fs_heap_initialize(void)
+{
+  FAR void *buf = kmm_malloc(CONFIG_FS_HEAPSIZE);
+  DEBUGASSERT(buf != NULL);
+  g_fs_heap = mm_initialize("heapfs", buf, CONFIG_FS_HEAPSIZE);
+}
+
+FAR void *fs_heap_zalloc(size_t size)
+{
+  return mm_zalloc(g_fs_heap, size);
+}
+
+size_t fs_heap_malloc_size(FAR void *mem)
+{
+  return mm_malloc_size(g_fs_heap, mem);
+}
+
+FAR void *fs_heap_realloc(FAR void *oldmem, size_t size)
+{
+  return mm_realloc(g_fs_heap, oldmem, size);
+}
+
+void fs_heap_free(FAR void *mem)
+{
+  mm_free(g_fs_heap, mem);
+}
+
+#endif
diff --git a/fs/fs_heap.h b/fs/fs_heap.h
new file mode 100644
index 0000000000..2ed359b1ba
--- /dev/null
+++ b/fs/fs_heap.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * fs/fs_heap.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 __FS_FS_HEAP_H
+#define __FS_FS_HEAP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+#include <nuttx/kmalloc.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#if defined(CONFIG_FS_HEAPSIZE) && CONFIG_FS_HEAPSIZE > 0
+void      fs_heap_initialize(void);
+FAR void *fs_heap_zalloc(size_t size);
+size_t    fs_heap_malloc_size(FAR void *mem);
+FAR void *fs_heap_realloc(FAR void *oldmem, size_t size);
+void      fs_heap_free(FAR void *mem);
+#else
+#  define fs_heap_initialize()
+#  define fs_heap_zalloc       kmm_zalloc
+#  define fs_heap_malloc_size  kmm_malloc_size
+#  define fs_heap_realloc      kmm_realloc
+#  define fs_heap_free         kmm_free
+#endif
+
+#endif
diff --git a/fs/fs_initialize.c b/fs/fs_initialize.c
index 4424711196..d82753920b 100644
--- a/fs/fs_initialize.c
+++ b/fs/fs_initialize.c
@@ -31,6 +31,7 @@
 #include "inode/inode.h"
 #include "aio/aio.h"
 #include "vfs/lock.h"
+#include "fs_heap.h"
 
 /****************************************************************************
  * Private Functions
@@ -81,6 +82,8 @@ void fs_initialize(void)
 {
   fs_trace_begin();
 
+  fs_heap_initialize();
+
   /* Initial inode, file, and VFS data structures */
 
   inode_initialize();
diff --git a/fs/shm/shmfs_alloc.c b/fs/shm/shmfs_alloc.c
index 05a0f540b1..971f96831e 100644
--- a/fs/shm/shmfs_alloc.c
+++ b/fs/shm/shmfs_alloc.c
@@ -31,6 +31,7 @@
 #include <nuttx/pgalloc.h>
 
 #include "shm/shmfs.h"
+#include "fs_heap.h"
 
 /****************************************************************************
  * Public Functions
@@ -54,7 +55,7 @@ FAR struct shmfs_object_s *shmfs_alloc_object(size_t length)
       return NULL;
     }
 
-  object = kmm_zalloc(alloc_size);
+  object = fs_heap_zalloc(alloc_size);
   if (object)
     {
       object->paddr = (FAR char *)(object + 1);
@@ -156,6 +157,6 @@ void shmfs_free_object(FAR struct shmfs_object_s *object)
        * (and the shared memory in case of FLAT build)
        */
 
-      kmm_free(object);
+      fs_heap_free(object);
     }
 }
diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c
index 83d73425a0..2e4dc5a91d 100644
--- a/fs/tmpfs/fs_tmpfs.c
+++ b/fs/tmpfs/fs_tmpfs.c
@@ -39,6 +39,7 @@
 
 #include "inode/inode.h"
 #include "fs_tmpfs.h"
+#include "fs_heap.h"
 
 #ifndef CONFIG_DISABLE_MOUNTPOINT
 
@@ -245,7 +246,7 @@ static int tmpfs_realloc_directory(FAR struct 
tmpfs_directory_s *tdo,
 
   /* Realloc the directory object */
 
-  newentry = kmm_realloc(tdo->tdo_entry, objsize);
+  newentry = fs_heap_realloc(tdo->tdo_entry, objsize);
   if (newentry == NULL)
     {
       return -ENOMEM;
@@ -285,7 +286,7 @@ static int tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
         {
           /* Free the file object */
 
-          kmm_free(tfo->tfo_data);
+          fs_heap_free(tfo->tfo_data);
           tfo->tfo_data = NULL;
           tfo->tfo_alloc = 0;
           tfo->tfo_size = 0;
@@ -326,7 +327,7 @@ static int tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
 
   /* Realloc the file object */
 
-  newdata = kmm_realloc(tfo->tfo_data, allocsize);
+  newdata = fs_heap_realloc(tfo->tfo_data, allocsize);
   if (newdata == NULL)
     {
       return -ENOMEM;
@@ -377,8 +378,8 @@ static void tmpfs_release_lockedfile(FAR struct 
tmpfs_file_s *tfo)
     {
       tmpfs_unlock_file(tfo);
       nxrmutex_destroy(&tfo->tfo_lock);
-      kmm_free(tfo->tfo_data);
-      kmm_free(tfo);
+      fs_heap_free(tfo->tfo_data);
+      fs_heap_free(tfo);
     }
 
   /* Otherwise, just decrement the reference count on the file object */
@@ -470,7 +471,7 @@ static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s 
*tdo,
 
   if (tdo->tdo_entry[index].tde_name != NULL)
     {
-      kmm_free(tdo->tdo_entry[index].tde_name);
+      lib_free(tdo->tdo_entry[index].tde_name);
     }
 
   /* Remove by replacing this entry with the final directory entry */
@@ -535,7 +536,7 @@ static int tmpfs_add_dirent(FAR struct tmpfs_directory_s 
*tdo,
   index = tmpfs_realloc_directory(tdo, nentries);
   if (index < 0)
     {
-      kmm_free(newname);
+      fs_heap_free(newname);
       return index;
     }
 
@@ -560,7 +561,7 @@ tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent)
 
   /* Create a new zero length file object */
 
-  tfo = kmm_malloc(sizeof(*tfo));
+  tfo = fs_heap_zalloc(sizeof(*tfo));
   if (tfo == NULL)
     {
       return NULL;
@@ -693,7 +694,7 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs,
 
 errout_with_file:
   nxrmutex_destroy(&newtfo->tfo_lock);
-  kmm_free(newtfo);
+  fs_heap_free(newtfo);
 
 errout_with_parent:
   parent->tdo_refs--;
@@ -712,7 +713,7 @@ tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent)
 
   /* Create a new zero length directory object */
 
-  tdo = kmm_malloc(sizeof(*tdo));
+  tdo = fs_heap_zalloc(sizeof(*tdo));
   if (tdo == NULL)
     {
       return NULL;
@@ -846,7 +847,7 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
 
 errout_with_directory:
   nxrmutex_destroy(&newtdo->tdo_lock);
-  kmm_free(newtdo);
+  fs_heap_free(newtdo);
 
 errout_with_parent:
   parent->tdo_refs--;
@@ -1215,7 +1216,7 @@ static int tmpfs_free_callout(FAR struct 
tmpfs_directory_s *tdo,
 
   if (tdo->tdo_entry[index].tde_name != NULL)
     {
-      kmm_free(tdo->tdo_entry[index].tde_name);
+      lib_free(tdo->tdo_entry[index].tde_name);
     }
 
   /* Remove by replacing this entry with the final directory entry */
@@ -1251,19 +1252,19 @@ static int tmpfs_free_callout(FAR struct 
tmpfs_directory_s *tdo,
           return TMPFS_UNLINKED;
         }
 
-      kmm_free(tfo->tfo_data);
+      fs_heap_free(tfo->tfo_data);
     }
   else /* if (to->to_type == TMPFS_DIRECTORY) */
     {
       tdo = (FAR struct tmpfs_directory_s *)to;
 
-      kmm_free(tdo->tdo_entry);
+      fs_heap_free(tdo->tdo_entry);
     }
 
   /* Free the object now */
 
   nxrmutex_destroy(&to->to_lock);
-  kmm_free(to);
+  fs_heap_free(to);
   return TMPFS_DELETED;
 }
 
@@ -1995,7 +1996,7 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR 
const char *relpath,
   fs = mountpt->i_private;
   DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL);
 
-  tdir = kmm_zalloc(sizeof(*tdir));
+  tdir = fs_heap_zalloc(sizeof(*tdir));
   if (tdir == NULL)
     {
       return -ENOMEM;
@@ -2006,7 +2007,7 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR 
const char *relpath,
   ret = tmpfs_lock(fs);
   if (ret < 0)
     {
-      kmm_free(tdir);
+      fs_heap_free(tdir);
       return ret;
     }
 
@@ -2059,7 +2060,7 @@ static int tmpfs_closedir(FAR struct inode *mountpt,
   tmpfs_lock_directory(tdo);
   tdo->tdo_refs--;
   tmpfs_unlock_directory(tdo);
-  kmm_free(dir);
+  fs_heap_free(dir);
   return OK;
 }
 
@@ -2177,7 +2178,7 @@ static int tmpfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
 
   /* Create an instance of the tmpfs file system */
 
-  fs = kmm_zalloc(sizeof(struct tmpfs_s));
+  fs = fs_heap_zalloc(sizeof(struct tmpfs_s));
   if (fs == NULL)
     {
       return -ENOMEM;
@@ -2190,7 +2191,7 @@ static int tmpfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
   tdo = tmpfs_alloc_directory(NULL);
   if (tdo == NULL)
     {
-      kmm_free(fs);
+      fs_heap_free(fs);
       return -ENOMEM;
     }
 
@@ -2238,11 +2239,11 @@ static int tmpfs_unbind(FAR void *handle, FAR struct 
inode **blkdriver,
   /* Now we can destroy the root file system and the file system itself. */
 
   nxrmutex_destroy(&tdo->tdo_lock);
-  kmm_free(tdo->tdo_entry);
-  kmm_free(tdo);
+  fs_heap_free(tdo->tdo_entry);
+  fs_heap_free(tdo);
 
   nxrmutex_destroy(&fs->tfs_lock);
-  kmm_free(fs);
+  fs_heap_free(fs);
   return ret;
 }
 
@@ -2405,8 +2406,8 @@ static int tmpfs_unlink(FAR struct inode *mountpt, FAR 
const char *relpath)
   else
     {
       nxrmutex_destroy(&tfo->tfo_lock);
-      kmm_free(tfo->tfo_data);
-      kmm_free(tfo);
+      fs_heap_free(tfo->tfo_data);
+      fs_heap_free(tfo);
     }
 
   /* Release the reference and lock on the parent directory */
@@ -2547,8 +2548,8 @@ static int tmpfs_rmdir(FAR struct inode *mountpt, FAR 
const char *relpath)
   /* Free the directory object */
 
   nxrmutex_destroy(&tdo->tdo_lock);
-  kmm_free(tdo->tdo_entry);
-  kmm_free(tdo);
+  fs_heap_free(tdo->tdo_entry);
+  fs_heap_free(tdo);
 
   /* Release the reference and lock on the parent directory */
 
diff --git a/fs/vfs/fs_pseudofile.c b/fs/vfs/fs_pseudofile.c
index a45d2875a8..23890ef0bf 100644
--- a/fs/vfs/fs_pseudofile.c
+++ b/fs/vfs/fs_pseudofile.c
@@ -38,6 +38,7 @@
 
 #include "inode/inode.h"
 #include "notify/notify.h"
+#include "fs_heap.h"
 
 /****************************************************************************
  * Private Types
@@ -133,8 +134,8 @@ static void pseudofile_remove(FAR struct fs_pseudofile_s 
*pf)
 {
   nxmutex_unlock(&pf->lock);
   nxmutex_destroy(&pf->lock);
-  kmm_free(pf->content);
-  kmm_free(pf);
+  fs_heap_free(pf->content);
+  fs_heap_free(pf);
 }
 
 static int pseudofile_close(FAR struct file *filep)
@@ -170,13 +171,13 @@ static int pseudofile_expand(FAR struct inode *node,
   FAR struct fs_pseudofile_s *pf = node->i_private;
   FAR void *tmp;
 
-  if (pf->content && kmm_malloc_size(pf->content) >= size)
+  if (pf->content && fs_heap_malloc_size(pf->content) >= size)
     {
       node->i_size = size;
       return 0;
     }
 
-  tmp = kmm_realloc(pf->content, 1 << LOG2_CEIL(size));
+  tmp = fs_heap_realloc(pf->content, 1 << LOG2_CEIL(size));
   if (tmp == NULL)
     {
       return -ENOMEM;
@@ -362,7 +363,7 @@ static int pseudofile_munmap(FAR struct task_group_s *group,
 
           if (inode->i_private)
             {
-              kmm_free(inode->i_private);
+              fs_heap_free(inode->i_private);
             }
 
           inode->i_private = NULL;
@@ -402,7 +403,7 @@ static int pseudofile_truncate(FAR struct file *filep, 
off_t length)
     {
       FAR void *tmp;
 
-      tmp = kmm_realloc(pf->content, length);
+      tmp = fs_heap_realloc(pf->content, length);
       if (tmp == NULL)
         {
           ret = -ENOMEM;
@@ -480,7 +481,7 @@ int pseudofile_create(FAR struct inode **node, FAR const 
char *path,
       return -EINVAL;
     }
 
-  pf = kmm_zalloc(sizeof(struct fs_pseudofile_s));
+  pf = fs_heap_zalloc(sizeof(struct fs_pseudofile_s));
   if (pf == NULL)
     {
       return -ENOMEM;
@@ -515,7 +516,7 @@ reserve_err:
   inode_unlock();
 lock_err:
   nxmutex_destroy(&pf->lock);
-  kmm_free(pf);
+  fs_heap_free(pf);
   return ret;
 }
 

Reply via email to