From 1aab457b4c2f292ba067e84f16c076bfcedb1b49 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Wed, 27 Dec 2023 19:10:05 +0800 Subject: [PATCH] sched:add parameters to restore_critical_section 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 --- arch/arm/src/arm/arm_syscall.c | 10 ++++++++-- arch/arm/src/armv6-m/arm_svcall.c | 2 +- arch/arm/src/armv7-a/arm_syscall.c | 10 ++++++++-- arch/arm/src/armv7-m/arm_svcall.c | 2 +- arch/arm/src/armv7-r/arm_syscall.c | 10 ++++++++-- arch/arm/src/armv8-m/arm_svcall.c | 2 +- arch/arm/src/armv8-r/arm_syscall.c | 10 ++++++++-- arch/arm64/src/common/arm64_syscall.c | 8 ++++++-- arch/risc-v/src/common/riscv_swint.c | 2 +- .../src/common/supervisor/riscv_perform_syscall.c | 9 +++++++-- arch/sim/src/sim/sim_exit.c | 2 +- arch/sim/src/sim/sim_smpsignal.c | 2 +- arch/sim/src/sim/sim_switchcontext.c | 5 +++-- arch/x86_64/src/common/x86_64_exit.c | 2 +- arch/x86_64/src/common/x86_64_switchcontext.c | 2 +- arch/x86_64/src/intel64/intel64_handlers.c | 9 +++++++-- arch/xtensa/src/common/xtensa_swint.c | 2 +- include/nuttx/irq.h | 9 +++------ 18 files changed, 67 insertions(+), 31 deletions(-) diff --git a/arch/arm/src/arm/arm_syscall.c b/arch/arm/src/arm/arm_syscall.c index f3f36de67a..090fc788fd 100644 --- a/arch/arm/src/arm/arm_syscall.c +++ b/arch/arm/src/arm/arm_syscall.c @@ -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 */ @@ -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; } diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c index d4d87d9c19..9429dffc01 100644 --- a/arch/arm/src/armv6-m/arm_svcall.c +++ b/arch/arm/src/armv6-m/arm_svcall.c @@ -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; diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index b8e6e6e6c4..43767947a0 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -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 @@ -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; } diff --git a/arch/arm/src/armv7-m/arm_svcall.c b/arch/arm/src/armv7-m/arm_svcall.c index 037561e03b..eeb171303c 100644 --- a/arch/arm/src/armv7-m/arm_svcall.c +++ b/arch/arm/src/armv7-m/arm_svcall.c @@ -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; diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index a7a4244c19..c04589f635 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -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 @@ -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; } diff --git a/arch/arm/src/armv8-m/arm_svcall.c b/arch/arm/src/armv8-m/arm_svcall.c index 1c3af03f7a..db6523ae65 100644 --- a/arch/arm/src/armv8-m/arm_svcall.c +++ b/arch/arm/src/armv8-m/arm_svcall.c @@ -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; diff --git a/arch/arm/src/armv8-r/arm_syscall.c b/arch/arm/src/armv8-r/arm_syscall.c index 2526e51671..d56009b463 100644 --- a/arch/arm/src/armv8-r/arm_syscall.c +++ b/arch/arm/src/armv8-r/arm_syscall.c @@ -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 @@ -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; } diff --git a/arch/arm64/src/common/arm64_syscall.c b/arch/arm64/src/common/arm64_syscall.c index 04dd20f197..4fd20e3920 100644 --- a/arch/arm64/src/common/arm64_syscall.c +++ b/arch/arm64/src/common/arm64_syscall.c @@ -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 */ @@ -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; diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c index 95edae139e..33c60bbf0f 100644 --- a/arch/risc-v/src/common/riscv_swint.c +++ b/arch/risc-v/src/common/riscv_swint.c @@ -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; diff --git a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c index cd134fb4e1..06250caee4 100644 --- a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c +++ b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c @@ -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; @@ -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 diff --git a/arch/sim/src/sim/sim_exit.c b/arch/sim/src/sim/sim_exit.c index 53a2221d51..eb000b06fa 100644 --- a/arch/sim/src/sim/sim_exit.c +++ b/arch/sim/src/sim/sim_exit.c @@ -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 */ diff --git a/arch/sim/src/sim/sim_smpsignal.c b/arch/sim/src/sim/sim_smpsignal.c index 97f2e8ff42..4ecba8bc7a 100644 --- a/arch/sim/src/sim/sim_smpsignal.c +++ b/arch/sim/src/sim/sim_smpsignal.c @@ -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. diff --git a/arch/sim/src/sim/sim_switchcontext.c b/arch/sim/src/sim/sim_switchcontext.c index 182d1a375b..6d4d3603a7 100644 --- a/arch/sim/src/sim/sim_switchcontext.c +++ b/arch/sim/src/sim/sim_switchcontext.c @@ -32,6 +32,7 @@ #include "clock/clock.h" #include "sim_internal.h" +#include "sched/sched.h" /**************************************************************************** * Public Functions @@ -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 */ @@ -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 */ diff --git a/arch/x86_64/src/common/x86_64_exit.c b/arch/x86_64/src/common/x86_64_exit.c index 9c2c86d37f..d264a06408 100644 --- a/arch/x86_64/src/common/x86_64_exit.c +++ b/arch/x86_64/src/common/x86_64_exit.c @@ -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 */ diff --git a/arch/x86_64/src/common/x86_64_switchcontext.c b/arch/x86_64/src/common/x86_64_switchcontext.c index c87a71339c..16f1417140 100644 --- a/arch/x86_64/src/common/x86_64_switchcontext.c +++ b/arch/x86_64/src/common/x86_64_switchcontext.c @@ -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. diff --git a/arch/x86_64/src/intel64/intel64_handlers.c b/arch/x86_64/src/intel64/intel64_handlers.c index 8fbcc21485..a4ad29c015 100644 --- a/arch/x86_64/src/intel64/intel64_handlers.c +++ b/arch/x86_64/src/intel64/intel64_handlers.c @@ -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. * @@ -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 diff --git a/arch/xtensa/src/common/xtensa_swint.c b/arch/xtensa/src/common/xtensa_swint.c index e8d482c1c8..ce5c321e08 100644 --- a/arch/xtensa/src/common/xtensa_swint.c +++ b/arch/xtensa/src/common/xtensa_swint.c @@ -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; diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h index ed89b46c95..dd1e1a6288 100644 --- a/include/nuttx/irq.h +++ b/include/nuttx/irq.h @@ -312,21 +312,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