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;
}