Move rammaps to use mm_map list

Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
Jukka Laitinen 2023-01-04 16:52:29 +04:00 committed by Xiang Xiao
parent a5ed8014e8
commit b8f23fc3f7
4 changed files with 110 additions and 192 deletions

View File

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

View File

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

View File

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

View File

@ -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,30 +35,28 @@
* - 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
/* This structure defines all "mapped" files */
/****************************************************************************
* Included Files
****************************************************************************/
struct fs_allmaps_s
{
mutex_t lock; /* Provides exclusive access the list */
struct fs_rammap_s *head; /* List of mapped files */
};
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/mm/map.h>
#ifdef CONFIG_FS_RAMMAP
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/* This is the list of all mapped files */
extern struct fs_allmaps_s g_rammaps;
/****************************************************************************
* 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 */