操作系统(七)深入理解Linux内核进程上下文切换
来源:华佗健康网
1.进程上下文的概念
2.上下文切换详细过程
__schedule // kernel/sched/core.c
->context_switch
->switch_mm_irqs_off //进程地址空间切换
->switch_to //处理器状态切换
2.1 进程地址空间切换
context_switch // kernel/sched/core.c
->switch_mm_irqs_off
->switch_mm
->__switch_mm
->check_and_switch_context
->cpu_switch_mm
->cpu_do_switch_mm(virt_to_phys(pgd),mm) //arch/arm64/include/asm/mmu_context.h
arch/arm64/mm/proc.S
158 /*
159 * cpu_do_switch_mm(pgd_phys, tsk)
160 *
161 * Set the translation table base pointer to be pgd_phys.
162 *
163 * - pgd_phys - physical address of new TTB
164 */
165 ENTRY(cpu_do_switch_mm)
166 mrs x2, ttbr1_el1
167 mmid x1, x1 // get mm->context.id
168 phys_to_ttbr x3, x0
169
170 alternative_if ARM64_HAS_CNP
171 cbz x1, 1f // skip CNP for reserved ASID
172 orr x3, x3, #TTBR_CNP_BIT
173 1:
174 alternative_else_nop_endif
175 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
176 bfi x3, x1, #48, #16 // set the ASID field in TTBR0
177 #endif
178 bfi x2, x1, #48, #16 // set the ASID
179 msr ttbr1_el1, x2 // in TTBR1 (since TCR.A1 is set)
180 isb
181 msr ttbr0_el1, x3 // now update TTBR0
182 isb
183 b post_ttbr_update_workaround // Back to C code...
184 ENDPROC(cpu_do_switch_mm)
2.2 处理器状态(硬件上下文)切换
switch_to
->__switch_to
... //浮点寄存器等的切换
->cpu_switch_to(prev, next)
arch/arm64/kernel/entry.S:
1032 /*
1033 * Register switch for AArch64. The callee-saved registers need to be saved
1034 * and restored. On entry:
1035 * x0 = previous task_struct (must be preserved across the switch)
1036 * x1 = next task_struct
1037 * Previous and next are guaranteed not to be the same.
1038 *
1039 */
1040 ENTRY(cpu_switch_to)
1041 mov x10, #THREAD_CPU_CONTEXT
1042 add x8, x0, x10
1043 mov x9, sp
1044 stp x19, x20, [x8], #16 // store callee-saved registers
1045 stp x21, x22, [x8], #16
1046 stp x23, x24, [x8], #16
1047 stp x25, x26, [x8], #16
1048 stp x27, x28, [x8], #16
1049 stp x29, x9, [x8], #16
1050 str lr, [x8]
1051 add x8, x1, x10
1052 ldp x19, x20, [x8], #16 // restore callee-saved registers
1053 ldp x21, x22, [x8], #16
1054 ldp x23, x24, [x8], #16
1055 ldp x25, x26, [x8], #16
1056 ldp x27, x28, [x8], #16
1057 ldp x29, x9, [x8], #16
1058 ldr lr, [x8]
1059 mov sp, x9
1060 msr sp_el0, x1
1061 ret
1062 ENDPROC(cpu_switch_to)
3.ASID机制
4. 普通用户进程、普通用户线程、内核线程切换的差别
5. 进程切换全景视图
我们以下场景为例: A,B两个进程都是普通的用户进程,从进程A切换到进程B,简单起见我们在这里不考虑其他的抢占时机,我们假设A,B进程只是循环进行一些基本的运算操作,从来不调用任何系统调用,只考虑被时钟中断,返回用户空间之前被抢占的情况。
下面给出进程切换的全景视图:
6. 总结
因篇幅问题不能全部显示,请点此查看更多更全内容