This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 4959e269d6 sched/sem_waitirq: Move kmm_map() call to sem_wait()
4959e269d6 is described below

commit 4959e269d69078db474b2a8a1dda64c6859cd5a1
Author: Ville Juven <ville.ju...@unikie.com>
AuthorDate: Wed Mar 12 15:05:34 2025 +0200

    sched/sem_waitirq: Move kmm_map() call to sem_wait()
    
    The kernel mapping should be performed in sem_wait (thread level) as
    virtual memory mappings cannot be added from interrupt, at least for now.
    
    The reason?
    
    kmm_map() depends on mm_map_add(), which in turn uses a mutex for mutual
    exclusion. Using mutexes from interrupt level is not permitted.
    
    Mapping tcb->waitobj into kernel virtual memory directly in sem_wait()
    makes sense, since accessing tcb->waitobj via a user virtual address can
    lead to unexpected results (the wrong mappings can be in place).
---
 sched/semaphore/sem_recover.c | 5 +++++
 sched/semaphore/sem_wait.c    | 9 +++++++++
 sched/semaphore/sem_waitirq.c | 9 ---------
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/sched/semaphore/sem_recover.c b/sched/semaphore/sem_recover.c
index ad543a2a1e..241574a2aa 100644
--- a/sched/semaphore/sem_recover.c
+++ b/sched/semaphore/sem_recover.c
@@ -31,6 +31,7 @@
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 #include <nuttx/sched.h>
+#include <nuttx/mm/kmap.h>
 
 #include "semaphore/semaphore.h"
 
@@ -100,6 +101,10 @@ void nxsem_recover(FAR struct tcb_s *tcb)
        */
 
       atomic_fetch_add(NXSEM_COUNT(sem), 1);
+
+#ifdef CONFIG_MM_KMAP
+      kmm_unmap(sem);
+#endif
     }
 
   /* Release all semphore holders for the task */
diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c
index e7ba58bf6c..5cd14b728f 100644
--- a/sched/semaphore/sem_wait.c
+++ b/sched/semaphore/sem_wait.c
@@ -33,6 +33,7 @@
 #include <nuttx/init.h>
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
+#include <nuttx/mm/kmap.h>
 
 #include "sched/sched.h"
 #include "semaphore/semaphore.h"
@@ -117,6 +118,10 @@ static int nxsem_wait_slow(FAR sem_t *sem)
 
       DEBUGASSERT(rtcb->waitobj == NULL);
 
+#ifdef CONFIG_MM_KMAP
+      sem = kmm_map_user(rtcb, sem, sizeof(*sem));
+#endif
+
       /* Save the waited on semaphore in the TCB */
 
       rtcb->waitobj = sem;
@@ -201,6 +206,10 @@ static int nxsem_wait_slow(FAR sem_t *sem)
 
       ret = rtcb->errcode != OK ? -rtcb->errcode : OK;
 
+#ifdef CONFIG_MM_KMAP
+      kmm_unmap(sem);
+#endif
+
 #ifdef CONFIG_PRIORITY_INHERITANCE
       if (prioinherit != 0)
         {
diff --git a/sched/semaphore/sem_waitirq.c b/sched/semaphore/sem_waitirq.c
index c7eae08f4a..35ab8c8ba7 100644
--- a/sched/semaphore/sem_waitirq.c
+++ b/sched/semaphore/sem_waitirq.c
@@ -32,7 +32,6 @@
 
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
-#include <nuttx/mm/kmap.h>
 
 #include "sched/sched.h"
 #include "semaphore/semaphore.h"
@@ -74,10 +73,6 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode)
   FAR struct tcb_s *rtcb = this_task();
   FAR sem_t *sem = wtcb->waitobj;
 
-#ifdef CONFIG_MM_KMAP
-  sem = kmm_map_user(wtcb, sem, sizeof(*sem));
-#endif
-
   /* It is possible that an interrupt/context switch beat us to the punch
    * and already changed the task's state.
    */
@@ -102,10 +97,6 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode)
 
   dq_rem((FAR dq_entry_t *)wtcb, SEM_WAITLIST(sem));
 
-#ifdef CONFIG_MM_KMAP
-  kmm_unmap(sem);
-#endif
-
   /* Indicate that the wait is over. */
 
   wtcb->waitobj = NULL;

Reply via email to