You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2023/01/03 14:09:18 UTC

[GitHub] [nuttx] jlaitine opened a new pull request, #8026: Add mm map

jlaitine opened a new pull request, #8026:
URL: https://github.com/apache/nuttx/pull/8026

   ## Summary
   
   This PR adds a simple linked list to store mmap mappings, to support unmap.
   
   The drivers which want to store mappings can "select MM_MAP" and use mm_map_add and mm_map_rm to register/unregister mappings to the task_group.
   
   This PR also takes the mm_map into use in mm/shm driver and anonymous mappings. The sys-v shm interface still maintains it's own granule allocator in task_group
   
   ## Impact
   
   Adds interface to make it possible to do munmap
   Adds munmap for anonymous mappings
   Fixes mm/shm for process exit; previously it doesn't free the reserved physical pages if they are mapped at process exit
   
   ## Testing
   
   Tested in stm32 and mpfs riscv builds, together with inhouse posix shmfs driver
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1370738483

   > > BTW, it's better to migrate the ram map and anon map to the new interface, which is clearer and also demo that new mmap interface is flexible enough to support the complex case.
   > 
   > Agree. I can move ram mapping (MAP_PRIVATE, MAP_ANONYMOUS) to an own file at least. It should also have an own CONFIG flag (can make it default to y to keep current functionality). I find this interface quite useless as it is now, it doesn't even support mapping from page pool.
   > 
   
   Yes, but it's useful for no MMU case. it's a first step to incorporate rammap into the new mmap interface. Once it's done, we can support page pool for MMU.
   
   > rammaps deserve an own PR, but I'll see if I can make use of the mm_map in it already as you suggested above. That sould be extended to also support MAP_SHARED. I find this interface quite useless as it is now, and this is why I don't like touching it too much in this PR.
   > 
   
   supporting MAP_SHARED require we save some mapping info to inode.
   
   > I think that after we agree on the interface for storing the mappings, 
   
   Yes, I think so.
   
   >I will present the posix SHMFS; this is an interface that I know is interesting to many. For example we have implemented an own version of PX4 uORB publish subscribe interface with this, and it is really nice, since it works inter process both in linux and nuttx (in all flat, protected and kernel). There are also other pubsub interfaces which could utilize this.
   
   Nice feature. Where can I find the document or source code? is it bas on PX4 uORB or this new one: https://github.com/apache/nuttx/pull/6653


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061396990


##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,44 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   nxmutex_unlock(&g_rammaps.lock);
   return ret;
 #else
+
+#ifdef CONFIG_MM_MAP
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_entry_s *map = 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
+   */
+
+  mm_map_lock(group);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061194065


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !vaddr_in_area(vaddr, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ *   Find the first mapping matching address and length
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+                                             size_t length)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && vaddr != map->vaddr && length != map->length)
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_rm
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_rm(FAR struct task_group_s *group,
+              FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      nxmutex_unlock(&mm->mm_map_mutex);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))

Review Comment:
   just to save memory one pointer in every map_entry. I don't think that munmap is time critical (it is never real time anyhow).
   
   Since munmap does need to always go through all the mappings it is algorithmically O(n^2) anyways, even if you used RBT here ( would become O(n) * O(log n) ) since even in that case you'd have to start search again after every found mapping in munmap.
   
   Normally you'll anyways have just a couple of mathing mappings, so "typically" this is just linear; that is, in case of N matching entries you go through the list N+1 times. In normal case you map an area once, so with sq you got through the list twice, whereas with dq you'd go through it once. Not significant at least for me.
   
   If someone, someday, wants to do e.g. RBT for this, it would consume 3 pointers + color.... At this point I don't see that necessary and it is somewhat complicated due to 2 keys (start and length)
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063468888


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   why not get from the current task? mm_map_s equals to task_group_s in this context.



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   why not get from the current task



##########
mm/shm/shmdt.c:
##########
@@ -113,6 +91,16 @@ int shmdt(FAR const void *shmaddr)
       goto errout_with_errno;
     }
 
+  if (!group)

Review Comment:
   so it isn't perfect:(.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062159098


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   I measured the difference to have it always included on nucleo-f091rc:nsh
   
   With mapping code always included the size is 40612 bytes, and without it is  40492 bytes. The difference is just 120 bytes in code, which originates from fs_mumap.c.
   
   So I think it is ok to remove the flag and have it always included. Will do that
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063317621


##########
fs/mmap/fs_rammap.c:
##########
@@ -44,12 +41,81 @@
  * 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 *map_entry,
+                        FAR void *start,
+                        size_t length)
 {
-  NXMUTEX_INITIALIZER
-};
+  FAR void *newaddr;
+  unsigned int offset;
+  bool kernel = map_entry->priv.i != 0 ? true : false;
+
+  /* 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 - map_entry->vaddr;
+  if (offset + length < map_entry->length)
+    {
+      ferr("ERROR: Cannot umap without unmapping to the end\n");
+      return -ENOSYS;
+    }
+
+  /* Okay.. the region is beging umapped to the end.  Make sure the length

Review Comment:
   supposed to be "unmapped", thanks, fixed :)



##########
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 has been copied to memory and

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064470936


##########
fs/mmap/fs_mmap.c:
##########
@@ -140,20 +145,6 @@ 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);

Review Comment:
   but the caller who call munmap will report the error now. BTW, the new complex driver may need to clear up the resource in munmap callback.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065772178


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   I added https://github.com/apache/nuttx/pull/8068 to clean it up



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062159525


##########
mm/Kconfig:
##########
@@ -257,4 +257,8 @@ config MM_PANIC_ON_FAILURE
 	default n
 	depends on DEBUG_MM
 
+config MM_MAP

Review Comment:
   I measured the difference to have it always included on nucleo-f091rc:nsh
   
   With mapping code always included the size is 40612 bytes, and without it is 40492 bytes. The difference is just 120 bytes in code, which originates from fs_mumap.c.
   
   So I think it is ok to remove the flag and have it always included. Will do that



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062150946


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   If you insist that we add the group as a parameter here, I can do. It just can't be anything else than currently running one IMHO. Please let me know if this is mandatory?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065630233


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   System-V shm driver (mm/shm/) have to naturally implement the system-v interfaces (shmget, shmat, shmdt etc...). Of course, when that interface creates memory mappings, we have then two ways of deleting the mappings (posix unmap & system-v shmdt).
   
   We can try to clean up the system-v shm interface, but I'd like to rather bring in the posix shm interface next, which I find more useful and interesting.
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063397722


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   Nowhere any more. I don't think that it has any use any more, this has been changed so many times. I'll just remove it



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063315629


##########
fs/mmap/fs_anonmap.h:
##########
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * 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 negatet errno is returned appropriately.

Review Comment:
   thanks, fixed



##########
fs/mmap/fs_rammap.c:
##########
@@ -44,12 +41,81 @@
  * 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 *map_entry,
+                        FAR void *start,
+                        size_t length)
 {
-  NXMUTEX_INITIALIZER
-};
+  FAR void *newaddr;
+  unsigned int offset;
+  bool kernel = map_entry->priv.i != 0 ? true : false;
+
+  /* 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

Review Comment:
   thanks, fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061175458


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   we can, but shouldn't do.
   
   - for uintptr_t it is ok, but uintptr_t is not C89/90  (and is optional even in newer)
   - direct cast between int and void * is illegal in principle (different size, some compilers even warn about this: "cast from pointer to integer of different size")
   - it is much cleaner to type priv.p = ptr; and priv.i = i; than adding typecasts
   - using union is extendable to other types without breaking any existing functionality
   - most importantly, I like it like this ;)
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061323025


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   > the lock tries to protect the sq modifications. In a multi-threaded application separate threads can do mmap/munmap simultanously.
   > 
   
   Yes, but it's unsafe to return the entry after locking. The caller of mm_map_find_contains which touch the returned value will suffer the race condition.
   
   > But it is right that since mm_map_remove takes a direct reference to map, it needs to be locked also above in some cases to protect the queue.
   > 
   > I'll fix the locking
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061372433


##########
mm/shm/shmat.c:
##########
@@ -32,11 +32,43 @@
 #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 *map,
+                      FAR void *start,
+                      size_t length)
+{
+  int ret;
+
+  if (group)
+    {
+      /* Normal "unmap", let the shmdt do the work */
+
+      ret = shmdt(start);
+    }
+  else
+    {
+      /* Address environment is being deleted, and the group is not current.
+       * Get shmid from map->priv and only free the pages, don't touch any
+       * mappings
+       */
+
+      shm_destroy(map->priv.i);

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061372041


##########
fs/mmap/fs_mmap.c:
##########
@@ -42,6 +42,50 @@
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: unmap_anonymous
+ ****************************************************************************/
+
+#ifdef CONFIG_MM_MAP
+static int unmap_anonymous(FAR struct task_group_s *group,
+                           FAR struct mm_map_entry_s *map,
+                           FAR void *start,
+                           size_t length)
+{
+  /* "priv" field stores whether the allocation is done in kernel */

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061392888


##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,44 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   nxmutex_unlock(&g_rammaps.lock);
   return ret;
 #else
+
+#ifdef CONFIG_MM_MAP
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_entry_s *map = 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
+   */
+
+  mm_map_lock(group);

Review Comment:
   I'll ad a check on lock return value here still



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061691266


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)

Review Comment:
   I think we can



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1060776537


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));

