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 */