diff options
Diffstat (limited to 'Documentation/power/freezing-of-tasks.txt')
-rw-r--r-- | Documentation/power/freezing-of-tasks.txt | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index 04dc1cf9d215..38b57248fd61 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt | |||
@@ -19,12 +19,13 @@ we only consider hibernation, but the description also applies to suspend). | |||
19 | Namely, as the first step of the hibernation procedure the function | 19 | Namely, as the first step of the hibernation procedure the function |
20 | freeze_processes() (defined in kernel/power/process.c) is called. It executes | 20 | freeze_processes() (defined in kernel/power/process.c) is called. It executes |
21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and | 21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and |
22 | sends a fake signal to each of them. A task that receives such a signal and has | 22 | either wakes them up, if they are kernel threads, or sends fake signals to them, |
23 | TIF_FREEZE set, should react to it by calling the refrigerator() function | 23 | if they are user space processes. A task that has TIF_FREEZE set, should react |
24 | (defined in kernel/power/process.c), which sets the task's PF_FROZEN flag, | 24 | to it by calling the function called refrigerator() (defined in |
25 | changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is | 25 | kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state |
26 | cleared for it. Then, we say that the task is 'frozen' and therefore the set of | 26 | to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. |
27 | functions handling this mechanism is called 'the freezer' (these functions are | 27 | Then, we say that the task is 'frozen' and therefore the set of functions |
28 | handling this mechanism is referred to as 'the freezer' (these functions are | ||
28 | defined in kernel/power/process.c and include/linux/freezer.h). User space | 29 | defined in kernel/power/process.c and include/linux/freezer.h). User space |
29 | processes are generally frozen before kernel threads. | 30 | processes are generally frozen before kernel threads. |
30 | 31 | ||
@@ -35,21 +36,27 @@ task enter refrigerator() if the flag is set. | |||
35 | 36 | ||
36 | For user space processes try_to_freeze() is called automatically from the | 37 | For user space processes try_to_freeze() is called automatically from the |
37 | signal-handling code, but the freezable kernel threads need to call it | 38 | signal-handling code, but the freezable kernel threads need to call it |
38 | explicitly in suitable places. The code to do this may look like the following: | 39 | explicitly in suitable places or use the wait_event_freezable() or |
40 | wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) | ||
41 | that combine interruptible sleep with checking if TIF_FREEZE is set and calling | ||
42 | try_to_freeze(). The main loop of a freezable kernel thread may look like the | ||
43 | following one: | ||
39 | 44 | ||
45 | set_freezable(); | ||
40 | do { | 46 | do { |
41 | hub_events(); | 47 | hub_events(); |
42 | wait_event_interruptible(khubd_wait, | 48 | wait_event_freezable(khubd_wait, |
43 | !list_empty(&hub_event_list)); | 49 | !list_empty(&hub_event_list) || |
44 | try_to_freeze(); | 50 | kthread_should_stop()); |
45 | } while (!signal_pending(current)); | 51 | } while (!kthread_should_stop() || !list_empty(&hub_event_list)); |
46 | 52 | ||
47 | (from drivers/usb/core/hub.c::hub_thread()). | 53 | (from drivers/usb/core/hub.c::hub_thread()). |
48 | 54 | ||
49 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has | 55 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has |
50 | set TIF_FREEZE for it, the freezing of tasks will fail and the entire | 56 | set TIF_FREEZE for it, the freezing of tasks will fail and the entire |
51 | hibernation operation will be cancelled. For this reason, freezable kernel | 57 | hibernation operation will be cancelled. For this reason, freezable kernel |
52 | threads must call try_to_freeze() somewhere. | 58 | threads must call try_to_freeze() somewhere or use one of the |
59 | wait_event_freezable() and wait_event_freezable_timeout() macros. | ||
53 | 60 | ||
54 | After the system memory state has been restored from a hibernation image and | 61 | After the system memory state has been restored from a hibernation image and |
55 | devices have been reinitialized, the function thaw_processes() is called in | 62 | devices have been reinitialized, the function thaw_processes() is called in |
@@ -81,7 +88,16 @@ hibernation image has been created and before the system is finally powered off. | |||
81 | The majority of these are user space processes, but if any of the kernel threads | 88 | The majority of these are user space processes, but if any of the kernel threads |
82 | may cause something like this to happen, they have to be freezable. | 89 | may cause something like this to happen, they have to be freezable. |
83 | 90 | ||
84 | 2. The second reason is to prevent user space processes and some kernel threads | 91 | 2. Next, to create the hibernation image we need to free a sufficient amount of |
92 | memory (approximately 50% of available RAM) and we need to do that before | ||
93 | devices are deactivated, because we generally need them for swapping out. Then, | ||
94 | after the memory for the image has been freed, we don't want tasks to allocate | ||
95 | additional memory and we prevent them from doing that by freezing them earlier. | ||
96 | [Of course, this also means that device drivers should not allocate substantial | ||
97 | amounts of memory from their .suspend() callbacks before hibernation, but this | ||
98 | is e separate issue.] | ||
99 | |||
100 | 3. The third reason is to prevent user space processes and some kernel threads | ||
85 | from interfering with the suspending and resuming of devices. A user space | 101 | from interfering with the suspending and resuming of devices. A user space |
86 | process running on a second CPU while we are suspending devices may, for | 102 | process running on a second CPU while we are suspending devices may, for |
87 | example, be troublesome and without the freezing of tasks we would need some | 103 | example, be troublesome and without the freezing of tasks we would need some |
@@ -111,7 +127,7 @@ frozen before the driver's .suspend() callback is executed and it will be | |||
111 | thawed after the driver's .resume() callback has run, so it won't be accessing | 127 | thawed after the driver's .resume() callback has run, so it won't be accessing |
112 | the device while it's suspended. | 128 | the device while it's suspended. |
113 | 129 | ||
114 | 3. Another reason for freezing tasks is to prevent user space processes from | 130 | 4. Another reason for freezing tasks is to prevent user space processes from |
115 | realizing that hibernation (or suspend) operation takes place. Ideally, user | 131 | realizing that hibernation (or suspend) operation takes place. Ideally, user |
116 | space processes should not notice that such a system-wide operation has occurred | 132 | space processes should not notice that such a system-wide operation has occurred |
117 | and should continue running without any problems after the restore (or resume | 133 | and should continue running without any problems after the restore (or resume |