Review Comment:
   don't need



##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   why need add i field? we can always assign an integer to pointer:
   priv = (FAR void *)(uinptr_t)i;



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)

Review Comment:
   why need cast to (void *)?



##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task
+ *   group's list
+ *
+ * Input Parameters:
+ *   vaddr   - Address within the mapped area
+ *
+ * Returned Value:
+ *   Pointer to the mapping, NULL if not found
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr);
+
+/****************************************************************************
+ * 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_rm
+ *
+ * Description:
+ *   Removes a virtual memory area from the list of mappings
+ *   Sets the given pointer argument to a value which can be used to continue
+ *   iteration (previous or NULL)
+ *
+ * Input Parameters:
+ *   group   - Pointer to current task_group_s. NULL in process exit case
+ *   map     - Pointer to a pointer to the mapping to be removed
+ *
+ * Returned Value:
+ *   OK:       Removed succesfully
+ *   -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_rm(FAR struct task_group_s *group,

Review Comment:
   mm_map_remove



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;

Review Comment:
   why not?
   
   1. kmm_malloc entry in the first place
   2. or kmm_malloc here and return



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   the lock doesn't fix any race condition, it's always unsafe to hold an entry without lock



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !vaddr_in_area(vaddr, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ *   Find the first mapping matching address and length
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+                                             size_t length)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && vaddr != map->vaddr && length != map->length)
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_rm
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_rm(FAR struct task_group_s *group,
+              FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      nxmutex_unlock(&mm->mm_map_mutex);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))

Review Comment:
   why not use dq_entry to avoid the loop



##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +160,38 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   nxmutex_unlock(&g_rammaps.lock);
   return ret;
 #else
+
+#ifdef CONFIG_MM_MAP

Review Comment:
   let's remove g_rammaps and reuse tg_mm_map, to avoid the code duplication



##########
mm/Kconfig:
##########
@@ -257,4 +257,8 @@ config MM_PANIC_ON_FAILURE
 	default n
 	depends on DEBUG_MM
 
+config MM_MAP

Review Comment:
   the basic map code need always exist, otherwise many drivers willn't work



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>

Review Comment:
   remove the header files which are already included in mm/map.h



##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task
+ *   group's list
+ *
+ * Input Parameters:
+ *   vaddr   - Address within the mapped area
+ *
+ * Returned Value:
+ *   Pointer to the mapping, NULL if not found
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr);

Review Comment:
   why not only define mm_map_find?



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);

Review Comment:
   let's merge if/else block into one



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !vaddr_in_area(vaddr, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ *   Find the first mapping matching address and length
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+                                             size_t length)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && vaddr != map->vaddr && length != map->length)
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   ditto, if you want to avoid the race condition, you have to hold the lock until you don't touch map.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063431469


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   And yes, you are absolutely right. These two shouldn't be mixed. I want to stick to 2., but have an exception for mm_map_remove for the practical reason that process exit case cannot be handled without some extra argument indicating that the context is not valid
   
   But this argument doesn't need to be "group", it could as well be a boolean flag "on_process_exit" or such, if you prefer. Passing group is simpler for driver developer, because otherwise he/she needs to determine the process exit case himself by checking the group passed to "unmap" function "group ? true : false"



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063505448


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   no, it is not. At the time when group is being deleted, it is not scheduled to run any more, so it is not the readytorun list. But we could pass the group here, the same as when initializing, if it looks better. It doesn't really matter to me whether you pass the group or map here.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063129078


##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);

Review Comment:
   FAR struct mm_map_s *map



##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);

Review Comment:
   FAR struct mm_map_s *map



##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   or use mm_map_s as the first argument. it's better to decouple the function of mm_map_s/mm_map_entry_s from task_group_s, which mean all functions in mm/map.h require the first argument is mm_map_s except mm_map_next.



##########
fs/mmap/fs_anonmap.h:
##########
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * 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 negatet 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 *map, bool kernel);
+#else
+static inline int map_anonymous(FAR struct mm_map_entry_s *map, bool kernel)

Review Comment:
   define macro to avoid using c89 extension in the common code



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   where we will use the returned value?



##########
mm/shm/shmdt.c:
##########
@@ -113,6 +91,16 @@ int shmdt(FAR const void *shmaddr)
       goto errout_with_errno;
     }
 
+  if (!group)

Review Comment:
   group is impossible NULL with the check at line 182



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064456982


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   Getting info from current task. Accessing group struct belongs in sched, so added a macros into sched.h to get the current mm and mm from group.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064462401


##########
fs/mmap/fs_rammap.h:
##########
@@ -53,29 +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

Review Comment:
   I just moved the comment to to top of the file, it was originally describing functionality of the structure which was removed. Now it describes the functionality of the whole driver



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065590789


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   but why not reuse mumap implementation? BTW, will you refine shm driver in the upcoming patch?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065702612


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   Yes, I think it will be much better if we can:
   
   1. Share the same code base for both posix and system-v shm interface(e.g. shmget->shm_open, shmat->mmap, shmctl->ioctl, shmdt->shm_unlink).
   2. Share the same code path between posix shm and other drivers (e.g., fb and video), so mmap/munmap don't need handle shm specially.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065404814


##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR 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;
+
+  if (!mm || !entry)
+    {
+      return OK;
+    }
+
+  int 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);
+      *entry = NULL;

Review Comment:
   Sure. The idea for that was lost long ago. Done.



##########
include/nuttx/sched.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 group_get_mm(group)          (group ? &group->tg_mm_map : NULL)

Review Comment:
   done



##########
include/nuttx/sched.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 group_get_mm(group)          (group ? &group->tg_mm_map : NULL)
+
+/* Get a pointer to current the process' memory map struct */
+
+#define get_current_mm()             (group_get_mm(nxsched_self()->group))

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063449856


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,326 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = nxrmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * Just delete the entry
+       */
+

