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/10 10:34:37 UTC
[nuttx] 06/06: Move rammaps to use mm_map list
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 b8f23fc3f7b547d5dc69d79a6cbb1ae970255c70
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Wed Jan 4 16:52:29 2023 +0400
Move rammaps to use mm_map list
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
fs/mmap/fs_mmap.c | 4 +-
fs/mmap/fs_munmap.c | 117 ------------------------------------------------
fs/mmap/fs_rammap.c | 125 +++++++++++++++++++++++++++++++++++++---------------
fs/mmap/fs_rammap.h | 56 ++++++++---------------
4 files changed, 110 insertions(+), 192 deletions(-)
diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index e0f81f53a9..b979805b6d 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -135,7 +135,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
* do much better in the KERNEL build using the MMU.
*/
- return rammap(filep, length, offset, kernel, mapped);
+ return rammap(filep, &entry, kernel);
#endif
}
@@ -162,7 +162,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
* do much better in the KERNEL build using the MMU.
*/
- return rammap(filep, length, offset, kernel, mapped);
+ return rammap(filep, &entry, kernel);
#else
ferr("ERROR: mmap not supported \n");
return -ENOSYS;
diff --git a/fs/mmap/fs_munmap.c b/fs/mmap/fs_munmap.c
index 85ec132876..b0a37ada85 100644
--- a/fs/mmap/fs_munmap.c
+++ b/fs/mmap/fs_munmap.c
@@ -44,122 +44,6 @@
static int file_munmap_(FAR void *start, size_t length, bool kernel)
{
-#ifdef CONFIG_FS_RAMMAP
- FAR struct fs_rammap_s *prev;
- FAR struct fs_rammap_s *curr;
- FAR void *newaddr;
- unsigned int offset;
- int ret;
-
- /* Find a region containing this start and length in the list of regions */
-
- ret = nxmutex_lock(&g_rammaps.lock);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Search the list of regions */
-
- for (prev = NULL, curr = g_rammaps.head; curr;
- prev = curr, curr = curr->flink)
- {
- /* Does this region include any part of the specified range? */
-
- if ((uintptr_t)start < (uintptr_t)curr->addr + curr->length &&
- (uintptr_t)start + length >= (uintptr_t)curr->addr)
- {
- break;
- }
- }
-
- /* Did we find the region */
-
- if (!curr)
- {
- ferr("ERROR: Region not found\n");
- ret = -EINVAL;
- goto errout_with_lock;
- }
-
- /* Get the offset from the beginning of the region and the actual number
- * of bytes to "unmap". All mappings must extend to the end of the region.
- * There is no support for free a block of memory but leaving a block of
- * memory at the end. This is a consequence of using kumm_realloc() to
- * simulate the unmapping.
- */
-
- offset = start - curr->addr;
- if (offset + length < curr->length)
- {
- ferr("ERROR: Cannot umap without unmapping to the end\n");
- ret = -ENOSYS;
- goto errout_with_lock;
- }
-
- /* Okay.. the region is beging umapped to the end. Make sure the length
- * indicates that.
- */
-
- length = curr->length - offset;
-
- /* Are we unmapping the entire region (offset == 0)? */
-
- if (length >= curr->length)
- {
- /* Yes.. remove the mapping from the list */
-
- if (prev)
- {
- prev->flink = curr->flink;
- }
- else
- {
- g_rammaps.head = curr->flink;
- }
-
- /* Then free the region */
-
- if (kernel)
- {
- kmm_free(curr);
- }
- else
- {
- kumm_free(curr);
- }
- }
-
- /* No.. We have been asked to "unmap' only a portion of the memory
- * (offset > 0).
- */
-
- else
- {
- if (kernel)
- {
- newaddr = kmm_realloc(curr->addr,
- sizeof(struct fs_rammap_s) + length);
- }
- else
- {
- newaddr = kumm_realloc(curr->addr,
- sizeof(struct fs_rammap_s) + length);
- }
-
- DEBUGASSERT(newaddr == (FAR void *)(curr->addr));
- UNUSED(newaddr); /* May not be used */
- curr->length = length;
- }
-
- nxmutex_unlock(&g_rammaps.lock);
- return OK;
-
-errout_with_lock:
- nxmutex_unlock(&g_rammaps.lock);
- return ret;
-#else
-
FAR struct tcb_s *tcb = nxsched_self();
FAR struct task_group_s *group = tcb->group;
FAR struct mm_map_entry_s *entry = NULL;
@@ -185,7 +69,6 @@ errout_with_lock:
}
return ret;
-#endif /* CONFIG_FS_RAMMAP */
}
/****************************************************************************
diff --git a/fs/mmap/fs_rammap.c b/fs/mmap/fs_rammap.c
index 95977cd9e8..5e346b8a5e 100644
--- a/fs/mmap/fs_rammap.c
+++ b/fs/mmap/fs_rammap.c
@@ -23,9 +23,7 @@
****************************************************************************/
#include <nuttx/config.h>
-
#include <sys/types.h>
-#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
@@ -35,7 +33,6 @@
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
-#include "inode/inode.h"
#include "fs_rammap.h"
#ifdef CONFIG_FS_RAMMAP
@@ -44,12 +41,83 @@
* Public Data
****************************************************************************/
-/* This is the list of all mapped files */
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
-struct fs_allmaps_s g_rammaps =
+static int unmap_rammap(FAR struct task_group_s *group,
+ FAR struct mm_map_entry_s *entry,
+ FAR void *start,
+ size_t length)
{
- NXMUTEX_INITIALIZER
-};
+ FAR void *newaddr;
+ unsigned int offset;
+ bool kernel = entry->priv.i != 0 ? true : false;
+ int ret;
+
+ /* Get the offset from the beginning of the region and the actual number
+ * of bytes to "unmap". All mappings must extend to the end of the region.
+ * There is no support for freeing a block of memory but leaving a block of
+ * memory at the end. This is a consequence of using kumm_realloc() to
+ * simulate the unmapping.
+ */
+
+ offset = start - entry->vaddr;
+ if (offset + length < entry->length)
+ {
+ ferr("ERROR: Cannot umap without unmapping to the end\n");
+ return -ENOSYS;
+ }
+
+ /* Okay.. the region is being unmapped to the end. Make sure the length
+ * indicates that.
+ */
+
+ length = entry->length - offset;
+
+ /* Are we unmapping the entire region (offset == 0)? */
+
+ if (length >= entry->length)
+ {
+ /* Free the region */
+
+ if (kernel)
+ {
+ kmm_free(entry->vaddr);
+ }
+ else
+ {
+ kumm_free(entry->vaddr);
+ }
+
+ /* Then remove the mapping from the list */
+
+ ret = mm_map_remove(get_group_mm(group), entry);
+ }
+
+ /* No.. We have been asked to "unmap' only a portion of the memory
+ * (offset > 0).
+ */
+
+ else
+ {
+ if (kernel)
+ {
+ newaddr = kmm_realloc(entry->vaddr, length);
+ }
+ else
+ {
+ newaddr = kumm_realloc(entry->vaddr, length);
+ }
+
+ DEBUGASSERT(newaddr == entry->vaddr);
+ UNUSED(newaddr); /* May not be used */
+ entry->length = length;
+ ret = OK;
+ }
+
+ return ret;
+}
/****************************************************************************
* Public Functions
@@ -81,15 +149,14 @@ struct fs_allmaps_s g_rammaps =
*
****************************************************************************/
-int rammap(FAR struct file *filep, size_t length,
- off_t offset, bool kernel, FAR void **mapped)
+int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
+ bool kernel)
{
- FAR struct fs_rammap_s *map;
- FAR uint8_t *alloc;
FAR uint8_t *rdbuffer;
ssize_t nread;
off_t fpos;
int ret;
+ size_t length = entry->length;
/* There is a major design flaw that I have not yet thought of fix for:
* The goal is to have a single region of memory that represents a single
@@ -106,40 +173,29 @@ int rammap(FAR struct file *filep, size_t length,
/* Allocate a region of memory of the specified size */
- alloc = kernel ?
- kmm_malloc(sizeof(struct fs_rammap_s) + length) :
- kumm_malloc(sizeof(struct fs_rammap_s) + length);
- if (!alloc)
+ rdbuffer = kernel ? kmm_malloc(length) : kumm_malloc(length);
+ if (!rdbuffer)
{
ferr("ERROR: Region allocation failed, length: %d\n", (int)length);
return -ENOMEM;
}
- /* Initialize the region */
-
- map = (FAR struct fs_rammap_s *)alloc;
- memset(map, 0, sizeof(struct fs_rammap_s));
- map->addr = alloc + sizeof(struct fs_rammap_s);
- map->length = length;
- map->offset = offset;
-
/* Seek to the specified file offset */
- fpos = file_seek(filep, offset, SEEK_SET);
+ fpos = file_seek(filep, entry->offset, SEEK_SET);
if (fpos < 0)
{
/* Seek failed... errno has already been set, but EINVAL is probably
* the correct response.
*/
- ferr("ERROR: Seek to position %d failed\n", (int)offset);
+ ferr("ERROR: Seek to position %d failed\n", (int)entry->offset);
ret = fpos;
goto errout_with_region;
}
/* Read the file data into the memory region */
- rdbuffer = map->addr;
while (length > 0)
{
nread = file_read(filep, rdbuffer, length);
@@ -154,7 +210,7 @@ int rammap(FAR struct file *filep, size_t length,
/* All other read errors are bad. */
ferr("ERROR: Read failed: offset=%d ret=%d\n",
- (int)offset, (int)nread);
+ (int)entry->offset, (int)nread);
ret = nread;
goto errout_with_region;
@@ -180,27 +236,26 @@ int rammap(FAR struct file *filep, size_t length,
/* Add the buffer to the list of regions */
- ret = nxmutex_lock(&g_rammaps.lock);
+ entry->vaddr = rdbuffer;
+ entry->priv.i = kernel ? 1 : 0;
+ entry->munmap = unmap_rammap;
+
+ ret = mm_map_add(entry);
if (ret < 0)
{
goto errout_with_region;
}
- map->flink = g_rammaps.head;
- g_rammaps.head = map;
-
- nxmutex_unlock(&g_rammaps.lock);
- *mapped = map->addr;
return OK;
errout_with_region:
if (kernel)
{
- kmm_free(alloc);
+ kmm_free(rdbuffer);
}
else
{
- kumm_free(alloc);
+ kumm_free(rdbuffer);
}
return ret;
diff --git a/fs/mmap/fs_rammap.h b/fs/mmap/fs_rammap.h
index 2ad01cab2e..a3c0a49fa1 100644
--- a/fs/mmap/fs_rammap.h
+++ b/fs/mmap/fs_rammap.h
@@ -18,25 +18,7 @@
*
****************************************************************************/
-#ifndef __FS_MMAP_FS_RAMMAP_H
-#define __FS_MMAP_FS_RAMMAP_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <nuttx/mutex.h>
-
-#ifdef CONFIG_FS_RAMMAP
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/* This structure describes one file that has been copied to memory and
+/* This driver manages files that have been copied to memory and
* managed as a share-able "memory mapped" file. This functionality is
* intended to provide a substitute for memory mapped files for architectures
* that do not have MMUs and, hence, cannot support on demand paging of
@@ -53,29 +35,27 @@
* - There are not access privileges.
*/
-struct fs_rammap_s
-{
- struct fs_rammap_s *flink; /* Implements a singly linked list */
- FAR void *addr; /* Start of allocated memory */
- size_t length; /* Length of region */
- off_t offset; /* File offset */
-};
+#ifndef __FS_MMAP_FS_RAMMAP_H
+#define __FS_MMAP_FS_RAMMAP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
-/* This structure defines all "mapped" files */
+#include <sys/types.h>
+#include <nuttx/mm/map.h>
-struct fs_allmaps_s
-{
- mutex_t lock; /* Provides exclusive access the list */
- struct fs_rammap_s *head; /* List of mapped files */
-};
+#ifdef CONFIG_FS_RAMMAP
/****************************************************************************
- * Public Data
+ * Public Types
****************************************************************************/
-/* This is the list of all mapped files */
-
-extern struct fs_allmaps_s g_rammaps;
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
/****************************************************************************
* Public Function Prototypes
@@ -107,8 +87,8 @@ extern struct fs_allmaps_s g_rammaps;
*
****************************************************************************/
-int rammap(FAR struct file *filep, size_t length,
- off_t offset, bool kernel, FAR void **mapped);
+int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry,
+ bool kernel);
#endif /* CONFIG_FS_RAMMAP */
#endif /* __FS_MMAP_FS_RAMMAP_H */