task切换-__entry_task percpu 静态变量作用
1、__entry_task为内核静态定义的percpu变量,在进程切换时,会将next进程的进程描述符保存到该变量中。
arch/arm64/kernel/process.c
497 498/* 499 * We store our current task in sp_el0, which is clobbered by userspace. Keep a 500 * shadow copy so that we can restore this upon entry from userspace. 501 * 502 * This is *only* for exception entry from EL0, and is not valid until we 503 * __switch_to() a user task. 504 */ 505DEFINE_PER_CPU(struct task_struct *, __entry_task); 506 507static void entry_task_switch(struct task_struct *next) 508{ 509 __this_cpu_write(__entry_task, next); 510} 511
调用顺序
544/* 545 * Thread switching. 546 */ 547__notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, 548 struct task_struct *next) 549{ 550 struct task_struct *last; 556 entry_task_switch(next);
2、kernel_entry 从用户态切换到内核态是,从__entry_task 获取 当前的 task 指针,放到 sp_el0 中。
175 176 .macro kernel_entry, el, regsize = 64 199 ldr_this_cpu tsk, __entry_task, x20 200 msr sp_el0, tsk
所以,内核中,sp_el0 指向 current task 。 内核中 current 宏,通过读取当前的 sp_el0 来得到 current task
v5.10/arch/arm64/include/asm/current.h
11/* 12 * We don't use read_sysreg() as we want the compiler to cache the value where 13 * possible. 14 */ 15static __always_inline struct task_struct *get_current(void) 16{ 17 unsigned long sp_el0; 18 19 asm ("mrs %0, sp_el0" : "=r" (sp_el0)); 20 21 return (struct task_struct *)sp_el0; 22} 23 24#define current get_current()