Review Comment:
   now there is a bug introduced here at some point. Should set r = *map in this place. Will fix



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063513004


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   so, that's why I prefer the first approach, which is more consistent. There are many exceptions you can't use the current task.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063428645


##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);

Review Comment:
   Removed "group" argument. You always lock your own, the currently running memory maps



##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);

Review Comment:
   Removed "group" argument. You always lock your own, the currently running memory maps



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065468467


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   There are two ways to unmap the shm region by the user. sysv "shmdt" call (see "man shmdt"), and "unmap" call. 
   
   - sysv "shmdt" call is always done during normal user process execution
   - unmap call could be done during normal process execution (but normally you'd use the shmdt if using this interface)
   - unmap call can be done during proceess exit, if user has left the memory unmapped, or process dies unexpectedly
   
   shmdt_priv is the common function which does the actual work for all cases.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063411826


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   It is no point in adding group or map as the first argument for any functions in mm_map. You always work with currently running process' maps, and there is just no point in passing that as an argument. In fact, it is bad, because someone might think that he/she could start tinkering with some other process mappings, which is just never possible.
   
   Only exception is the mapping removal, because then the context may be in fact invalid and shouldn't be used at all for anything. Thats why the group is being passed there so that the drivers can check if it is NULL. If it is not NULL, it is always the current of course. I agree that it is maybe not the cleanest solution, but for the mm_map_remove function there just has to be some way to pass the info that the context is invalid. Because that really happens at process destruction, and cleanup of kernel resources is still required.
   
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065630233


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   System-V shm driver (mm/shm/) have to naturally implement the system-v interfaces (shmget, shmat, shmdt etc...). Of course, when that interface creates memory mappings, we have then two ways of deleting the mappings (posix unmap & system-v shmdt).
   
   But I see what you mean, we could just implement shm_unmap and call that from the shmdt. It would maybe make the code a bit cleaner, but I tried to avoid changing existing shm driver too much. For me, system-v interfaces are obsolete...
   
   We can try to clean up the system-v shm interface, but I'd like to rather bring in the posix shm interface next, which I find more useful and interesting.
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065405960


##########
fs/mmap/fs_rammap.c:
##########
@@ -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(group_get_mm(group), &entry);

Review Comment:
   I don't care, if you insist we can do it. My thinking is that it can still fail. Not done yet.



##########
fs/mmap/Kconfig:
##########
@@ -25,3 +25,9 @@ config FS_RAMMAP
 
 if FS_RAMMAP

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061194774


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   I think that it would be very strange use case. With real MMU you'd have to switch address environments to do that mapping. In which case you could map memory for some other process?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061196819


##########
mm/Kconfig:
##########
@@ -257,4 +257,8 @@ config MM_PANIC_ON_FAILURE
 	default n
 	depends on DEBUG_MM
 
+config MM_MAP

Review Comment:
   This is a trade off between granularity and simplicity. For now there are just a few drivers which can make use of memory maps & unmap feature.
   
   But always enabling this increases code size for all targets, I don't want to do it at this point.
   
   Having a separate config for it only means that features which use that select it.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061373239


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));

Review Comment:
   removed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1060621034


##########
fs/mmap/fs_mmap.c:
##########
@@ -42,6 +42,50 @@
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: unmap_anonymous
+ ****************************************************************************/
+
+#ifdef CONFIG_MM_MAP
+static int unmap_anonymous(FAR struct task_group_s *group,
+                           FAR struct mm_map_entry_s *map,
+                           FAR void *start,
+                           size_t length)
+{
+  /* "priv" field stores whether the allocation is done in kernel */

Review Comment:
   This comment was accidentally left in wrong place, will correct



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065404972


##########
fs/mmap/fs_rammap.h:
##########
@@ -53,29 +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/mutex.h>

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065461901


##########
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 -ENOENT;

Review Comment:
   Oops. Some fumble, fixed



##########
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 -ENOENT;
+    }
+
+  return OK;

Review Comment:
   Oops. Some fumble, fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 merged pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 merged PR #8026:
URL: https://github.com/apache/nuttx/pull/8026


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063431469


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   And yes, you are absolutely right. These two shouldn't be mixed. I want to stick to 2., but have an exception for mm_map_remove for the practical reason that process exit case cannot be handled without some extra argument indicating that the context is not valid
   
   But this argument doesn't need to be "group", it could as well be a boolean flag "on_process_exit" or such, if you prefer



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063431469


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   And yes, you are absolutely right. These two shouldn't be mixed. I want to stick to 2., but have an exception for mm_map_remove for the practical reason that process exit case cannot be handled without some extra argument indicating that the context is not valid



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063394016


##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);

Review Comment:
   I find it more logical to lock mappings of a group, than first having to dig out the actual map from inside the group, in every place where you do that...



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061698798


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   A process can never inject new mappings to another process' address space. That wouldn't make sense. The only reason why kernel internal munmap has it here is because group can't be used during process exit. So we are passing NULL during process exit
   
   can you give an example of a (posix) interface which would require mapping to another process' address space? I am not aware of any OS that would do that, even inside kernel.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1370475861

   BTW, it's better to migrate the ram map and anon map to the new interface, which is clearer and also demo that new mmap interface is flexible enough to support the complex case.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061188946


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   the lock protects th sq modifications. In a multi-threaded application separate threads can do mmap/munmap simultanously. Other parts of the single map_entry don't need to be protected. The queue modifications are only done in these functions, and that's why the mutex is there.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061188946


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   the lock tries to protect the sq modifications. In a multi-threaded application separate threads can do mmap/munmap simultanously.
   
   But it is right that since mm_map_remove takes a direct reference to map, it needs to be locked also above in some cases to protect the queue.
   
   I'll fix the locking
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061321619


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   > we can, but shouldn't do.
   > 
   > * for uintptr_t it is ok, but uintptr_t is not C89/90  (and is optional even in newer)
   
   C89 require is for toolchain which means we can't use the compiler specific new feature. But since libc is provided by NuttX self, we can use C99 or even newer library feature in common code if NuttX's libc provide the support. 
   
   > * direct cast between int and void * is illegal in principle (different size, some compilers even warn about this: "cast from pointer to integer of different size")
   > * it is much cleaner to type priv.p = ptr; and priv.i = i; than adding typecasts
   > * using union is extendable to other types without breaking any existing functionality
   > * most importantly, I like it like this ;)
   
   if you want uintptr_t is better than int.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] acassis commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061450789


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   @jlaitine @xiaoxiang781216 good point about uintptr_t, note that it is widespread in many places inside nuttx/drivers/, nuttx/wireless/ and even inside nuttx/tools/. Since we are not testing it on any board that really requires C89, what you think if we force the NuttX Simulator to use C89?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1060842580


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   it's better to add task_group_s as an explicit argument since it's very use to create a mapping for other (not current) process sometime.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061387032


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061374911


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)

Review Comment:
   map->vaddr is (FAR const void *), but munmap takes in (FAR void *). In this specific case we can just translate to FAR void *. Fixed this  by adding FAR, which I missed earlier



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061375058


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task
+ *   group's list
+ *
+ * Input Parameters:
+ *   vaddr   - Address within the mapped area
+ *
+ * Returned Value:
+ *   Pointer to the mapping, NULL if not found
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr);

Review Comment:
   done



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;

Review Comment:
   done cleanup in here



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061376597


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !vaddr_in_area(vaddr, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ *   Find the first mapping matching address and length
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+                                             size_t length)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && vaddr != map->vaddr && length != map->length)
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065404158


