sem_waitirq: Use kmap interface to access the semaphore

The temporary mappings via addrenv_select() and addrenv_restore() simply
do not work from interrupt, so remove its usage and replace with kmap
which is safe.
This commit is contained in:
Ville Juven 2024-12-17 11:59:42 +02:00 committed by Xiang Xiao
parent 95d1e52535
commit 510d9659b4
3 changed files with 14 additions and 16 deletions

View file

@ -416,6 +416,9 @@ int addrenv_leave(FAR struct tcb_s *tcb);
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
* Note:
* This API is not safe to use from interrupt.
*
****************************************************************************/
int addrenv_select(FAR struct addrenv_s *addrenv,

View file

@ -339,6 +339,9 @@ int addrenv_leave(FAR struct tcb_s *tcb)
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
* Note:
* This API is not safe to use from interrupt.
*
****************************************************************************/
int addrenv_select(FAR struct addrenv_s *addrenv,

View file

@ -30,9 +30,9 @@
#include <assert.h>
#include <errno.h>
#include <nuttx/addrenv.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/mm/kmap.h>
#include "sched/sched.h"
#include "semaphore/semaphore.h"
@ -54,16 +54,16 @@
* 2. From logic associated with sem_timedwait(). This function is called
* when the timeout elapses without receiving the semaphore.
*
* Note: this function should used within critical_section
* Note: this function should be used within critical_section.
*
* Input Parameters:
* wtcb - A pointer to the TCB of the task that is waiting on a
* semphaphore, but has received a signal or timeout instead.
* errcode - EINTR if the semaphore wait was awakened by a signal;
* ETIMEDOUT if awakened by a timeout
* ETIMEDOUT if awakened by a timeout.
*
* Returned Value:
* None
* None.
*
* Assumptions:
*
@ -74,13 +74,8 @@ 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_ARCH_ADDRENV
FAR struct addrenv_s *oldenv;
if (wtcb->addrenv_own)
{
addrenv_select(wtcb->addrenv_own, &oldenv);
}
#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
@ -107,11 +102,8 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode)
dq_rem((FAR dq_entry_t *)wtcb, SEM_WAITLIST(sem));
#ifdef CONFIG_ARCH_ADDRENV
if (wtcb->addrenv_own)
{
addrenv_restore(oldenv);
}
#ifdef CONFIG_MM_KMAP
kmm_unmap(sem);
#endif
/* Indicate that the wait is over. */