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;