##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR char *r_end = r_start + range_length;
+
+  return (u_start >= r_start && u_start < r_end && /* start is in range */

Review Comment:
   Sure. I also took a liberty to add full stop in the end of the sentence.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065702612


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   Yes, I think it will be much better if we can:
   
   1. Share the same code base for both posix and system-v shm interface(e.g. shmget->shm_open, shmat->mmap, shmctl->ioctl, shmdt->shm_unlink).
   2. Share the same code path between posix shm and other drivers (e.g., fb and video).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065702612


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   Yes, I think it will be much better if we can:
   
   1. Share the same code base for both posix and system-v shm interface
   2. Share the same code path between posix shm and other drivers (e.g., fb and video)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063401584


##########
mm/shm/shmdt.c:
##########
@@ -113,6 +91,16 @@ int shmdt(FAR const void *shmaddr)
       goto errout_with_errno;
     }
 
+  if (!group)

Review Comment:
   the shmdt_priv is called from two places. "shmdt" is the normal detach function for user, and there the "group" always exists.
   
   shmdt_priv is also called from "munmap_shm" in shmat.c. From there the group can also be "null" in case unmap is being done at process destruction phase.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063585176


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   Initializing and destroying the map is correct I think. Only the mm_map_s structure is passed, which is the one to initialize (in task group creation) and destroyed (in task group destruction, process exit)
   
   The only question is that how you pass the info about task exit case to driver's unmap (from the mm_map_destroy). You can either have the logic in every driver, conditionally calling mm_map_remove only in normal case(not during group destruction) OR forwarding this info to mm_map_remove.
   
   If passing group for this purpose feels wrong, we can
   - pass mm_map_s instead (NULL or current one)
   - a boolean flag
   - we can conditionally call the mm_map_remove from drivers only when the context is known (not during process exit).
   
   We can even re-think the driver's munmap "group" argument. That was given only because it is a good indication to the driver that the context is not valid when the group is null.
   
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063317974


##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully

Review Comment:
   fixed



##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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.

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065281454


##########
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 char *u_start = (FAR char *)start;

Review Comment:
   cast to const char *



##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR 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;
+
+  if (!mm || !entry)
+    {
+      return OK;
+    }
+
+  int ret = nxrmutex_lock(&mm->mm_map_mutex);

Review Comment:
   move the declaration of ret to the beginning.



##########
fs/mmap/fs_rammap.c:
##########
@@ -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;

Review Comment:
   remove? let use entry->length directly like entry->offset



##########
fs/mmap/Kconfig:
##########
@@ -25,3 +25,9 @@ config FS_RAMMAP
 
 if FS_RAMMAP

Review Comment:
   remove the empty if/endif



##########
include/nuttx/sched.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 group_get_mm(group)          (group ? &group->tg_mm_map : NULL)

Review Comment:
   group_get_mm->get_group_mm



##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,40 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   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)))
+        {
+          if (entry->munmap)

Review Comment:
   let's debug assert, it's programming error not runtime error if entry->munmap is NULL



##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR 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;
+
+  if (!mm || !entry)
+    {
+      return OK;
+    }
+
+  int 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);
+      *entry = NULL;

Review Comment:
   why not change the declaration to:
   ```
   int mm_map_remove(FAR struct mm_map_s *mm,
                     FAR struct mm_map_entry_s *entry)
   ```



##########
fs/mmap/fs_rammap.h:
##########
@@ -53,29 +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/mutex.h>

Review Comment:
   remove mutex.h



##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,40 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   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)

Review Comment:
   remove if, already checked by while



##########
fs/mmap/fs_rammap.c:
##########
@@ -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(group_get_mm(group), &entry);

Review Comment:
   should we let mm_map_remove return void? it's very hard to do anything if it returns fail here.



##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR char *r_end = r_start + range_length;
+
+  return (u_start >= r_start && u_start < r_end && /* start is in range */

Review Comment:
   start/end -> Start/End



##########
mm/shm/shmat.c:
##########
@@ -32,11 +32,39 @@
 #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 Function Prototypes
+ ****************************************************************************/
+
+int shmdt_priv(FAR struct task_group_s *group, FAR const void *shmaddr,

Review Comment:
   move to mm/shm/shm.h



##########
include/nuttx/sched.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 group_get_mm(group)          (group ? &group->tg_mm_map : NULL)
+
+/* Get a pointer to current the process' memory map struct */
+
+#define get_current_mm()             (group_get_mm(nxsched_self()->group))

Review Comment:
   the change need merge to the second patch to avoid the build break.



##########
mm/shm/shmdt.c:
##########
@@ -33,32 +33,34 @@
 #include <nuttx/sched.h>
 #include <nuttx/mm/shm.h>
 #include <nuttx/pgalloc.h>
+#include <nuttx/mm/map.h>
 
 #include "shm/shm.h"
 
 #ifdef CONFIG_MM_SHM
 
 /****************************************************************************
- * Public Functions
+ * Private Functions

Review Comment:
   shmdt_priv isn't static function



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065406482


##########
mm/shm/shmat.c:
##########
@@ -32,11 +32,39 @@
 #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 Function Prototypes
+ ****************************************************************************/
+
+int shmdt_priv(FAR struct task_group_s *group, FAR const void *shmaddr,

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061376243


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   yes, fixed in mm/shm driver and in fs_munmap. Changed the mutex to rmutex, keep it locked always when managing the list. The concept is very similar to inode handling.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061378372


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   I like the enum way, do you see it unacceptable?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061470297


##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +160,38 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   nxmutex_unlock(&g_rammaps.lock);
   return ret;
 #else
+
+#ifdef CONFIG_MM_MAP

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064028467


##########
fs/mmap/fs_mmap.c:
##########
@@ -140,20 +145,6 @@ 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);

Review Comment:
   the driver who implements mmap need call mm_map_add



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061323025


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;

Review Comment:
   > the lock tries to protect the sq modifications. In a multi-threaded application separate threads can do mmap/munmap simultanously.
   > 
   
   Yes, but it's unsafe to return the entry after unlocking. The caller of mm_map_find_contains which touch the returned value will suffer the race condition.
   
   > But it is right that since mm_map_remove takes a direct reference to map, it needs to be locked also above in some cases to protect the queue.
   > 
   > I'll fix the locking
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061650947


##########
mm/Kconfig:
##########
@@ -257,4 +257,8 @@ config MM_PANIC_ON_FAILURE
 	default n
 	depends on DEBUG_MM
 
+config MM_MAP

Review Comment:
   if so, we need select this config for the driver which support mmap command. But if nobody calls mmap and munmap, the linker will remove all related code from final image. On the other hand, the driver which implement mmap function can't remove even nobody call mmap and munmap since it's very hard to let compiler/linker to remove the reference by pointer.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063394016


##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);

Review Comment:
   I find it more logical to lock mappings of a group(process), than first having to dig out the actual map from inside the group, in every place where you do that...



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063425825


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   The current code mixes all possible combination:
   
   1. Some pass task_group_s as the first argument
   2. Some directly access the current task internally
   
   It isn't good. The better method  is using only either method 1 or method 2 but not both. So, I suggest method 1 because it's more flexible. But if you prefer you can stick to the method 2.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063428271


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   Added a patch to fix this if



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1373730206

   One way to remove group argument from mm_map_remove is just to put a restriction that "driver mustn't call mm_map_remove in the munmap function if the group is unknown (NULL)". Then you would get rid of the iffy goto in mm_map_remove function as well. All entries can be deleted directly in mm_map_destroy() regardless of the current context.
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064457650


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;

Review Comment:
   done



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064460709


##########
include/nuttx/sched.h:
##########
@@ -506,6 +506,10 @@ struct task_group_s
 
   struct group_shm_s tg_shm;        /* Task shared memory logic             */
 #endif
+
+  /* Virtual memory mapping info ********************************************/
+
+  FAR struct mm_map_s tg_mm_map;    /* Task mmappings */

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064464826


##########
fs/mmap/fs_mmap.c:
##########
@@ -140,20 +145,6 @@ 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);

Review Comment:
   Normally yes. 
   
   There are a couple of drivers now which only work in FLAT mode,so they don't need to unmap, and mmap doesn't allocate anything (only return a pointer to frame buffer or such), so also no need to cleanup anything. So for those, there is currently no need to call munmap, and also no need to register the mapping.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1374467833

   @xiaoxiang781216 : Here is a commit which shows how the IF would look like if you added the mm_map_s as an argument to every function (the option 1. you mentioned avove). In my opinion it just complicates things for every driver using the interface, since they need to fetch & dig into the task_group structure, even if they don't need it for anything else.
   
   But if you think that this would look better, I am fine with it.
   
   Please let me know which way you insist this to be, I will then clean up the git history accordingly.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063505448


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   no, it is not. At the time when group is being deleted, it is not scheduled to run any more, so it is not the readytorun list.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064457337


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   removed task_group_s, only using mm_map_s * where needed



##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,155 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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:
+ *   group   - Pointer to current task_group_s. NULL in process exit case
+ *   map     - Pointer to a pointer to the mapping to be removed
+ *
+ * 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 task_group_s *group,
+                  FAR struct mm_map_entry_s **map);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065404158


