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 <juk...@ssrc.tii.ae> AuthorDate: Wed Jan 4 16:52:29 2023 +0400 Move rammaps to use mm_map list Signed-off-by: Jukka Laitinen <juk...@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 */