1 What is a process freeze
Process freeze technology (freezing of tasks) refers to the "controllable" pause state of the user process and some kernel threads when the system hibernate or suspend.
2 Why do I need to freeze technology
Assuming there is no freeze technique, the process can pause at any of the scheduled points, and until Cpu_down is paused and migrated. This can cause a lot of problems for the system:
(1) It is possible to destroy the file system. Between the system creation hibernate image and the CPU down, if a process is still modifying the contents of the file system, this will cause the system to recover from the full recovery of the file system;
(2) It is possible to cause the creation of hibernation image to fail. Creating a hibernation image requires sufficient memory space, but during this time, if there is a process that is requesting memory, it can cause the creation to fail;
(3) It is possible to interfere with the suspend and resume of the equipment. Before the CPU is down, device suspend, if the process is still accessing the device, especially access to competitive resources, it is possible to cause equipment suspend exception;
(4) It is possible to cause the process-aware system to hibernate. The ideal state of system hibernation is that all tasks are not aware of the hibernation process, and all automatically resume work after waking up, but some processes, such as a process that requires all CPU online to function properly, will work abnormally during hibernation if the process does not freeze.
3 Code Implementation Framework
Frozen objects are entities in the kernel that can be scheduled for execution, including user processes, kernel threads, and work_queue. The user process can be frozen by default, using the signal processing mechanism, kernel threads and work_queue are not frozen by default, and a few kernel threads and Work_queue specify Freezable flags when they are created, which require the freeze state to be judged. When the system enters freezing, it actively pauses the operation.
Kernel threads can be called Kthread_freezable_should_stop to determine the freezing state, and actively call __refrigerator into the freeze; Work_queue by judging Max_ The active property, if max_active=0, does not queue up for new work, and all work is deferred.
There are three important global variables that mark the system's Freeze state: Pm_freezing, system_freezing_cnt, and pm_nosig_freezing, if all 0, indicate that the system does not enter a freeze; system_freezing_cnt >0 indicates that the system is frozen, pm_freezing=true represents a freeze on the user process, pm_nosig_freezing=true represents freezing kernel threads and workqueue. They are placed in the freeze_processes and Freeze_kernel_threads, zeroed in Thaw_processes and Thaw_kernel_threads.
Fake_signal_wake_up function skillfully utilizes the signal processing mechanism, only sets the tif_sigpending bit of the task, but does not transmit any signal, then wakes up the task, so that the task will enter the signal processing flow when returning to the user state, check the system's freeze state, and do the corresponding treatment.
The code for the task's active invocation of Try_to_freeze is as follows:
- Static inline bool Try_to_freeze_unsafe (void)
- {
- if (likely (current))//Check if the system is in freezing state
- return false;
- return __refrigerator (FALSE); Active entry Freeze
- }
- Static inline bool Freezing (struct task_struct *p)
- {
- if (Likely (!atomic_read (&system_freezing_cnt)))//system overall into freezing
- return false;
- Return Freezing_slow_path (P);
- }
- BOOL Freezing_slow_path (struct task_struct *p)
- {
- if (P->flags & Pf_nofreeze)//Whether the current process is allowed to freeze
- return false;
- if (pm_nosig_freezing | | cgroup_freezing (P))//system freezes Kernel threads
- return true;
- if (pm_freezing &&!) ( P->flags & Pf_kthread)//system freezes user process
- return true;
- return false;
- }
The main function that goes into the frozen state until recovery:
BOOL __refrigerator (bool check_kthr_stop)
- {
- ...
- for (;;) {
- Set_current_state (task_uninterruptible); Set the process to uninterruptible state
- SPIN_LOCK_IRQ (&freezer_lock);
- Current->flags |= Pf_frozen; Set frozen state
- if (!freezing (current) | |
- (Check_kthr_stop && kthread_should_stop ())) Determine if the system is still frozen
- Current->flags &= ~pf_frozen; Unfreeze State if the system is unfrozen
- SPIN_UNLOCK_IRQ (&freezer_lock);
- if (! ( Current->flags & Pf_frozen))//If the freeze has been canceled, jump out of the loop, resume execution
- Break
- Was_frozen = true;
- Schedule ();
- }
- ......
- }
4 Reference Documents
(1) http://www.wowotech.net/linux_kenrel/suspend_and_resume.html
(2) http://www.wowotech.net/linux_kenrel/std_str_func.html
(3) Kenrel Document:freezing-of-tasks.txt
Linux process Freeze Technology