##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR char *r_end = r_start + range_length;
+
+  return (u_start >= r_start && u_start < r_end && /* start is in range */

Review Comment:
   Sure. I also took the liberty to add a full stop in the end of the sentence.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065452343


##########
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 -ENOENT;
+    }
+
+  return OK;

Review Comment:
   -ENOENT



##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   why call shmdt_priv here and munmap_shm?



##########
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 -ENOENT;

Review Comment:
   OK



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065472046


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   Yes, but mm_map_remove at line 205 will trigger munmap_shm and then shmdt_priv. Line 212 call shmdt_priv again, is it double free here?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065567897


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   No, mm_map_remove doesn't trigger munmap_shm. It is vice versa, munmap_shm calls mm_map_remove.
   
   So, mm_map_remove is called from either munmap or shmdt, depending on which one is used to unmap the region.
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065790373


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   Thanks!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063493292


##########
mm/shm/shmdt.c:
##########
@@ -113,6 +91,16 @@ int shmdt(FAR const void *shmaddr)
       goto errout_with_errno;
     }
 
+  if (!group)

Review Comment:
   World is rarely perfect :)
   
   But that's why I made a private function shmdt_priv, so that you don't need to duplicate code for the two cleanup cases 1) normal munmap 2) process exit (where you must still return pages and deallocate kernel memory, but cannot touch group or MMU)
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064462671


##########
fs/mmap/fs_rammap.c:
##########
@@ -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 *map_entry,

Review Comment:
   done, it is just "entry" in all places



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065404322


##########
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 char *u_start = (FAR char *)start;

Review Comment:
   If that pleases your aesthetic eye, sure. Done.



##########
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 char *u_start = (FAR char *)start;
+  FAR char *u_end = u_start + length;
+  FAR char *r_start = (FAR char *)range_start;
+  FAR 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;
+
+  if (!mm || !entry)
+    {
+      return OK;
+    }
+
+  int ret = nxrmutex_lock(&mm->mm_map_mutex);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065405158


##########
fs/mmap/fs_rammap.c:
##########
@@ -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;

Review Comment:
   No, it is needed like this. See the loop in the end of the function.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1060621819


##########
fs/mmap/fs_munmap.c:
##########
@@ -23,9 +23,11 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/mm/map.h>
 
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/ioctl.h>

Review Comment:
   This was leftovers from rebase, will remove



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061376968


##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +160,38 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   nxmutex_unlock(&g_rammaps.lock);
   return ret;
 #else
+
+#ifdef CONFIG_MM_MAP

Review Comment:
   Didn't do this yet, I will look into this one soon



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061509569


##########
include/nuttx/mm/map.h:
##########
@@ -43,7 +49,11 @@ struct mm_map_entry_s
   off_t offset;
   int prot;
   int flags;
-  FAR void *priv;
+  union
+  {
+    FAR void *p;
+    int i;

Review Comment:
   I think it is, in general, a good idea to include some target which forces using C89 into CI.
   
   I am myself not that pedantic about that, as long as all the supported boards compile with the respective compilers, we should be good.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1371889416

   The rammaps went broken, I will need to fix it still. It was a bit too quick...


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061655622


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   If you want to do some advance IPC, it's a performance boost if we can do map from source process to the target process, but since some function require task_group_s as the first argument, it's good to keep consistence that all function accept task_group_s  as the first argument.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061194065


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)
+            {
+              /* This is a bug. A driver provides munmap, but can't munmap
+               * the region. Just delete the map entry.
+               */
+
+              kmm_free(map);
+            }
+        }
+      else
+        {
+          /* Mappping has been added, but there is no unmap. Just delete the
+           * map entry.
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = kmm_zalloc(sizeof(struct mm_map_entry_s));
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  if (!map)
+    {
+      return -ENOMEM;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  *map = *entry;
+
+  ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  nxmutex_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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task group's list
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !vaddr_in_area(vaddr, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_find
+ *
+ * Description:
+ *   Find the first mapping matching address and length
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
+                                             size_t length)
+{
+  FAR struct tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && vaddr != map->vaddr && length != map->length)
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_rm
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_rm(FAR struct task_group_s *group,
+              FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = nxmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      nxmutex_unlock(&mm->mm_map_mutex);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))

Review Comment:
   just to save memory one pointer in every map_entry. I don't think that munmap is time critical (it is never real time anyhow).
   
   Since munmap does need to always go through all the mappings it is algorithmically O(n^2) anyways, even if you used RBT here ( would become O(n * log n) ) since even in that case you'd have to start search again after every found mapping in munmap.
   
   Normally you'll anyways have just a couple of mathing mappings, so "typically" this is just linear; that is, in case of N matching entries you go through the list N+1 times. In normal case you map an area once, so with sq you got through the list twice, whereas with dq you'd go through it once. Not significant at least for me.
   
   If someone, someday, wants to do e.g. RBT for this, it would consume 3 pointers + color.... At this point I don't see that necessary and it is somewhat complicated due to 2 keys (start and length)
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1370756078

   
   > > I will present the posix SHMFS; this is an interface that I know is interesting to many. For example we have implemented an own version of PX4 uORB publish subscribe interface with this, and it is really nice, since it works inter process both in linux and nuttx (in all flat, protected and kernel). There are also other pubsub interfaces which could utilize this.
   > 
   > Nice feature. Where can I find the document or source code? is it bas on PX4 uORB or this new one: #6653
   
   It is based on PX4 uORB; the project that I am working with atm. is drone project and the uORB needs to be a drop-in replacement for PX4
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061372242


##########
fs/mmap/fs_munmap.c:
##########
@@ -23,9 +23,11 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/mm/map.h>
 
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/ioctl.h>

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062178285


##########
mm/Kconfig:
##########
@@ -257,4 +257,8 @@ config MM_PANIC_ON_FAILURE
 	default n
 	depends on DEBUG_MM
 
+config MM_MAP

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063413414


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   In fact, the group argument can be deleted also in mm_map_lock and mm_map_unlock, as also there you'll be only able to lock your own process' mappings. Certainly not any other's



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063450573


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,326 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = nxrmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * Just delete the entry
+       */
+

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065406297


##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,40 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   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)

Review Comment:
   No, I want to unlock() only if it is locked, the if guards that 



##########
fs/mmap/fs_munmap.c:
##########
@@ -158,7 +159,40 @@ static int file_munmap_(FAR void *start, size_t length, bool kernel)
   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)))
