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:31 UTC
[nuttx] branch master updated (f864e5f657 -> b8f23fc3f7)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from f864e5f657 wireless/bluetooth: add interrupt_context hander for netsnoop
new 6e4ddf78bb include/nuttx/mm/map.h: Change mm_map_entry "priv" into union type
new 7f8bec7070 Add mm/mm_map virtual memory mapping list
new 5150979488 mm/shm: Remove gs_vaddr from task group and use dynamic vm_map instead
new dd97900221 fs/mmap: Add mappings to mm_map list if CONFIG_MM_MAP is defined
new a5ed8014e8 Move anonymous mapping emulation into own module under fs/mmap
new b8f23fc3f7 Move rammaps to use mm_map list
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
fs/mmap/Kconfig | 7 +-
fs/mmap/Make.defs | 4 +
.../modlib_loadshdrs.c => fs/mmap/fs_anonmap.c | 107 ++++---
.../src/mpfs/mpfs_usb.h => fs/mmap/fs_anonmap.h | 49 ++--
fs/mmap/fs_mmap.c | 55 ++--
fs/mmap/fs_munmap.c | 125 ++------
fs/mmap/fs_rammap.c | 125 +++++---
fs/mmap/fs_rammap.h | 56 ++--
include/nuttx/mm/map.h | 162 ++++++++++-
include/nuttx/mm/shm.h | 25 +-
include/nuttx/sched.h | 13 +
mm/Makefile | 1 +
{drivers/i2s => mm/map}/Make.defs | 14 +-
mm/map/mm_map.c | 315 +++++++++++++++++++++
mm/shm/shmat.c | 40 ++-
mm/shm/shmdt.c | 109 ++++---
sched/group/group_create.c | 4 +
sched/group/group_leave.c | 4 +
18 files changed, 863 insertions(+), 352 deletions(-)
copy libs/libc/modlib/modlib_loadshdrs.c => fs/mmap/fs_anonmap.c (53%)
copy arch/risc-v/src/mpfs/mpfs_usb.h => fs/mmap/fs_anonmap.h (70%)
copy {drivers/i2s => mm/map}/Make.defs (85%)
create mode 100644 mm/map/mm_map.c
[nuttx] 02/06: Add mm/mm_map virtual memory mapping list
Posted by xi...@apache.org.
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 7f8bec7070077967224af219c733dc4ff6147202
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Thu Apr 7 16:17:21 2022 +0400
Add mm/mm_map virtual memory mapping list
The task_group specific list can be used to store information about
mmappings.
For a driver or filesystem performing mmap can also enable munmap by
adding an item to this list using mm_map_add(). The item is then
returned in the corresponding munmap call.
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
include/nuttx/mm/map.h | 156 +++++++++++++++++++++-
include/nuttx/sched.h | 13 ++
mm/Makefile | 1 +
mm/map/Make.defs | 28 ++++
mm/map/mm_map.c | 315 +++++++++++++++++++++++++++++++++++++++++++++
sched/group/group_create.c | 4 +
sched/group/group_leave.c | 4 +
7 files changed, 517 insertions(+), 4 deletions(-)
diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h
index f845054e34..ac7d0c442e 100644
--- a/include/nuttx/mm/map.h
+++ b/include/nuttx/mm/map.h
@@ -44,7 +44,7 @@ struct task_group_s;
struct mm_map_entry_s
{
FAR struct mm_map_entry *flink; /* this is used as sq_entry_t */
- FAR const void *vaddr;
+ FAR void *vaddr;
size_t length;
off_t offset;
int prot;
@@ -63,7 +63,7 @@ struct mm_map_entry_s
*/
int (*munmap)(FAR struct task_group_s *group,
- FAR struct mm_map_entry_s *map,
+ FAR struct mm_map_entry_s *entry,
FAR void *start,
size_t length);
};
@@ -73,11 +73,159 @@ struct mm_map_entry_s
struct mm_map_s
{
sq_queue_t mm_map_sq;
- mutex_t mm_map_mutex;
+ rmutex_t mm_map_mutex;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+/****************************************************************************
+ * Name: mm_map_lock
+ *
+ * Description:
+ * Get exclusive access current task_group's mm_map
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * OK on success
+ * A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(void);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ * Relinquish exclusive access to current task_group's mm_map
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(void);
+
+/****************************************************************************
+ * Name: mm_map_initialize
+ *
+ * Description:
+ * Initialization function, called only by group_initialize
+ *
+ * Input Parameters:
+ * mm - Pointer to the mm_map structure to be initialized
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void mm_map_initialize(FAR struct mm_map_s *mm);
+
+/****************************************************************************
+ * Name: mm_map_destroy
+ *
+ * Description:
+ * Uninitialization function, called only by group_release
+ *
+ * Input Parameters:
+ * mm - Pointer to the mm_map structure to be initialized
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void mm_map_destroy(FAR struct mm_map_s *mm);
+
+/****************************************************************************
+ * Name: mm_map_add
+ *
+ * Description:
+ * Adds a virtual memory area into the list of mappings
+ *
+ * Input Parameters:
+ * entry - A pointer to mm_map_entry_s, mapping info to be added
+ *
+ * Returned Value:
+ * OK Added successfully
+ * -EINVAL: Invalid attempt to get the semaphore
+ * -EINTR: The wait was interrupted by the receipt of a signal.
+ * -ENOMEM: Out of memory
+ *
+ ****************************************************************************/
+
+int mm_map_add(FAR struct mm_map_entry_s *entry);
+
+/****************************************************************************
+ * Name: mm_map_next
+ *
+ * Description:
+ * Returns the next mapping in the list, following the argument.
+ * Can be used to iterate through all the mappings. Returns the first
+ * mapping when the argument "entry" is NULL.
+ *
+ * Input Parameters:
+ * entry - Pointer to a single mapping in this task group or NULL to get
+ * the first one
+ *
+ * Returned Value:
+ * Pointer to the next mapping
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_next(
+ FAR const struct mm_map_entry_s *entry);
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ * Find the first mapping matching address and length
+ *
+ * Input Parameters:
+ * vaddr - Start address of the mapped area
+ * length - Length of the mapping
+ *
+ * Returned Value:
+ * Pointer to the mapping, NULL if not found
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+ size_t length);
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ * Removes a virtual memory area from the list of mappings
+ * Sets the given pointer argument to NULL after successful removal
+ *
+ * Input Parameters:
+ * mm - Pointer to the list of entries, from which the entry is
+ * removed. If passed mm is NULL, the function doesn't do
+ * anything, but just returns OK.
+ *
+ * entry - Pointer to the entry to be removed. If the passed entry is
+ * NULL the function doesn't do anything but just returns OK
+ *
+ * Returned Value:
+ * OK: Removed successfully
+ * -EINVAL: Invalid attempt to get the semaphore
+ * -EINTR: The wait was interrupted by the receipt of a signal.
+ * -ENOENT: Memory area not found
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct mm_map_s *mm,
+ FAR struct mm_map_entry_s *entry);
+
+#endif /* __INCLUDE_NUTTX_MM_MAP_H */
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index bf8db3ff81..ce450a8137 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -43,6 +43,7 @@
#include <nuttx/mm/shm.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
+#include <nuttx/mm/map.h>
#include <arch/arch.h>
@@ -180,6 +181,14 @@
# define TCB_REG_OFF(reg) (reg * sizeof(uint32_t))
#endif
+/* Get a pointer to the process' memory map struct from the task_group */
+
+#define get_group_mm(group) (group ? &group->tg_mm_map : NULL)
+
+/* Get a pointer to current the process' memory map struct */
+
+#define get_current_mm() (get_group_mm(nxsched_self()->group))
+
/****************************************************************************
* Public Type Definitions
****************************************************************************/
@@ -506,6 +515,10 @@ struct task_group_s
struct group_shm_s tg_shm; /* Task shared memory logic */
#endif
+
+ /* Virtual memory mapping info ********************************************/
+
+ struct mm_map_s tg_mm_map; /* Task mmappings */
};
/* struct tcb_s *************************************************************/
diff --git a/mm/Makefile b/mm/Makefile
index 1d1d5f2413..a9d0c2272b 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -32,6 +32,7 @@ include circbuf/Make.defs
include mempool/Make.defs
include kasan/Make.defs
include ubsan/Make.defs
+include map/Make.defs
BINDIR ?= bin
diff --git a/mm/map/Make.defs b/mm/map/Make.defs
new file mode 100644
index 0000000000..1d1f602d2b
--- /dev/null
+++ b/mm/map/Make.defs
@@ -0,0 +1,28 @@
+############################################################################
+# mm/map/Make.defs
+#
+# 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.
+#
+############################################################################
+
+# Virtual memory map list support
+
+CSRCS += mm_map.c
+
+# Add the shared memory directory to the build
+
+DEPPATH += --dep-path map
+VPATH += :map
diff --git a/mm/map/mm_map.c b/mm/map/mm_map.c
new file mode 100644
index 0000000000..22126bb4b7
--- /dev/null
+++ b/mm/map/mm_map.c
@@ -0,0 +1,315 @@
+/****************************************************************************
+ * mm/map/mm_map.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 <nuttx/mm/map.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/sched.h>
+#include <nuttx/kmalloc.h>
+#include <assert.h>
+#include <debug.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool in_range(FAR const void *start, size_t length,
+ FAR const void *range_start, size_t range_length)
+{
+ FAR const char *u_start = (FAR const char *)start;
+ FAR const char *u_end = u_start + length;
+ FAR const char *r_start = (FAR const char *)range_start;
+ FAR const char *r_end = r_start + range_length;
+
+ return (u_start >= r_start && u_start < r_end && /* Start is in range. */
+ u_end >= r_start && u_end <= r_end); /* End is in range. */
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mm_map_lock
+ *
+ * Description:
+ * Get exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+int mm_map_lock(void)
+{
+ return nxrmutex_lock(&get_current_mm()->mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ * Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(void)
+{
+ DEBUGVERIFY(nxrmutex_unlock(&get_current_mm()->mm_map_mutex));
+}
+
+/****************************************************************************
+ * Name: mm_map_initialize
+ *
+ * Description:
+ * Allocates a task group specific mm_map stucture. Called when the group
+ * is initialized
+ *
+ ****************************************************************************/
+
+void mm_map_initialize(FAR struct mm_map_s *mm)
+{
+ sq_init(&mm->mm_map_sq);
+ nxrmutex_init(&mm->mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_destroy
+ *
+ * Description:
+ * De-allocates a task group specific mm_map stucture and the mm_map_mutex
+ *
+ ****************************************************************************/
+
+void mm_map_destroy(FAR struct mm_map_s *mm)
+{
+ FAR struct mm_map_entry_s *entry;
+
+ while ((entry = (FAR struct mm_map_entry_s *)sq_remfirst(&mm->mm_map_sq)))
+ {
+ /* Pass null as group argument to indicate that actual MMU mappings
+ * must not be touched. The process is being deleted and we don't
+ * know in which context we are. Only kernel memory allocations
+ * need to be freed by drivers
+ */
+
+ /* Unmap the whole region */
+
+ if (entry->munmap)
+ {
+ if (entry->munmap(NULL, entry, entry->vaddr, entry->length) < 0)
+ {
+ /* This would be an error in the driver. It has defined munmap,
+ * but is not able to munmap the full area which it has mapped
+ */
+
+ merr("Driver munmap failed\n");
+ }
+ }
+
+ kmm_free(entry);
+ }
+
+ nxrmutex_destroy(&mm->mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_add
+ *
+ * Description:
+ * Add a mapping to task group's mm_map list
+ *
+ ****************************************************************************/
+
+int mm_map_add(FAR struct mm_map_entry_s *entry)
+{
+ FAR struct mm_map_s *mm = get_current_mm();
+ FAR struct mm_map_entry_s *new_entry;
+ int ret;
+
+ if (!entry)
+ {
+ return -EINVAL;
+ }
+
+ /* Copy the provided mapping and add to the list */
+
+ new_entry = kmm_malloc(sizeof(struct mm_map_entry_s));
+ if (!new_entry)
+ {
+ return -EINVAL;
+ }
+
+ *new_entry = *entry;
+
+ ret = nxrmutex_lock(&mm->mm_map_mutex);
+ if (ret < 0)
+ {
+ kmm_free(new_entry);
+ return ret;
+ }
+
+ sq_addfirst((sq_entry_t *)new_entry, &mm->mm_map_sq);
+
+ nxrmutex_unlock(&mm->mm_map_mutex);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mm_map_next
+ *
+ * Description:
+ * Returns the next mapping in the list.
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_next(
+ FAR const struct mm_map_entry_s *entry)
+{
+ FAR struct mm_map_s *mm = get_current_mm();
+ FAR struct mm_map_entry_s *next_entry = NULL;
+
+ if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+ {
+ if (entry == NULL)
+ {
+ next_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+ }
+ else
+ {
+ next_entry = (struct mm_map_entry_s *)
+ sq_next(((sq_entry_t *)entry));
+ }
+
+ nxrmutex_unlock(&mm->mm_map_mutex);
+ }
+
+ return next_entry;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ * Find the first mapping containing the range from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr, size_t length)
+{
+ FAR struct mm_map_s *mm = get_current_mm();
+ FAR struct mm_map_entry_s *found_entry = NULL;
+
+ if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+ {
+ found_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+ while (found_entry && !in_range(vaddr, length,
+ found_entry->vaddr,
+ found_entry->length))
+ {
+ found_entry = (struct mm_map_entry_s *)
+ sq_next(((sq_entry_t *)found_entry));
+ }
+
+ nxrmutex_unlock(&mm->mm_map_mutex);
+ }
+
+ return found_entry;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ * Remove a mapping from the task group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct mm_map_s *mm,
+ FAR struct mm_map_entry_s *entry)
+{
+ FAR struct mm_map_entry_s *prev_entry;
+ FAR struct mm_map_entry_s *removed_entry = NULL;
+ int ret;
+
+ if (!mm || !entry)
+ {
+ return OK;
+ }
+
+ ret = nxrmutex_lock(&mm->mm_map_mutex);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ prev_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+ /* Check if the list was empty */
+
+ if (!prev_entry)
+ {
+ nxrmutex_unlock(&mm->mm_map_mutex);
+ return -ENOENT;
+ }
+
+ /* Check if removing the first item */
+
+ if (entry == prev_entry)
+ {
+ sq_remfirst(&mm->mm_map_sq);
+ removed_entry = prev_entry;
+ }
+ else
+ {
+ /* Loop through the remaining items to find the one to be removed */
+
+ while ((removed_entry = (struct mm_map_entry_s *)
+ sq_next(((sq_entry_t *)prev_entry))))
+ {
+ if (entry == removed_entry)
+ {
+ sq_remafter((sq_entry_t *)prev_entry, &mm->mm_map_sq);
+ break;
+ }
+
+ prev_entry = removed_entry;
+ }
+ }
+
+ nxrmutex_unlock(&mm->mm_map_mutex);
+
+ /* If the item was removed, also delete the entry struct */
+
+ if (removed_entry)
+ {
+ kmm_free(removed_entry);
+ return OK;
+ }
+
+ return -ENOENT;
+}
+
+#endif /* defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) */
diff --git a/sched/group/group_create.c b/sched/group/group_create.c
index fe7533629a..ac31f659f9 100644
--- a/sched/group/group_create.c
+++ b/sched/group/group_create.c
@@ -245,6 +245,10 @@ void group_initialize(FAR struct task_tcb_s *tcb)
DEBUGASSERT(tcb && tcb->cmn.group);
group = tcb->cmn.group;
+ /* Allocate mm_map list if required */
+
+ mm_map_initialize(&group->tg_mm_map);
+
#ifdef HAVE_GROUP_MEMBERS
/* Assign the PID of this new task as a member of the group. */
diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c
index 2b1d11fdc0..4aa4797e78 100644
--- a/sched/group/group_leave.c
+++ b/sched/group/group_leave.c
@@ -176,6 +176,10 @@ static inline void group_release(FAR struct task_group_s *group)
env_release(group);
#endif
+ /* Destroy the mm_map list */
+
+ mm_map_destroy(&group->tg_mm_map);
+
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM)
/* Release any resource held by shared memory virtual page allocator */
[nuttx] 03/06: mm/shm: Remove gs_vaddr from task group and use dynamic vm_map instead
Posted by xi...@apache.org.
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 51509794888584d89432370da281753cfad8af09
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Tue Apr 12 16:34:50 2022 +0400
mm/shm: Remove gs_vaddr from task group and use dynamic vm_map instead
Replace static gs_vaddr with a new dynamic mapping list. Collecting all
this kind of virtual memory mappings into a single structure makes
things more consistent.
This still leaves the task group specific granule alloocator, gs_handle,
in the task group
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
include/nuttx/mm/shm.h | 25 ++++++++----
mm/shm/shmat.c | 40 ++++++++++++++++--
mm/shm/shmdt.c | 109 +++++++++++++++++++++++++++++++++----------------
3 files changed, 127 insertions(+), 47 deletions(-)
diff --git a/include/nuttx/mm/shm.h b/include/nuttx/mm/shm.h
index eeb9d14e55..b89db5bbd3 100644
--- a/include/nuttx/mm/shm.h
+++ b/include/nuttx/mm/shm.h
@@ -84,13 +84,6 @@ struct group_shm_s
*/
GRAN_HANDLE gs_handle;
-
- /* This array is used to do a reverse lookup: Give the virtual address
- * of a shared memory region, find the region index that performs that
- * mapping.
- */
-
- uintptr_t gs_vaddr[CONFIG_ARCH_SHM_MAXREGIONS];
};
/****************************************************************************
@@ -171,5 +164,23 @@ FAR void *shm_alloc(FAR struct task_group_s *group, FAR void *vaddr,
void shm_free(FAR struct task_group_s *group, FAR void *vaddr, size_t size);
+/****************************************************************************
+ * Name: shmdt_priv
+ *
+ * Description:
+ * This is the shmdt internal implementation of the shm driver. It takes
+ * the task group struct as a parameter and can handle both normal detach
+ * and cleanup during process exit.
+ *
+ * Input Parameters:
+ * group - A reference to the group structure from which to detach
+ * shmaddr - Virtual start address where the allocation starts.
+ * shmid - Id of the allocation
+ *
+ ****************************************************************************/
+
+int shmdt_priv(FAR struct task_group_s *group, FAR const void *shmaddr,
+ int shmid);
+
#endif /* CONFIG_MM_SHM */
#endif /* __INCLUDE_NUTTX_MM_SHM_H */
diff --git a/mm/shm/shmat.c b/mm/shm/shmat.c
index 590f68cdd3..9642729cc5 100644
--- a/mm/shm/shmat.c
+++ b/mm/shm/shmat.c
@@ -32,11 +32,32 @@
#include <nuttx/sched.h>
#include <nuttx/arch.h>
#include <nuttx/pgalloc.h>
+#include <nuttx/mm/map.h>
#include "shm/shm.h"
#ifdef CONFIG_MM_SHM
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int munmap_shm(FAR struct task_group_s *group,
+ FAR struct mm_map_entry_s *entry,
+ FAR void *start,
+ size_t length)
+{
+ FAR const void *shmaddr = entry->vaddr;
+ int shmid = entry->priv.i;
+
+ if (mm_map_remove(get_group_mm(group), entry))
+ {
+ shmerr("ERROR: mm_map_remove() failed\n");
+ }
+
+ return shmdt_priv(group, shmaddr, shmid);
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -103,6 +124,7 @@ FAR void *shmat(int shmid, FAR const void *shmaddr, int shmflg)
FAR void *vaddr;
unsigned int npages;
int ret;
+ struct mm_map_entry_s entry;
/* Get the region associated with the shmid */
@@ -114,9 +136,8 @@ FAR void *shmat(int shmid, FAR const void *shmaddr, int shmflg)
tcb = nxsched_self();
DEBUGASSERT(tcb && tcb->group);
+
group = tcb->group;
- DEBUGASSERT(group->tg_shm.gs_handle != NULL &&
- group->tg_shm.gs_vaddr[shmid] == 0);
/* Get exclusive access to the region data structure */
@@ -150,12 +171,23 @@ FAR void *shmat(int shmid, FAR const void *shmaddr, int shmflg)
goto errout_with_vaddr;
}
- /* Save the virtual address of the region. We will need that in shmat()
+ /* Save the virtual address of the region. We will need that in shmdt()
* to do the reverse lookup: Give the virtual address of the region to
* detach, we need to get the region table index.
*/
- group->tg_shm.gs_vaddr[shmid] = (uintptr_t)vaddr;
+ entry.vaddr = vaddr;
+ entry.length = region->sr_ds.shm_segsz;
+ entry.offset = 0;
+ entry.munmap = munmap_shm;
+ entry.priv.i = shmid;
+
+ ret = mm_map_add(&entry);
+ if (ret < 0)
+ {
+ shmerr("ERROR: mm_map_add() failed\n");
+ goto errout_with_vaddr;
+ }
/* Increment the count of processes attached to this region */
diff --git a/mm/shm/shmdt.c b/mm/shm/shmdt.c
index 1f24f2e55f..7878b70eec 100644
--- a/mm/shm/shmdt.c
+++ b/mm/shm/shmdt.c
@@ -33,6 +33,7 @@
#include <nuttx/sched.h>
#include <nuttx/mm/shm.h>
#include <nuttx/pgalloc.h>
+#include <nuttx/mm/map.h>
#include "shm/shm.h"
@@ -43,22 +44,23 @@
****************************************************************************/
/****************************************************************************
- * Name: shmdt
+ * Name: shmdt_priv
*
* Description:
- * The shmdt() function detaches the shared memory segment located at the
- * address specified by shmaddr from the address space of the calling
+ * The shmdt_priv() function detaches the shared memory segment located at
+ * the address specified by shmaddr from the address space of the calling
* process.
*
* Input Parameters:
* shmid - Shared memory identifier
+ * group - Current task_group, NULL during process exit
*
* Returned Value:
- * Upon successful completion, shmdt() will decrement the value of
+ * Upon successful completion, shmdt_priv() will decrement the value of
* shm_nattch in the data structure associated with the shared memory ID
* of the attached shared memory segment and return 0.
*
- * Otherwise, the shared memory segment will not be detached, shmdt()
+ * Otherwise, the shared memory segment will not be detached, shmdt_priv()
* will return -1, and errno will be set to indicate the error.
*
* - EINVAL
@@ -67,38 +69,14 @@
*
****************************************************************************/
-int shmdt(FAR const void *shmaddr)
+int shmdt_priv(FAR struct task_group_s *group, FAR const void *shmaddr,
+ int shmid)
{
FAR struct shm_region_s *region;
- FAR struct task_group_s *group;
- FAR struct tcb_s *tcb;
+ pid_t pid;
unsigned int npages;
- int shmid;
int ret;
- /* Get the TCB and group containing our virtual memory allocator */
-
- tcb = nxsched_self();
- DEBUGASSERT(tcb && tcb->group);
- group = tcb->group;
-
- /* Perform the reverse lookup to get the shmid corresponding to this
- * shmaddr.
- */
-
- for (shmid = 0;
- shmid < CONFIG_ARCH_SHM_MAXREGIONS &&
- group->tg_shm.gs_vaddr[shmid] != (uintptr_t)shmaddr;
- shmid++);
-
- if (shmid >= CONFIG_ARCH_SHM_MAXREGIONS)
- {
- shmerr("ERROR: No region matching this virtual address: %p\n",
- shmaddr);
- ret = -EINVAL;
- goto errout_with_errno;
- }
-
/* Get the region associated with the shmid */
region = &g_shminfo.si_region[shmid];
@@ -113,6 +91,16 @@ int shmdt(FAR const void *shmaddr)
goto errout_with_errno;
}
+ if (!group)
+ {
+ pid = 0;
+ goto on_process_exit;
+ }
+ else
+ {
+ pid = group->tg_pid;
+ }
+
/* Free the virtual address space */
shm_free(group, (FAR void *)shmaddr, region->sr_ds.shm_segsz);
@@ -131,9 +119,7 @@ int shmdt(FAR const void *shmaddr)
shmerr("ERROR: up_shmdt() failed\n");
}
- /* Indicate that there is no longer any mapping for this region. */
-
- group->tg_shm.gs_vaddr[shmid] = 0;
+on_process_exit:
/* Decrement the count of processes attached to this region.
* If the count decrements to zero and there is a pending unlink,
@@ -162,7 +148,7 @@ int shmdt(FAR const void *shmaddr)
/* Save the process ID of the last operation */
- region->sr_ds.shm_lpid = tcb->pid;
+ region->sr_ds.shm_lpid = pid;
/* Save the time of the last shmdt() */
@@ -178,4 +164,55 @@ errout_with_errno:
return ERROR;
}
+int shmdt(FAR const void *shmaddr)
+{
+ FAR struct tcb_s *tcb;
+ FAR struct mm_map_entry_s *entry;
+ FAR struct task_group_s *group;
+ int shmid;
+ int ret;
+
+ /* Get the TCB and group containing our virtual memory allocator */
+
+ tcb = nxsched_self();
+ DEBUGASSERT(tcb && tcb->group);
+ group = tcb->group;
+
+ /* Get exclusive access to process' mm_map */
+
+ ret = mm_map_lock();
+ if (ret == OK)
+ {
+ /* Perform the reverse lookup to get the shmid corresponding to this
+ * shmaddr. The mapping is matched with just shmaddr == map->vaddr.
+ */
+
+ entry = mm_map_find(shmaddr, 1);
+ if (!entry || entry->vaddr != shmaddr)
+ {
+ ret = -EINVAL;
+ shmerr("ERROR: No region matching this virtual address: %p\n",
+ shmaddr);
+
+ mm_map_unlock();
+ return -EINVAL;
+ }
+
+ shmid = entry->priv.i;
+
+ /* Indicate that there is no longer any mapping for this region. */
+
+ if (mm_map_remove(get_group_mm(group), entry) < 0)
+ {
+ shmerr("ERROR: mm_map_remove() failed\n");
+ }
+
+ mm_map_unlock();
+
+ ret = shmdt_priv(tcb->group, shmaddr, shmid);
+ }
+
+ return ret;
+}
+
#endif /* CONFIG_MM_SHM */
[nuttx] 04/06: fs/mmap: Add mappings to mm_map list if CONFIG_MM_MAP is defined
Posted by xi...@apache.org.
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 dd97900221a84a2dc50ff229176fd14577ae9604
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Fri Apr 8 11:31:24 2022 +0400
fs/mmap: Add mappings to mm_map list if CONFIG_MM_MAP is defined
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
fs/mmap/fs_mmap.c | 80 ++++++++++++++++++++++++++++++++++++++++++-----------
fs/mmap/fs_munmap.c | 28 ++++++++++++++++++-
2 files changed, 91 insertions(+), 17 deletions(-)
diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index 36e710ad23..4f541fffe9 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -41,6 +41,46 @@
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: unmap_anonymous
+ ****************************************************************************/
+
+static int unmap_anonymous(FAR struct task_group_s *group,
+ FAR struct mm_map_entry_s *entry,
+ FAR void *start,
+ size_t length)
+{
+ int ret;
+
+ /* De-allocate memory.
+ * NB: This is incomplete anounymous mapping implementation
+ * see file_mmap_ below
+ */
+
+ if (start == entry->vaddr && length == entry->length)
+ {
+ /* entry->priv marks allocation from kernel heap */
+
+ if (entry->priv.i)
+ {
+ kmm_free(start);
+ }
+ else
+ {
+ kumm_free(start);
+ }
+
+ ret = mm_map_remove(group, &entry);
+ }
+ else
+ {
+ ret = -EINVAL;
+ ferr("ERROR: Unknown map type\n");
+ }
+
+ return ret;
+}
+
/****************************************************************************
* Name: file_mmap_
****************************************************************************/
@@ -51,6 +91,23 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
{
int ret;
+ /* Pass the information about the mapping in mm_map_entry_s structure.
+ * The driver may alter the structure, and if it supports unmap, it
+ * will also add it to the kernel maintained list of mappings.
+ */
+
+ struct mm_map_entry_s entry =
+ {
+ NULL, /* sq_entry_t */
+ start,
+ length,
+ offset,
+ prot,
+ flags,
+ { NULL }, /* priv.p */
+ NULL /* munmap */
+ };
+
/* Since only a tiny subset of mmap() functionality, we have to verify many
* things.
*/
@@ -120,6 +177,11 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
return -ENOMEM;
}
+ entry.vaddr = *mapped;
+ entry.munmap = unmap_anonymous;
+ entry.priv.i = kernel;
+ mm_map_add(&entry);
+
return OK;
}
@@ -140,24 +202,10 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
if (filep->f_inode && filep->f_inode->u.i_ops->mmap != NULL)
{
- /* Pass the information about the mapping in mm_map_entry_s structure.
- * The driver may alter the structure, and if it supports unmap, it
- * will also add it to the kernel maintained list of mappings.
- */
-
- struct mm_map_entry_s map =
- {
- NULL, /* sq_entry_t */
- start, length, offset,
- prot, flags,
- NULL, /* priv */
- NULL /* munmap */
- };
-
- ret = filep->f_inode->u.i_ops->mmap(filep, &map);
+ ret = filep->f_inode->u.i_ops->mmap(filep, &entry);
if (ret == OK)
{
- *mapped = (void *)map.vaddr;
+ *mapped = (void *)entry.vaddr;
}
}
else
diff --git a/fs/mmap/fs_munmap.c b/fs/mmap/fs_munmap.c
index 7b8e57d492..85ec132876 100644
--- a/fs/mmap/fs_munmap.c
+++ b/fs/mmap/fs_munmap.c
@@ -23,6 +23,7 @@
****************************************************************************/
#include <nuttx/config.h>
+#include <nuttx/mm/map.h>
#include <sys/types.h>
#include <sys/mman.h>
@@ -158,7 +159,32 @@ errout_with_lock:
nxmutex_unlock(&g_rammaps.lock);
return ret;
#else
- return OK;
+
+ FAR struct tcb_s *tcb = nxsched_self();
+ FAR struct task_group_s *group = tcb->group;
+ FAR struct mm_map_entry_s *entry = NULL;
+ int ret = OK;
+
+ /* Iterate through all the mappings and call the underlying
+ * unmap for every mapping where "start" lies
+ * break loop on any errors.
+ *
+ * Get exclusive access to mm_map for this
+ */
+
+ ret = mm_map_lock();
+ if (ret == OK)
+ {
+ while (ret == OK && (entry = mm_map_find(start, length)))
+ {
+ DEBUGASSERT(entry->munmap);
+ ret = entry->munmap(group, entry, start, length);
+ }
+
+ mm_map_unlock();
+ }
+
+ return ret;
#endif /* CONFIG_FS_RAMMAP */
}
[nuttx] 06/06: Move rammaps to use mm_map list
Posted by xi...@apache.org.
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 */
[nuttx] 01/06: include/nuttx/mm/map.h: Change mm_map_entry "priv" into union type
Posted by xi...@apache.org.
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 6e4ddf78bb8bd7c06fb5b5b3a43c65248a5a6778
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Tue Jan 3 15:06:39 2023 +0400
include/nuttx/mm/map.h: Change mm_map_entry "priv" into union type
To be able to directly store also other than pointer types
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
include/nuttx/mm/map.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h
index ffb4d18fbc..f845054e34 100644
--- a/include/nuttx/mm/map.h
+++ b/include/nuttx/mm/map.h
@@ -49,7 +49,11 @@ struct mm_map_entry_s
off_t offset;
int prot;
int flags;
- FAR void *priv;
+ union
+ {
+ FAR void *p;
+ int i;
+ } priv;
/* Drivers which register mappings may also
* implement the unmap function to undo anything done in mmap.
[nuttx] 05/06: Move anonymous mapping emulation into own module under fs/mmap
Posted by xi...@apache.org.
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 a5ed8014e876242cb9bea12499fef74ac0bfa76b
Author: Jukka Laitinen <ju...@ssrc.tii.ae>
AuthorDate: Mon Jan 9 12:02:24 2023 +0400
Move anonymous mapping emulation into own module under fs/mmap
Signed-off-by: Jukka Laitinen <ju...@ssrc.tii.ae>
---
fs/mmap/Kconfig | 7 +++-
fs/mmap/Make.defs | 4 ++
fs/mmap/fs_anonmap.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
fs/mmap/fs_anonmap.h | 61 +++++++++++++++++++++++++++
fs/mmap/fs_mmap.c | 61 +--------------------------
5 files changed, 186 insertions(+), 61 deletions(-)
diff --git a/fs/mmap/Kconfig b/fs/mmap/Kconfig
index b4551376e4..6732b8e89d 100644
--- a/fs/mmap/Kconfig
+++ b/fs/mmap/Kconfig
@@ -23,5 +23,8 @@ config FS_RAMMAP
See nuttx/fs/mmap/README.txt for additional information.
-if FS_RAMMAP
-endif
+config FS_ANONMAP
+ bool "Anonymous mapping emulation"
+ default y
+ ---help---
+ Simulate private anonymous mappings by plain malloc
diff --git a/fs/mmap/Make.defs b/fs/mmap/Make.defs
index ab8cbd05e4..dff6e732b8 100644
--- a/fs/mmap/Make.defs
+++ b/fs/mmap/Make.defs
@@ -24,6 +24,10 @@ ifeq ($(CONFIG_FS_RAMMAP),y)
CSRCS += fs_rammap.c
endif
+ifeq ($(CONFIG_FS_ANONMAP),y)
+CSRCS += fs_anonmap.c
+endif
+
# Include MMAP build support
DEPPATH += --dep-path mmap
diff --git a/fs/mmap/fs_anonmap.c b/fs/mmap/fs_anonmap.c
new file mode 100644
index 0000000000..534806e9af
--- /dev/null
+++ b/fs/mmap/fs_anonmap.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * fs/mmap/fs_anonmap.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 <nuttx/config.h>
+#include <nuttx/kmalloc.h>
+#include <debug.h>
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: unmap_anonymous
+ ****************************************************************************/
+
+static int unmap_anonymous(FAR struct task_group_s *group,
+ FAR struct mm_map_entry_s *entry,
+ FAR void *start,
+ size_t length)
+{
+ int ret;
+
+ /* De-allocate memory.
+ * NB: This is incomplete anounymous mapping implementation
+ * see file_mmap_ below
+ */
+
+ if (start == entry->vaddr && length == entry->length)
+ {
+ /* entry->priv marks allocation from kernel heap */
+
+ if (entry->priv.i)
+ {
+ kmm_free(start);
+ }
+ else
+ {
+ kumm_free(start);
+ }
+
+ ret = mm_map_remove(get_group_mm(group), entry);
+ }
+ else
+ {
+ ret = -EINVAL;
+ ferr("ERROR: Unknown map type\n");
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int map_anonymous(FAR struct mm_map_entry_s *entry, bool kernel)
+{
+ int ret;
+
+ /* REVISIT: Should reside outside of the heap. That is really the
+ * only purpose of MAP_ANONYMOUS: To get non-heap memory. In KERNEL
+ * build, this could be accomplished using pgalloc(), provided that
+ * you had logic in place to assign a virtual address to the mapping.
+ */
+
+ entry->vaddr = kernel ?
+ kmm_zalloc(entry->length) : kumm_zalloc(entry->length);
+ if (entry->vaddr == NULL)
+ {
+ ferr("ERROR: kumm_alloc() failed, enable DEBUG_MM for info!\n");
+ return -ENOMEM;
+ }
+
+ entry->munmap = unmap_anonymous;
+ entry->priv.i = kernel;
+
+ ret = mm_map_add(entry);
+ if (ret < 0)
+ {
+ if (kernel)
+ {
+ kmm_free(entry->vaddr);
+ }
+ else
+ {
+ kumm_free(entry->vaddr);
+ }
+
+ entry->vaddr = NULL;
+ }
+
+ return ret;
+}
diff --git a/fs/mmap/fs_anonmap.h b/fs/mmap/fs_anonmap.h
new file mode 100644
index 0000000000..70725c5623
--- /dev/null
+++ b/fs/mmap/fs_anonmap.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ * fs/mmap/fs_anonmap.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_MMAP_FS_ANONMAP_H
+#define __FS_MMAP_FS_ANONMAP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <nuttx/mm/map.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: map_anonymous
+ *
+ * Description:
+ * Support simulation of private anonymous mapping by allocating memory
+ * from heap
+ *
+ * Input Parameters:
+ * map Input struct containing user request
+ * kernel kmm_zalloc or kumm_zalloc
+ *
+ * Returned Value:
+ * On success returns 0. Otherwise negated errno is returned appropriately.
+ *
+ * ENOMEM
+ * Insufficient memory is available to simulate mapping
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FS_ANONMAP
+int map_anonymous(FAR struct mm_map_entry_s *entry, bool kernel);
+#else
+#define map_anonymous(entry,kernel) (-ENOSYS)
+#endif /* CONFIG_FS_ANONMAP */
+
+#endif /* __FS_MMAP_FS_ANONMAP_H */
diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index 4f541fffe9..e0f81f53a9 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -36,51 +36,12 @@
#include "inode/inode.h"
#include "fs_rammap.h"
+#include "fs_anonmap.h"
/****************************************************************************
* Private Functions
****************************************************************************/
-/****************************************************************************
- * Name: unmap_anonymous
- ****************************************************************************/
-
-static int unmap_anonymous(FAR struct task_group_s *group,
- FAR struct mm_map_entry_s *entry,
- FAR void *start,
- size_t length)
-{
- int ret;
-
- /* De-allocate memory.
- * NB: This is incomplete anounymous mapping implementation
- * see file_mmap_ below
- */
-
- if (start == entry->vaddr && length == entry->length)
- {
- /* entry->priv marks allocation from kernel heap */
-
- if (entry->priv.i)
- {
- kmm_free(start);
- }
- else
- {
- kumm_free(start);
- }
-
- ret = mm_map_remove(group, &entry);
- }
- else
- {
- ret = -EINVAL;
- ferr("ERROR: Unknown map type\n");
- }
-
- return ret;
-}
-
/****************************************************************************
* Name: file_mmap_
****************************************************************************/
@@ -164,25 +125,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
if ((flags & MAP_ANONYMOUS) != 0)
{
- /* REVISIT: Should reside outside of the heap. That is really the
- * only purpose of MAP_ANONYMOUS: To get non-heap memory. In KERNEL
- * build, this could be accomplished using pgalloc(), provided that
- * you had logic in place to assign a virtual address to the mapping.
- */
-
- *mapped = kernel ? kmm_zalloc(length) : kumm_zalloc(length);
- if (*mapped == NULL)
- {
- ferr("ERROR: kumm_alloc() failed, enable DEBUG_MM for info!\n");
- return -ENOMEM;
- }
-
- entry.vaddr = *mapped;
- entry.munmap = unmap_anonymous;
- entry.priv.i = kernel;
- mm_map_add(&entry);
-
- return OK;
+ return map_anonymous(&entry, kernel);
}
if ((flags & MAP_PRIVATE) != 0)