diff options
Diffstat (limited to 'include/linux/freezer.h')
-rw-r--r-- | include/linux/freezer.h | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index d09af4b67cf1..ee899329e65a 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -75,28 +75,62 @@ static inline bool cgroup_freezing(struct task_struct *task) | |||
75 | */ | 75 | */ |
76 | 76 | ||
77 | 77 | ||
78 | /* Tell the freezer not to count the current task as freezable. */ | 78 | /** |
79 | * freezer_do_not_count - tell freezer to ignore %current | ||
80 | * | ||
81 | * Tell freezers to ignore the current task when determining whether the | ||
82 | * target frozen state is reached. IOW, the current task will be | ||
83 | * considered frozen enough by freezers. | ||
84 | * | ||
85 | * The caller shouldn't do anything which isn't allowed for a frozen task | ||
86 | * until freezer_cont() is called. Usually, freezer[_do_not]_count() pair | ||
87 | * wrap a scheduling operation and nothing much else. | ||
88 | */ | ||
79 | static inline void freezer_do_not_count(void) | 89 | static inline void freezer_do_not_count(void) |
80 | { | 90 | { |
81 | current->flags |= PF_FREEZER_SKIP; | 91 | current->flags |= PF_FREEZER_SKIP; |
82 | } | 92 | } |
83 | 93 | ||
84 | /* | 94 | /** |
85 | * Tell the freezer to count the current task as freezable again and try to | 95 | * freezer_count - tell freezer to stop ignoring %current |
86 | * freeze it. | 96 | * |
97 | * Undo freezer_do_not_count(). It tells freezers that %current should be | ||
98 | * considered again and tries to freeze if freezing condition is already in | ||
99 | * effect. | ||
87 | */ | 100 | */ |
88 | static inline void freezer_count(void) | 101 | static inline void freezer_count(void) |
89 | { | 102 | { |
90 | current->flags &= ~PF_FREEZER_SKIP; | 103 | current->flags &= ~PF_FREEZER_SKIP; |
104 | /* | ||
105 | * If freezing is in progress, the following paired with smp_mb() | ||
106 | * in freezer_should_skip() ensures that either we see %true | ||
107 | * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP. | ||
108 | */ | ||
109 | smp_mb(); | ||
91 | try_to_freeze(); | 110 | try_to_freeze(); |
92 | } | 111 | } |
93 | 112 | ||
94 | /* | 113 | /** |
95 | * Check if the task should be counted as freezable by the freezer | 114 | * freezer_should_skip - whether to skip a task when determining frozen |
115 | * state is reached | ||
116 | * @p: task in quesion | ||
117 | * | ||
118 | * This function is used by freezers after establishing %true freezing() to | ||
119 | * test whether a task should be skipped when determining the target frozen | ||
120 | * state is reached. IOW, if this function returns %true, @p is considered | ||
121 | * frozen enough. | ||
96 | */ | 122 | */ |
97 | static inline int freezer_should_skip(struct task_struct *p) | 123 | static inline bool freezer_should_skip(struct task_struct *p) |
98 | { | 124 | { |
99 | return !!(p->flags & PF_FREEZER_SKIP); | 125 | /* |
126 | * The following smp_mb() paired with the one in freezer_count() | ||
127 | * ensures that either freezer_count() sees %true freezing() or we | ||
128 | * see cleared %PF_FREEZER_SKIP and return %false. This makes it | ||
129 | * impossible for a task to slip frozen state testing after | ||
130 | * clearing %PF_FREEZER_SKIP. | ||
131 | */ | ||
132 | smp_mb(); | ||
133 | return p->flags & PF_FREEZER_SKIP; | ||
100 | } | 134 | } |
101 | 135 | ||
102 | /* | 136 | /* |