+        {
+          if (entry->munmap)

Review Comment:
   sure, done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1375383376

   
   > Yes, I think it isn't good to let's driver dig into task_group struct. Let's come back to my first suggestion but reject by you: All mm_map_s related function use tasK_group_s as the first argument.
   
   Any other part of the task_group_s doesn't belong to mm_map code, so it is really better to just pass mm_map_s where it is needed. I decoupled this from task_struct internals by adding helper macros into sched.h
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065650437


##########
mm/shm/shmdt.c:
##########
@@ -178,4 +164,55 @@ int shmdt(FAR const void *shmaddr)
   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);

Review Comment:
   I think I can do this cleanup soon, if you like



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1060742053


##########
mm/shm/shmat.c:
##########
@@ -32,11 +32,43 @@
 #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 *map,
+                      FAR void *start,
+                      size_t length)
+{
+  int ret;
+
+  if (group)
+    {
+      /* Normal "unmap", let the shmdt do the work */
+
+      ret = shmdt(start);
+    }
+  else
+    {
+      /* Address environment is being deleted, and the group is not current.
+       * Get shmid from map->priv and only free the pages, don't touch any
+       * mappings
+       */
+
+      shm_destroy(map->priv.i);

Review Comment:
   Here the whole attach counter logic was lost, need to still add that. It was not intended to destroy directly..



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063585176


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   Initializing and destroying the map is correct I think. Only the mm_map_s structure is passed, which is the one to initialize (in task group creation) and destroyed (in task group destruction, process exit)
   
   The only question is that how you pass the info about task exit case to driver's unmap (from the mm_map_destroy). You can either have the logic in every driver, conditionally calling mm_map_remove only in normal case(not during group destruction) OR forwarding this info to mm_map_remove.
   
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] hartmannathan commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
hartmannathan commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062566922


##########
fs/mmap/fs_anonmap.h:
##########
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * 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 negatet errno is returned appropriately.

Review Comment:
   ```suggestion
    *   On success returns 0. Otherwise negated errno is returned appropriately.
   ```



##########
fs/mmap/fs_rammap.c:
##########
@@ -44,12 +41,81 @@
  * 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 *map_entry,
+                        FAR void *start,
+                        size_t length)
 {
-  NXMUTEX_INITIALIZER
-};
+  FAR void *newaddr;
+  unsigned int offset;
+  bool kernel = map_entry->priv.i != 0 ? true : false;
+
+  /* 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

Review Comment:
   ```suggestion
      * There is no support for freeing a block of memory but leaving a block of
   ```



##########
fs/mmap/fs_rammap.c:
##########
@@ -44,12 +41,81 @@
  * 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 *map_entry,
+                        FAR void *start,
+                        size_t length)
 {
-  NXMUTEX_INITIALIZER
-};
+  FAR void *newaddr;
+  unsigned int offset;
+  bool kernel = map_entry->priv.i != 0 ? true : false;
+
+  /* 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 - map_entry->vaddr;
+  if (offset + length < map_entry->length)
+    {
+      ferr("ERROR: Cannot umap without unmapping to the end\n");
+      return -ENOSYS;
+    }
+
+  /* Okay.. the region is beging umapped to the end.  Make sure the length

Review Comment:
   ```suggestion
     /* Okay.. the region is being umapped to the end.  Make sure the length
   ```



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry

Review Comment:
   ```suggestion
          * Just delete the entry
   ```



##########
fs/mmap/fs_rammap.c:
##########
@@ -44,12 +41,81 @@
  * 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 *map_entry,
+                        FAR void *start,
+                        size_t length)
 {
-  NXMUTEX_INITIALIZER
-};
+  FAR void *newaddr;
+  unsigned int offset;
+  bool kernel = map_entry->priv.i != 0 ? true : false;
+
+  /* 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 - map_entry->vaddr;
+  if (offset + length < map_entry->length)
+    {
+      ferr("ERROR: Cannot umap without unmapping to the end\n");
+      return -ENOSYS;
+    }
+
+  /* Okay.. the region is beging umapped to the end.  Make sure the length

Review Comment:
   Supposed to be "umapped" or "unmapped"?



##########
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 has been copied to memory and

Review Comment:
   ```suggestion
   /* This driver manages files that have been copied to memory and
   ```



##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully

Review Comment:
   ```suggestion
    *   OK        Added successfully
   ```



##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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 a value which can be used to continue
+ *   iteration (previous or NULL)
+ *
+ * Input Parameters:
+ *   group   - Pointer to current task_group_s. NULL in process exit case
+ *   map     - Pointer to a pointer to the mapping to be removed
+ *
+ * Returned Value:
+ *   OK:       Removed succesfully

Review Comment:
   ```suggestion
    *   OK:       Removed successfully
   ```



##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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.

Review Comment:
   ```suggestion
    *   mapping when the argument "entry" is NULL.
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063408292


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   done



##########
fs/mmap/fs_anonmap.h:
##########
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * 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 negatet 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 *map, bool kernel);
+#else
+static inline int map_anonymous(FAR struct mm_map_entry_s *map, bool kernel)

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063318221


##########
include/nuttx/mm/map.h:
##########
@@ -63,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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 a value which can be used to continue
+ *   iteration (previous or NULL)
+ *
+ * Input Parameters:
+ *   group   - Pointer to current task_group_s. NULL in process exit case
+ *   map     - Pointer to a pointer to the mapping to be removed
+ *
+ * Returned Value:
+ *   OK:       Removed succesfully

Review Comment:
   fixed



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064460918


##########
include/nuttx/mm/map.h:
##########
@@ -84,34 +84,34 @@ struct mm_map_s
  * Name: mm_map_lock
  *
  * Description:
- *   Get exclusive access to task_group's mm_map
+ *   Get exclusive access current task_group's mm_map
  *
  * Input Parameters:
- *   mm - Pointer to the mm_map_s
+ *   None
  *
  * Returned Value:
  *   OK on success
  *   A negated errno value on failure
  *
  ****************************************************************************/
 
-int mm_map_lock(FAR struct task_group_s *group);
+int mm_map_lock(void);

Review Comment:
   done



