-----------------------------------------------------------------------------------
The process of understanding process scheduling and process switching during the time-tracking analysis process
-----------------------------------------------------------------------------------
This experiment is to understand the process of process scheduling and process switching during the time tracking analysis process. This is the last experiment, we have to complete this experiment, or to have a certain understanding of task switching.
The Linux task switch is implemented through switch_to . switch_to itself is a macro , by using the long jump instruction, when the operation of the long jump instruction is the TSS descriptor , it will cause the CPU task switching, at this time, The CPU saves the state of all registers to the TSS segment (the task status segment of the current task) pointed to by the current task register TR , and then finds the TSS segment of the new task with the operand of the long hop instruction (TSS descriptor), The contents are then filled into registers, and finally, the TSS selector for the new task is updated into the TR . This allows the system to formally start running the newly switched tasks.
With this added, let's review what we've learned before.
In a Linux system, a process's general execution process:
This is the process of switching from running user-state process x to running user-state process y .
1) running user-state process x
2) An interrupt occurred int 0x80
3)Save_all //Save site
4) Schedule ()is invoked during interrupt processing or before an interrupt is returned, where SWITCH_TO does a critical process context switch
5) After the label 1 starts to run the user-state process y(where Y has been switched out through the above steps so you can continue from the label 1)
6)Restore_all //recovery site
7)Iret
8) Continue to run user-state process y
But as we all know, here are a few special cases:
By interrupting the timing of the processing process, the user-state process and kernel threads switch between each other and the kernel threads switch to each other, very similar to the most common situation, but the kernel thread is running in the process of interruption without process user state and kernel state conversion;
1) kernel thread actively calls schedule (), only the process context switch, there is no interrupt context switch, and the most general situation is slightly abbreviated;
2) Create a child process of the system call in the child process execution starting point and return user state, such as fork;
3) After loading a new executable program, return to the condition of the user state, such as Execve.
Start the experiment.
Based on previous knowledge, this time we trace the schedule function to carefully analyze the process of the system for process scheduling and process switching.
Run Menuos, set 3 breakpoints:schedule,context_switch,switch_to.
Run to stop at the first breakpoint, that is, stop at the schedule function, use the List command to view its code, the S command analysis by article. In this process, we have to pay attention to the implementation of the trajectory, a moment to analyze.
continues to run, stopping at the second breakpoint, i.e. Context_switch stop at the place. Same as on, continue stepping. In this process, pay attention to the switch_to.
Context_switch called the switch_to function, this switch_to macro definition, we can take advantage of stepping into its internal observation.
Summarize
Switch_to the steps to switch from the a process to the B process are as follows:
Step1: copy two variables to register:
[prev] "a" (prev)
[Next] "D" (next)
This is also eax <== prev_a or eax<==%p (%ebp_a)
edx <== next_a or edx<==%n (%ebp_a)
Step2: Save the ebp and eflags of process a
PUSHFL / * Press the status register EFlags * /
PUSHL%EBP
Note that because ESP is now in the stack of a, they are saved to the kernel stack of the a process .
Step3: saves the current ESP to the a process kernel descriptor:
Movl%%esp,%[prev_sp]\n\t /*save ESP * /
This is also prev_a->thread.sp<== esp_a
When Switch_to is called, Prev is the process descriptor that points to the a process itself.
step4: the esp_bthat was saved from the descriptor of next (process B) before it was switched out from B.
MOVL%[next_sp],%%esp\n\t / * Restore ESP * /
This is also esp_b <==next_a->thread.sp
Note that next in the a process is the process descriptor that points to B. From this point on, the current process of CPU execution is already a B process , because ESP already points to B's kernel stack. However, the current EBP still points to the kernel stack of the a process , so all local variables are still local variables in a , such as Next is essentially%n (%ebp_a), or next_a, which points to The process descriptor for B .
step5: Save the instruction address labeled 1 to the IP domain of the a process descriptor:
movl $1f,%[prev_ip]\n\t / * Save EIP * /
This is also prev_a->thread.ip<==%1f
The next time a process returns from Switch_to, it will be executed from this command. The exact method depends on the next instruction of B that is switched back.
STEP6: Save the return address to the stack, then call the switch_to () function, and theswitch_to () function completes the hardware context switch.
PUSHL%[next_ip]\n\t / * RESTOREEIP * /
jmp switch_to\n / * Regparmcall * /
Note that if B has been switch_to out before , then [NEXT_IP] is the following 1f label , but if process B has just been created and has not been switch_to before, then [ NEXT_IP] will be ret_ftom_fork(see Copy_thread () function).
When switch_to () returns here, the return value Prev_a is written to %eax, which makes the EAX register in the SWITCH_TO macro always save the contents of prev_a, or, more precisely, is a pointer to the a process descriptor.
STEP7: after returning from Switch_to (), proceed from the 1: label, modify the kernel stack of ebp to B, and restore the eflags of B:
popl%%ebp\n\t / * Restore EBP * /
popfl\n /*restore Flags * *
If you return from switch_to () and continue running from here, then B must have been switch_to recalled before, so it was definitely backed up by Ebp_b and Flags_b, where the recovery operation was performed.
At this point, EBP has pointed to the kernel stack of B, so local variables such as the above Prev,next are not already in the a process stack, but in the B process stack (b the last time it was switched out before the two variables, so represents the B stack prev, next value), because prev==%p (%ebp_b), and before B was last switched out, the location holds the descriptor address of the B process. If this is the end of the switch_to, the prev variable in the later code (i.e. the code after switch_to in the Context_switch () function) points to the B process, so that process B does not know which process to switch back from. In the code after switch_to from Context_switch (), we see that Finish_task_switch (This_rq (), prev) needs to know which process was switched from before, so We have to find a way to save the descriptor of a process to the stack of B, which is the last function.
STEP8: writes eax to last to save the correct prev information in the stack of B .
"=a" (last)
This is last_b <==%eax .
The method of calling switch_to from context_switch () is:switch_to (Prev,next, prev);
So, this last is essentially prev, so after the SWITCH_TO macro executes, Prev_b is the correct process descriptor for a. Here, last is the equivalent of copying a process descriptor address from the process a stack to the stack of process B.
At this point,switch_to has finished executing , a stops running, and begins execution B. Thereafter, it may be in a schedule, process A is scheduled, there will be switch_to (c,a) Such a call, at this time, a again get scheduled, get dispatched, a process from Context_switch () switch_to The code behind the execution, this time, It sees that the prev_a will point to the C process descriptor.
-------------------------------------END----------------------------------------
Liu Jianxin + Original works reproduced please specify the source + "Linux kernel analysis" MOOC course
http://mooc.study.163.com/course/USTC-1000029000
-----------------------------------------------------------------------------------
Understanding process scheduling and process switching processes (Linux)