diff options
Diffstat (limited to 'Documentation/power/freezing-of-tasks.txt')
-rw-r--r-- | Documentation/power/freezing-of-tasks.txt | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index ec715cd78fbb..6ec291ea1c78 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt | |||
@@ -9,7 +9,7 @@ architectures). | |||
9 | 9 | ||
10 | II. How does it work? | 10 | II. How does it work? |
11 | 11 | ||
12 | There are four per-task flags used for that, PF_NOFREEZE, PF_FROZEN, TIF_FREEZE | 12 | There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN |
13 | and PF_FREEZER_SKIP (the last one is auxiliary). The tasks that have | 13 | and PF_FREEZER_SKIP (the last one is auxiliary). The tasks that have |
14 | PF_NOFREEZE unset (all user space processes and some kernel threads) are | 14 | PF_NOFREEZE unset (all user space processes and some kernel threads) are |
15 | regarded as 'freezable' and treated in a special way before the system enters a | 15 | regarded as 'freezable' and treated in a special way before the system enters a |
@@ -17,30 +17,31 @@ suspend state as well as before a hibernation image is created (in what follows | |||
17 | we only consider hibernation, but the description also applies to suspend). | 17 | we only consider hibernation, but the description also applies to suspend). |
18 | 18 | ||
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. A system-wide |
21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and | 21 | variable system_freezing_cnt (as opposed to a per-task flag) is used to indicate |
22 | either wakes them up, if they are kernel threads, or sends fake signals to them, | 22 | whether the system is to undergo a freezing operation. And freeze_processes() |
23 | if they are user space processes. A task that has TIF_FREEZE set, should react | 23 | sets this variable. After this, it executes try_to_freeze_tasks() that sends a |
24 | to it by calling the function called __refrigerator() (defined in | 24 | fake signal to all user space processes, and wakes up all the kernel threads. |
25 | kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state | 25 | All freezable tasks must react to that by calling try_to_freeze(), which |
26 | to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. | 26 | results in a call to __refrigerator() (defined in kernel/freezer.c), which sets |
27 | Then, we say that the task is 'frozen' and therefore the set of functions | 27 | the task's PF_FROZEN flag, changes its state to TASK_UNINTERRUPTIBLE and makes |
28 | handling this mechanism is referred to as 'the freezer' (these functions are | 28 | it loop until PF_FROZEN is cleared for it. Then, we say that the task is |
29 | defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). | 29 | 'frozen' and therefore the set of functions handling this mechanism is referred |
30 | User space processes are generally frozen before kernel threads. | 30 | to as 'the freezer' (these functions are defined in kernel/power/process.c, |
31 | kernel/freezer.c & include/linux/freezer.h). User space processes are generally | ||
32 | frozen before kernel threads. | ||
31 | 33 | ||
32 | __refrigerator() must not be called directly. Instead, use the | 34 | __refrigerator() must not be called directly. Instead, use the |
33 | try_to_freeze() function (defined in include/linux/freezer.h), that checks | 35 | try_to_freeze() function (defined in include/linux/freezer.h), that checks |
34 | the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the | 36 | if the task is to be frozen and makes the task enter __refrigerator(). |
35 | flag is set. | ||
36 | 37 | ||
37 | For user space processes try_to_freeze() is called automatically from the | 38 | For user space processes try_to_freeze() is called automatically from the |
38 | signal-handling code, but the freezable kernel threads need to call it | 39 | signal-handling code, but the freezable kernel threads need to call it |
39 | explicitly in suitable places or use the wait_event_freezable() or | 40 | explicitly in suitable places or use the wait_event_freezable() or |
40 | wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) | 41 | 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 | that combine interruptible sleep with checking if the task is to be frozen and |
42 | try_to_freeze(). The main loop of a freezable kernel thread may look like the | 43 | calling try_to_freeze(). The main loop of a freezable kernel thread may look |
43 | following one: | 44 | like the following one: |
44 | 45 | ||
45 | set_freezable(); | 46 | set_freezable(); |
46 | do { | 47 | do { |
@@ -53,7 +54,7 @@ following one: | |||
53 | (from drivers/usb/core/hub.c::hub_thread()). | 54 | (from drivers/usb/core/hub.c::hub_thread()). |
54 | 55 | ||
55 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has | 56 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has |
56 | set TIF_FREEZE for it, the freezing of tasks will fail and the entire | 57 | initiated a freezing operation, the freezing of tasks will fail and the entire |
57 | hibernation operation will be cancelled. For this reason, freezable kernel | 58 | hibernation operation will be cancelled. For this reason, freezable kernel |
58 | threads must call try_to_freeze() somewhere or use one of the | 59 | threads must call try_to_freeze() somewhere or use one of the |
59 | wait_event_freezable() and wait_event_freezable_timeout() macros. | 60 | wait_event_freezable() and wait_event_freezable_timeout() macros. |