From 1fad0f16541d1c9726cf9fc532078c31c384595b Mon Sep 17 00:00:00 2001 From: liwenxiang1 Date: Mon, 9 Dec 2024 14:09:45 +0800 Subject: [PATCH] arch/x86_64: this_task is stored in the CPU private data By default in SMP, obtaining this_task requires disabling interrupts, obtaining the current CPU index, accessing a global variable, and re-enabling interrupts. Storing this_task in percpu makes retrieval faster. Signed-off-by: liwenxiang1 --- arch/x86_64/include/irq.h | 44 +++++++++---------- .../x86_64/src/intel64/intel64_backtrace_fp.c | 4 +- arch/x86_64/src/intel64/intel64_cpustart.c | 4 +- arch/x86_64/src/intel64/intel64_regdump.c | 3 +- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/arch/x86_64/include/irq.h b/arch/x86_64/include/irq.h index 42790785bb528..0d82aafbd9339 100644 --- a/arch/x86_64/include/irq.h +++ b/arch/x86_64/include/irq.h @@ -72,13 +72,9 @@ struct intel64_cpu_s bool interrupt_context; -/* current_regs holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to current_regs must be through - * up_current_regs() and up_set_current_regs() functions - */ + /* Current task */ - uint64_t *current_regs; + struct tcb_s *this_task; #ifdef CONFIG_LIB_SYSCALL /* Current user RSP for syscall */ @@ -143,22 +139,6 @@ static inline_function int up_cpu_index(void) * Inline functions ****************************************************************************/ -static inline_function uint64_t *up_current_regs(void) -{ - uint64_t *regs; - __asm__ volatile("movq %%gs:(%c1), %0" - : "=r" (regs) - : "i" (offsetof(struct intel64_cpu_s, current_regs))); - return regs; -} - -static inline_function void up_set_current_regs(uint64_t *regs) -{ - __asm__ volatile("movq %0, %%gs:(%c1)" - :: "r" (regs), "i" (offsetof(struct intel64_cpu_s, - current_regs))); -} - static inline_function bool up_interrupt_context(void) { bool flag; @@ -177,12 +157,30 @@ static inline_function void up_set_interrupt_context(bool flag) interrupt_context))); } +/**************************************************************************** + * Schedule acceleration macros + ****************************************************************************/ + +#define up_this_task() \ + ({ \ + struct tcb_s *this_task; \ + __asm__ volatile("movq %%gs:(%c1), %0" \ + : "=r" (this_task) \ + : "i" (offsetof(struct intel64_cpu_s, this_task))); \ + this_task; \ + }) + +#define up_update_task(t) \ + __asm__ volatile("movq %0, %%gs:(%c1)" \ + :: "r" ((struct tcb_s *)t), \ + "i" (offsetof(struct intel64_cpu_s, this_task))) + /**************************************************************************** * Name: up_getusrpc ****************************************************************************/ #define up_getusrpc(regs) \ - (((uint64_t *)((regs) ? (regs) : up_current_regs()))[REG_RIP]) + (((uint64_t *)((regs) ? (regs) : running_regs()))[REG_RIP]) #undef EXTERN #ifdef __cplusplus diff --git a/arch/x86_64/src/intel64/intel64_backtrace_fp.c b/arch/x86_64/src/intel64/intel64_backtrace_fp.c index 517a7b587e408..03dd357ffa1c4 100644 --- a/arch/x86_64/src/intel64/intel64_backtrace_fp.c +++ b/arch/x86_64/src/intel64/intel64_backtrace_fp.c @@ -145,8 +145,8 @@ int up_backtrace(struct tcb_s *tcb, { ret += backtrace(rtcb->stack_base_ptr, rtcb->stack_base_ptr + rtcb->adj_stack_size, - (void *)up_current_regs()[REG_RBP], - (void *)up_current_regs()[REG_RIP], + (void *)running_regs()[REG_RBP], + (void *)running_regs()[REG_RIP], &buffer[ret], size - ret, &skip); } } diff --git a/arch/x86_64/src/intel64/intel64_cpustart.c b/arch/x86_64/src/intel64/intel64_cpustart.c index 9671825d821fe..e2b46d4637557 100644 --- a/arch/x86_64/src/intel64/intel64_cpustart.c +++ b/arch/x86_64/src/intel64/intel64_cpustart.c @@ -148,7 +148,7 @@ void x86_64_ap_boot(void) x86_64_cpu_priv_set(cpu); - tcb = this_task(); + tcb = current_task(cpu); UNUSED(tcb); /* Configure interrupts */ @@ -192,6 +192,8 @@ void x86_64_ap_boot(void) __revoke_low_memory(); } + up_update_task(tcb); + /* Then transfer control to the IDLE task */ nx_idle_trampoline(); diff --git a/arch/x86_64/src/intel64/intel64_regdump.c b/arch/x86_64/src/intel64/intel64_regdump.c index 9c13d57392b6a..646e1b32f86bc 100644 --- a/arch/x86_64/src/intel64/intel64_regdump.c +++ b/arch/x86_64/src/intel64/intel64_regdump.c @@ -30,6 +30,7 @@ #include #include +#include "sched/sched.h" #include "x86_64_internal.h" /**************************************************************************** @@ -113,7 +114,7 @@ void backtrace(uint64_t rbp) void up_dump_register(void *dumpregs) { - volatile uint64_t *regs = dumpregs ? dumpregs : up_current_regs(); + volatile uint64_t *regs = dumpregs ? dumpregs : running_regs(); uint64_t mxcsr; uint64_t cr2;