##########
fs/mmap/fs_anonmap.c:
##########
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * 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 *map,
+                           FAR void *start,
+                           size_t length)
+{
+  int ret;
+
+  /* De-allocate memory.
+   * NB: This is incomplete anounymous mapping implementation
+   * see file_mmap_ below
+   */
+
+  if (start == map->vaddr && length == map->length)
+    {
+      /* map->priv marks allocation from kernel heap */
+
+      if (map->priv.i)
+        {
+          kmm_free(start);
+        }
+      else
+        {
+          kumm_free(start);
+        }
+
+      ret = mm_map_remove(group, &map);
+    }
+  else
+    {
+      ret = -EINVAL;
+      ferr("ERROR: Unknown map type\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int map_anonymous(FAR struct mm_map_entry_s *map, bool kernel)
+{
+  /* 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.
+   */
+
+  map->vaddr = kernel ? kmm_zalloc(map->length) : kumm_zalloc(map->length);
+  if (map->vaddr == NULL)
+    {
+      ferr("ERROR: kumm_alloc() failed, enable DEBUG_MM for info!\n");
+      return -ENOMEM;
+    }
+
+  map->munmap = unmap_anonymous;
+  map->priv.i = kernel;
+
+  return mm_map_add(map);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064455426


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   passing mm_map_s and mm_map_entry_s in places where needed.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1370964335

   > BTW, it's better to migrate the ram map and anon map to the new interface, which is clearer and also demo that new mmap interface is flexible enough to support the complex case.
   
   Added patches for this


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1371900569

   > 
   
   now done. Rammaps doesn't need the private mapping structure for anything, all info fits in map_entry_s. So removed that too.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1371903609

   re-based to latest master


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1062150946


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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);

Review Comment:
   If you insist that we add the group as a parameter here, I can do. It just can't be anything else than currently running one IMHO.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1369965088

   There were some issues left after re-base. I commented them, and will fix those tomorrow.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061195452


##########
include/nuttx/mm/map.h:
##########
@@ -80,4 +80,137 @@ struct mm_map_s
  * Public Function Prototypes
  ****************************************************************************/
 
-#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
+#ifdef CONFIG_MM_MAP
+
+/****************************************************************************
+ * 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 succesfully
+ *   -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_contains
+ *
+ * Description:
+ *   Find the first mapping containing an address from the task
+ *   group's list
+ *
+ * Input Parameters:
+ *   vaddr   - Address within the mapped area
+ *
+ * Returned Value:
+ *   Pointer to the mapping, NULL if not found
+ *
+ ****************************************************************************/
+
+FAR struct mm_map_entry_s *mm_map_find_contains(FAR const void *vaddr);

Review Comment:
   yes, will do



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1370572411

   > BTW, it's better to migrate the ram map and anon map to the new interface, which is clearer and also demo that new mmap interface is flexible enough to support the complex case.
   
   Agree. I can move ram mapping (MAP_PRIVATE, MAP_ANONYMOUS) to an own file at least. It should also have an own CONFIG flag (can make it default to y to keep current functionality). I find this interface quite useless as it is now, it doesn't even support mapping from page pool.
   
   rammaps deserve an own PR, but I'll  see if I can make use of the mm_map in it already as you suggested above. That sould be extended to also support MAP_SHARED. I find this interface quite useless as it is now, and this is why I don't like touching it too much in this PR.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1061647084


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * 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/config.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <nuttx/queue.h>
+#include <nuttx/sched.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/mm/map.h>
+#include <nuttx/kmalloc.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool vaddr_in_area(FAR const void *addr, FAR const void *start,
+                          size_t length)
+{
+  uintptr_t u_addr = (uintptr_t)addr;
+  uintptr_t u_start = (uintptr_t)start;
+  return (u_addr >= u_start) && (u_addr < u_start + length);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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)
+{
+  memset(mm, 0, sizeof(struct mm_map_s));
+  sq_init(&mm->mm_map_sq);
+  nxmutex_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 *map;
+
+  while ((map = (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
+       */
+
+      if (map->munmap)
+        {
+          /* Unmap the whole region */
+
+          if (map->munmap(NULL, map, (void *)map->vaddr, map->length) < 0)

Review Comment:
   should we change vaddr to FAR void *



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1373445063

   Thanks @hartmannathan for fixing the typos in the comments!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063513004


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   so, that's why I prefer the first approach, which is more consistent. There are many exceptions you can't use the current task. When to use or not use the current task, the knowledge is very easy to decide in the high layer but not in mm_map_s function.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1064023523


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;

Review Comment:
   add FAR for all pointer



##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,155 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * 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:
+ *   group   - Pointer to current task_group_s. NULL in process exit case
+ *   map     - Pointer to a pointer to the mapping to be removed
+ *
+ * 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 task_group_s *group,
+                  FAR struct mm_map_entry_s **map);

Review Comment:
   let's unify the term:
   mm_map_entry_s->entry



##########
include/nuttx/sched.h:
##########
@@ -506,6 +506,10 @@ struct task_group_s
 
   struct group_shm_s tg_shm;        /* Task shared memory logic             */
 #endif
+
+  /* Virtual memory mapping info ********************************************/
+
+  FAR struct mm_map_s tg_mm_map;    /* Task mmappings */

Review Comment:
   remove FAR and include nuttx/mm/map.h in this file, and remove the same inclusion from group_create.c and group_leave.c



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;

Review Comment:
   please consistent the parameter name:
   mm_map_entry_s map v.s. entry
   



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   > Initializing and destroying the map is correct I think. Only the mm_map_s structure is passed, which is the one to initialize (in task group creation) and destroyed (in task group destruction, process exit)
   > 
   
   Here is three choices:
   
   1. Get info from the current task
   2. Pass task_group_s as first argument
   3. Pass mm_map_s as first argument
   
   Please don't mix the usage as much as you can, any exception need have a very good reason.
   
   > The only question is that how you pass the info about task exit case to driver's unmap (from the mm_map_destroy). You can either have the logic in every driver, conditionally calling mm_map_remove only in normal case(not during group destruction) OR forwarding this info to mm_map_remove.
   > 
   > If passing group for this purpose feels wrong, we can
   > 
   > * pass mm_map_s instead (NULL or current one)
   > * a boolean flag
   > * we can conditionally call the mm_map_remove from drivers only when the context is known (not during process exit).
   > 
   > We can even re-think the driver's munmap "group" argument. That was given only because it is a good indication to the driver that the context is not valid when the group is null.
   



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)

Review Comment:
   please make your naming consistence with each other.



##########
fs/mmap/fs_rammap.c:
##########
@@ -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 *map_entry,

Review Comment:
   let's unify the term, either entry or map_entry, not both in the code base.



##########
include/nuttx/mm/map.h:
##########
@@ -84,34 +84,34 @@ struct mm_map_s
  * Name: mm_map_lock
  *
  * Description:
- *   Get exclusive access to task_group's mm_map
+ *   Get exclusive access current task_group's mm_map
  *
  * Input Parameters:
- *   mm - Pointer to the mm_map_s
+ *   None
  *
  * Returned Value:
  *   OK on success
  *   A negated errno value on failure
  *
  ****************************************************************************/
 
-int mm_map_lock(FAR struct task_group_s *group);
+int mm_map_lock(void);

Review Comment:
   please move to the second patch



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,326 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = nxrmutex_lock(&mm->mm_map_mutex);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      nxrmutex_unlock(&mm->mm_map_mutex);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * Just delete the entry
+       */
+

Review Comment:
   I don't see why you need pass map as pointer of pointer to mm_map_entry_s.



##########
fs/mmap/fs_rammap.h:
##########
@@ -53,29 +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

Review Comment:
   why not keep the file guard in the origin place?



##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   Please keep the function consistent with each other, it's strange that some function use mm_map_s *, other use task_group_s *.
   



##########
fs/mmap/fs_anonmap.c:
##########
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * 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 *map,
+                           FAR void *start,
+                           size_t length)
+{
+  int ret;
+
+  /* De-allocate memory.
+   * NB: This is incomplete anounymous mapping implementation
+   * see file_mmap_ below
+   */
+
+  if (start == map->vaddr && length == map->length)
+    {
+      /* map->priv marks allocation from kernel heap */
+
+      if (map->priv.i)
+        {
+          kmm_free(start);
+        }
+      else
+        {
+          kumm_free(start);
+        }
+
+      ret = mm_map_remove(group, &map);
+    }
+  else
+    {
+      ret = -EINVAL;
+      ferr("ERROR: Unknown map type\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int map_anonymous(FAR struct mm_map_entry_s *map, bool kernel)
+{
+  /* 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.
+   */
+
+  map->vaddr = kernel ? kmm_zalloc(map->length) : kumm_zalloc(map->length);
+  if (map->vaddr == NULL)
+    {
+      ferr("ERROR: kumm_alloc() failed, enable DEBUG_MM for info!\n");
+      return -ENOMEM;
+    }
+
+  map->munmap = unmap_anonymous;
+  map->priv.i = kernel;
+
+  return mm_map_add(map);

Review Comment:
   should we free the resource if mm_map_add fail



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063394224


##########
include/nuttx/mm/map.h:
##########
@@ -73,11 +73,156 @@ 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 to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   OK on success
+ *   A negated errno value on failure
+ *
+ ****************************************************************************/
+
+int mm_map_lock(FAR struct task_group_s *group);
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ * Input Parameters:
+ *   mm - Pointer to the mm_map_s
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group);

Review Comment:
   See above



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063504249


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(&nxsched_self()->group->tg_mm_map.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(&nxsched_self()->group->tg_mm_map.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)

Review Comment:
   Correct me if I am wrong
   
   This is called during group initialization. The task is not yet running, but current task returns g_readytorun.head ( or in SMP case the g_assignedtasks[cpu].head)
   
   The task cannot be current/running yet if the group is only being initialized... But you could pass group here if it looks better.
   
   Then you have group in two functions, which are required when the group is being created and destroyed.
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1063413414


##########
mm/map/mm_map.c:
##########
@@ -0,0 +1,325 @@
+/****************************************************************************
+ * 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>
+
+#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)
+{
+  char *u_start = (char *)start;
+  char *u_end = u_start + length;
+  char *r_start = (char *)range_start;
+  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(FAR struct task_group_s *group)
+{
+  return nxrmutex_lock(&group->tg_mm_map.mm_map_mutex);
+}
+
+/****************************************************************************
+ * Name: mm_map_unlock
+ *
+ * Description:
+ *   Relinquish exclusive access to task_group's mm_map
+ *
+ ****************************************************************************/
+
+void mm_map_unlock(FAR struct task_group_s *group)
+{
+  DEBUGVERIFY(nxrmutex_unlock(&group->tg_mm_map.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 *map;
+
+  while ((map = (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 (!map->munmap ||
+          map->munmap(NULL, map, map->vaddr, map->length) < 0)
+        {
+          /* The driver doesn't support unmap, or unmap failed. Just free
+           * the entry.
+           * A call to drivers munmap failing here would be a bug in the
+           * driver. The driver should be able to unmap at least the full
+           * area, which it has mapped
+           */
+
+          kmm_free(map);
+        }
+    }
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map;
+  int ret;
+
+  if (!entry)
+    {
+      return -EINVAL;
+    }
+
+  /* Copy the provided mapping and add to the list */
+
+  map = kmm_malloc(sizeof(struct mm_map_entry_s));
+  if (!map)
+    {
+      return -EINVAL;
+    }
+
+  *map = *entry;
+
+  ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      kmm_free(map);
+      return ret;
+    }
+
+  sq_addfirst((sq_entry_t *)map, &mm->mm_map_sq);
+
+  mm_map_unlock(group);
+
+  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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      if (entry == NULL)
+        {
+          map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+        }
+      else
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)entry));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * 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 tcb_s *tcb = nxsched_self();
+  FAR struct task_group_s *group = tcb->group;
+  FAR struct mm_map_s *mm = &group->tg_mm_map;
+  FAR struct mm_map_entry_s *map = NULL;
+
+  if (mm_map_lock(group) == OK)
+    {
+      map = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+      while (map && !in_range(vaddr, length, map->vaddr, map->length))
+        {
+          map = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)map));
+        }
+
+      mm_map_unlock(group);
+    }
+
+  return map;
+}
+
+/****************************************************************************
+ * Name: mm_map_remove
+ *
+ * Description:
+ *   Remove a mapping from the task  group's list
+ *
+ ****************************************************************************/
+
+int mm_map_remove(FAR struct task_group_s *group,
+                  FAR struct mm_map_entry_s **map)
+{
+  FAR struct mm_map_entry_s *prev;
+  FAR struct mm_map_entry_s *r = NULL;
+  FAR struct mm_map_s *mm;
+
+  if (!group)
+    {
+      /* We end up in here only through mm_map_destroy. The address
+       * environment is being destroyed and the group is not valid.
+       * just delete the entry
+       */
+
+      goto free_mem;
+    }
+
+  mm = &group->tg_mm_map;
+
+  int ret = mm_map_lock(group);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  prev = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
+
+  /* Check if the list was empty */
+
+  if (!prev)
+    {
+      mm_map_unlock(group);
+      return -ENOENT;
+    }
+
+  /* Check if removing the first item */
+
+  if (*map == prev)
+    {
+      sq_remfirst(&mm->mm_map_sq);
+      *map = NULL;
+      r = prev;
+    }
+  else
+    {
+      /* Loop through the remaining items to find the one to be removed */
+
+      while ((r = (struct mm_map_entry_s *)sq_next(((sq_entry_t *)prev))))
+        {
+          if (*map == r)
+            {
+              sq_remafter((sq_entry_t *)prev, &mm->mm_map_sq);
+              *map = prev;

Review Comment:
   In fact, the group argument can be deleted also in mm_map_lock and mm_map_unlock, as also there you'll be only able to lock your own process' mappings. Certainly not any other's
   
   And as the only exception is the process deletion, there you don't lock anyways since there is no more scheduling for the process.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1374547749

   > One way to remove group argument from mm_map_remove is just to put a restriction that "driver mustn't call mm_map_remove in the munmap function if the group is unknown (NULL)". Then you would get rid of the iffy goto in mm_map_remove function as well. All entries can be deleted directly in mm_map_destroy() regardless of the current context.
   
   My comment isn't to remove group from mm_map_remove, but make the usage consistent.
   
   > @xiaoxiang781216 : Here is a commit which shows how the IF would look like if you added the mm_map_s as an argument to every function (the option 1. you mentioned avove):
   > 
   > [tiiuae@1385bca](https://github.com/tiiuae/nuttx/commit/1385bca224ea263f4ef6c4d4b74d7933744ca4ae)
   > 
   > In my opinion it just complicates things for every driver using the interface, since they need to fetch & dig into the task_group structure, even if they don't need it for anything else.
   > 
   > But if you think that this would look better, I am fine with it.
   > 
   > Please let me know which way you insist this to be, I will then clean up the git history accordingly.
   
   Yes, I think it isn't good to let's driver dig into task_group struct. Let's come back to my first suggestion but reject by you:
   All mm_map_s related function use tasK_group_s as the first argument.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#issuecomment-1376867557

   re-based to current master


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065405960


##########
fs/mmap/fs_rammap.c:
##########
@@ -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(group_get_mm(group), &entry);

Review Comment:
   I don't care, if you insist we can do it. My thinking is that it could still fail and the user can propagate the error so that it is not lost



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] jlaitine commented on a diff in pull request #8026: Add mm map

Posted by GitBox <gi...@apache.org>.
jlaitine commented on code in PR #8026:
URL: https://github.com/apache/nuttx/pull/8026#discussion_r1065407280


##########
mm/shm/shmdt.c:
##########
@@ -33,32 +33,34 @@
 #include <nuttx/sched.h>
 #include <nuttx/mm/shm.h>
 #include <nuttx/pgalloc.h>
+#include <nuttx/mm/map.h>
 
 #include "shm/shm.h"
 
 #ifdef CONFIG_MM_SHM
 
 /****************************************************************************
- * Public Functions
+ * Private Functions

Review Comment:
   done, moved to Public. I considered it "private" because it is not supposed to be called outside this driver



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org