sched/group: addrenv: allocate current group for each cpu

Summary:
- In case of SMP and ADDRENV, allocate current group for each cpu
  - g_pid_current holds pid of the group and uses for addrenv switching
  - allocate g_group_current for each cpu in stead of g_pid_current
  - g_group_current is the array that pointed to the current task_group_s struct

Impact:
- ADDRENV=y and SMP=y

Testing:
- sabre-6quad:smp w/ qemu
- sabre-6quad:knsh w/ qemu
- sabre-6quad:knsh_smp w/ qemu (WIP)

Signed-off-by: Oki Minabe <minabe.oki@gmail.com>
This commit is contained in:
Oki Minabe 2022-05-06 18:58:38 +09:00 committed by Petro Karashchenko
parent d9a519444c
commit 22787ee109
3 changed files with 28 additions and 31 deletions

View File

@ -52,14 +52,14 @@ extern FAR struct task_group_s *g_grouphead;
#endif
#ifdef CONFIG_ARCH_ADDRENV
/* This variable holds the PID of the current task group. This ID is
* zero if the current task is a kernel thread that has no address
* environment (other than the kernel context).
/* This variable holds the current task group. This pointer is NULL
* if the current task is a kernel thread that has no address environment
* (other than the kernel context).
*
* This must only be accessed with interrupts disabled.
*/
extern pid_t g_pid_current;
extern FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
#endif
/****************************************************************************

View File

@ -39,14 +39,14 @@
* Public Data
****************************************************************************/
/* This variable holds the PID of the current task group. This ID is
* zero if the current task is a kernel thread that has no address
* environment (other than the kernel context).
/* This variable holds the current task group. This pointer is NULL
* if the current task is a kernel thread that has no address environment
* (other than the kernel context).
*
* This must only be accessed with interrupts disabled.
*/
pid_t g_pid_current = INVALID_PROCESS_ID;
FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
/****************************************************************************
* Public Functions
@ -85,7 +85,7 @@ int group_addrenv(FAR struct tcb_s *tcb)
FAR struct task_group_s *group;
FAR struct task_group_s *oldgroup;
irqstate_t flags;
pid_t pid;
int cpu;
int ret;
/* NULL for the tcb means to use the TCB of the task at the head of the
@ -111,34 +111,24 @@ int group_addrenv(FAR struct tcb_s *tcb)
return OK;
}
/* Get the PID of the group that needs the address environment */
pid = group->tg_pid;
DEBUGASSERT(pid != INVALID_PROCESS_ID);
/* Are we going to change address environments? */
flags = enter_critical_section();
if (pid != g_pid_current)
cpu = this_cpu();
oldgroup = g_group_current[cpu];
if (group != oldgroup)
{
/* Yes.. Is there a current address environment in place? */
if (g_pid_current != INVALID_PROCESS_ID)
if (oldgroup)
{
/* Find the old group with this ID. */
/* We need to flush the D-Cache and Invalidate the I-Cache for
* the group whose environment is disappearing.
*/
oldgroup = group_findbypid(g_pid_current);
DEBUGASSERT(oldgroup &&
(oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);
if (oldgroup)
{
/* We need to flush the D-Cache and Invalidate the I-Cache for
* the group whose environment is disappearing.
*/
up_addrenv_coherent(&oldgroup->tg_addrenv);
}
DEBUGASSERT((oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);
up_addrenv_coherent(&oldgroup->tg_addrenv);
}
/* Instantiate the new address environment (removing the old
@ -155,7 +145,7 @@ int group_addrenv(FAR struct tcb_s *tcb)
/* Save the new, current group */
g_pid_current = pid;
g_group_current[cpu] = group;
}
leave_critical_section(flags);

View File

@ -130,6 +130,7 @@ static inline void group_release(FAR struct task_group_s *group)
{
#ifdef CONFIG_ARCH_ADDRENV
save_addrenv_t oldenv;
int i;
#endif
#if CONFIG_TLS_TASK_NELEM > 0
@ -248,7 +249,13 @@ static inline void group_release(FAR struct task_group_s *group)
/* Mark no address environment */
g_pid_current = INVALID_PROCESS_ID;
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
{
if (group == g_group_current[i])
{
g_group_current[i] = NULL;
}
}
/* Restore the previous addrenv */