sched/addrenv.c: Implement re-entrancy for addrenv_select()

Store the old environment in a local context so another temporary address
environment can be selected. This can happen especially when a process
is being loaded (the new process's mappings are temporarily instantiated)
and and interrupt occurs.
This commit is contained in:
Ville Juven
2023-04-19 15:29:00 +03:00
committed by Alin Jerpelea
parent 20623d7369
commit d48114a4b7
11 changed files with 56 additions and 24 deletions
+9 -6
View File
@@ -338,7 +338,8 @@ int addrenv_leave(FAR struct tcb_s *tcb)
* running process.
*
* Input Parameters:
* addrenv - The address environment.
* addrenv - The address environment to instantiate.
* oldenv - The old active address environment is placed here.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
@@ -347,10 +348,12 @@ int addrenv_leave(FAR struct tcb_s *tcb)
*
****************************************************************************/
int addrenv_select(FAR struct addrenv_s *addrenv)
int addrenv_select(FAR struct addrenv_s *addrenv,
FAR struct addrenv_s **oldenv)
{
FAR struct tcb_s *tcb = this_task();
addrenv_take(addrenv);
*oldenv = tcb->addrenv_curr;
tcb->addrenv_curr = addrenv;
return addrenv_switch(tcb);
}
@@ -359,10 +362,10 @@ int addrenv_select(FAR struct addrenv_s *addrenv)
* Name: addrenv_restore
*
* Description:
* Switch back to the procces's own address environment.
* Switch back to the procces's previous address environment.
*
* Input Parameters:
* None
* addrenv - The address environment to restore.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
@@ -371,11 +374,11 @@ int addrenv_select(FAR struct addrenv_s *addrenv)
*
****************************************************************************/
int addrenv_restore(void)
int addrenv_restore(FAR struct addrenv_s *addrenv)
{
FAR struct tcb_s *tcb = this_task();
addrenv_give(tcb->addrenv_curr);
tcb->addrenv_curr = tcb->addrenv_own;
tcb->addrenv_curr = addrenv;
return addrenv_switch(tcb);
}
+5 -2
View File
@@ -59,6 +59,9 @@
size_t group_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size)
{
size_t n = 0;
#ifdef CONFIG_ARCH_ADDRENV
FAR struct addrenv_s *oldenv;
#endif
/* Perform sanity checks */
@@ -73,7 +76,7 @@ size_t group_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size)
#ifdef CONFIG_ARCH_ADDRENV
if (tcb->addrenv_own != NULL)
{
addrenv_select(tcb->addrenv_own);
addrenv_select(tcb->addrenv_own, &oldenv);
}
#endif
@@ -98,7 +101,7 @@ size_t group_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size)
#ifdef CONFIG_ARCH_ADDRENV
if (tcb->addrenv_own != NULL)
{
addrenv_restore();
addrenv_restore(oldenv);
}
#endif
+16
View File
@@ -83,6 +83,15 @@ void nxsched_get_stateinfo(FAR struct tcb_s *tcb, FAR char *state,
{
irqstate_t flags;
#ifdef CONFIG_ARCH_ADDRENV
FAR struct addrenv_s *oldenv;
if (tcb->addrenv_own)
{
addrenv_select(tcb->addrenv_own, &oldenv);
}
#endif
/* if the state is waiting mutex */
flags = enter_critical_section();
@@ -100,4 +109,11 @@ void nxsched_get_stateinfo(FAR struct tcb_s *tcb, FAR char *state,
leave_critical_section(flags);
strlcpy(state, g_statenames[tcb->task_state], length);
}
#ifdef CONFIG_ARCH_ADDRENV
if (tcb->addrenv_own)
{
addrenv_restore(oldenv);
}
#endif
}
+4 -2
View File
@@ -73,9 +73,11 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode)
FAR sem_t *sem = wtcb->waitobj;
#ifdef CONFIG_ARCH_ADDRENV
FAR struct addrenv_s *oldenv;
if (wtcb->addrenv_own)
{
addrenv_select(wtcb->addrenv_own);
addrenv_select(wtcb->addrenv_own, &oldenv);
}
#endif
@@ -106,7 +108,7 @@ void nxsem_wait_irq(FAR struct tcb_s *wtcb, int errcode)
#ifdef CONFIG_ARCH_ADDRENV
if (wtcb->addrenv_own)
{
addrenv_restore();
addrenv_restore(oldenv);
}
#endif