Skip to content

Commit

Permalink
sched:add parameters to restore_critical_section
Browse files Browse the repository at this point in the history
reason:
In SMP, when a context switch occurs, restore_critical_section is executed.
To reduce the time taken for context switching, we directly pass the required
parameters to restore_critical_section instead of acquiring them repeatedly.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
  • Loading branch information
hujun260 committed Sep 1, 2024
1 parent 89589a5 commit 8a33529
Show file tree
Hide file tree
Showing 18 changed files with 67 additions and 31 deletions.
10 changes: 8 additions & 2 deletions arch/arm/src/arm/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@

uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
uint32_t cmd;
int cpu;

/* Nested interrupts are not supported */

Expand Down Expand Up @@ -158,9 +160,13 @@ uint32_t *arm_syscall(uint32_t *regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

restore_critical_section();
/* Restore the cpu lock */

restore_critical_section(tcb, cpu);
regs = (uint32_t *)CURRENT_REGS;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/armv6-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ int arm_svcall(int irq, void *context, void *arg)

if (regs != CURRENT_REGS)
{
restore_critical_section();
restore_critical_section(this_task(), this_cpu());
}

return OK;
Expand Down
10 changes: 8 additions & 2 deletions arch/arm/src/armv7-a/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ static void dispatch_syscall(void)

uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_KERNEL
uint32_t cpsr;
#endif
Expand Down Expand Up @@ -590,9 +592,13 @@ uint32_t *arm_syscall(uint32_t *regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

restore_critical_section();
/* Restore the cpu lock */

restore_critical_section(tcb, cpu);
regs = (uint32_t *)CURRENT_REGS;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/armv7-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ int arm_svcall(int irq, void *context, void *arg)

if (regs != CURRENT_REGS)
{
restore_critical_section();
restore_critical_section(this_task(), this_cpu());
}

return OK;
Expand Down
10 changes: 8 additions & 2 deletions arch/arm/src/armv7-r/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ static void dispatch_syscall(void)

uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
uint32_t cpsr;
#endif
Expand Down Expand Up @@ -567,9 +569,13 @@ uint32_t *arm_syscall(uint32_t *regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

restore_critical_section();
/* Restore the cpu lock */

restore_critical_section(tcb, cpu);
regs = (uint32_t *)CURRENT_REGS;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/armv8-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ int arm_svcall(int irq, void *context, void *arg)

if (regs != CURRENT_REGS)
{
restore_critical_section();
restore_critical_section(this_task(), this_cpu());
}

return OK;
Expand Down
10 changes: 8 additions & 2 deletions arch/arm/src/armv8-r/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ static void dispatch_syscall(void)

uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb;
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
uint32_t cpsr;
#endif
Expand Down Expand Up @@ -567,9 +569,13 @@ uint32_t *arm_syscall(uint32_t *regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

restore_critical_section();
/* Restore the cpu lock */

restore_critical_section(tcb, cpu);
regs = (uint32_t *)CURRENT_REGS;
}

Expand Down
8 changes: 6 additions & 2 deletions arch/arm64/src/common/arm64_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
uint64_t cmd;
struct regs_context *f_regs;
uint64_t *ret_regs;
struct tcb_s *tcb;
int cpu;

/* Nested interrupts are not supported */

Expand Down Expand Up @@ -252,11 +254,13 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, cpu);
}

return ret_regs;
Expand Down
9 changes: 7 additions & 2 deletions arch/risc-v/src/common/riscv_perform_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@

void *riscv_perform_syscall(uintreg_t *regs)
{
struct tcb_s *tcb;
int cpu;

/* Set up the interrupt register set needed by swint() */

CURRENT_REGS = regs;
Expand Down Expand Up @@ -64,11 +67,13 @@ void *riscv_perform_syscall(uintreg_t *regs)
* assertion logic for reporting crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, cpu);

/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value
Expand Down
2 changes: 1 addition & 1 deletion arch/risc-v/src/common/riscv_swint.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ int riscv_swint(int irq, void *context, void *arg)

if (regs != CURRENT_REGS)
{
restore_critical_section();
restore_critical_section(this_task(), this_cpu());
}

return OK;
Expand Down
2 changes: 1 addition & 1 deletion arch/sim/src/sim/sim_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void up_exit(int status)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Then switch contexts */

Expand Down
2 changes: 1 addition & 1 deletion arch/sim/src/sim/sim_smpsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ int up_cpu_paused_restore(void)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Then switch contexts. Any necessary address environment changes
* will be made when the interrupt returns.
Expand Down
5 changes: 3 additions & 2 deletions arch/sim/src/sim/sim_switchcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "clock/clock.h"
#include "sim_internal.h"
#include "sched/sched.h"

/****************************************************************************
* Public Functions
Expand Down Expand Up @@ -77,7 +78,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Then switch contexts */

Expand All @@ -102,7 +103,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Then switch contexts */

Expand Down
2 changes: 1 addition & 1 deletion arch/x86_64/src/common/x86_64_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void up_exit(int status)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Then switch contexts */

Expand Down
2 changes: 1 addition & 1 deletion arch/x86_64/src/common/x86_64_switchcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, this_cpu());

/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
Expand Down
9 changes: 7 additions & 2 deletions arch/x86_64/src/intel64/intel64_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
#ifndef CONFIG_SUPPRESS_INTERRUPTS
static uint64_t *common_handler(int irq, uint64_t *regs)
{
struct tcb_s *tcb;
int cpu;

/* Current regs non-zero indicates that we are processing an interrupt;
* g_current_regs is also used to manage interrupt level context switches.
*
Expand Down Expand Up @@ -99,11 +102,13 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
* crashes.
*/

g_running_tasks[this_cpu()] = this_task();
cpu = this_cpu();
tcb = current_task(cpu);
g_running_tasks[cpu] = tcb;

/* Restore the cpu lock */

restore_critical_section();
restore_critical_section(tcb, cpu);
}

/* If a context switch occurred while processing the interrupt then
Expand Down
2 changes: 1 addition & 1 deletion arch/xtensa/src/common/xtensa_swint.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ int xtensa_swint(int irq, void *context, void *arg)

if (regs != CURRENT_REGS)
{
restore_critical_section();
restore_critical_section(this_task(), this_cpu());
}

return OK;
Expand Down
9 changes: 3 additions & 6 deletions include/nuttx/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,21 +280,18 @@ void leave_critical_section(irqstate_t flags) noinstrument_function;
****************************************************************************/

#ifdef CONFIG_SMP
# define restore_critical_section() \
# define restore_critical_section(tcb, cpu) \
do { \
FAR struct tcb_s *tcb; \
int me = this_cpu(); \
tcb = current_task(me); \
if (tcb->irqcount <= 0) \
{\
if ((g_cpu_irqset & (1 << me)) != 0) \
if ((g_cpu_irqset & (1 << cpu)) != 0) \
{ \
cpu_irqlock_clear(); \
} \
} \
} while (0)
#else
# define restore_critical_section()
# define restore_critical_section(tcb, cpu)
#endif

#undef EXTERN
Expand Down

0 comments on commit 8a33529

Please sign in to comment.