diff options
-rw-r--r-- | include/linux/freezer.h | 9 | ||||
-rw-r--r-- | kernel/freezer.c | 25 |
2 files changed, 30 insertions, 4 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 3d50913d39d0..a0f1b3a3604f 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -49,6 +49,7 @@ static inline bool try_to_freeze(void) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | extern bool freeze_task(struct task_struct *p, bool sig_only); | 51 | extern bool freeze_task(struct task_struct *p, bool sig_only); |
52 | extern bool __set_freezable(bool with_signal); | ||
52 | 53 | ||
53 | #ifdef CONFIG_CGROUP_FREEZER | 54 | #ifdef CONFIG_CGROUP_FREEZER |
54 | extern bool cgroup_freezing(struct task_struct *task); | 55 | extern bool cgroup_freezing(struct task_struct *task); |
@@ -106,18 +107,18 @@ static inline int freezer_should_skip(struct task_struct *p) | |||
106 | /* | 107 | /* |
107 | * Tell the freezer that the current task should be frozen by it | 108 | * Tell the freezer that the current task should be frozen by it |
108 | */ | 109 | */ |
109 | static inline void set_freezable(void) | 110 | static inline bool set_freezable(void) |
110 | { | 111 | { |
111 | current->flags &= ~PF_NOFREEZE; | 112 | return __set_freezable(false); |
112 | } | 113 | } |
113 | 114 | ||
114 | /* | 115 | /* |
115 | * Tell the freezer that the current task should be frozen by it and that it | 116 | * Tell the freezer that the current task should be frozen by it and that it |
116 | * should send a fake signal to the task to freeze it. | 117 | * should send a fake signal to the task to freeze it. |
117 | */ | 118 | */ |
118 | static inline void set_freezable_with_signal(void) | 119 | static inline bool set_freezable_with_signal(void) |
119 | { | 120 | { |
120 | current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG); | 121 | return __set_freezable(true); |
121 | } | 122 | } |
122 | 123 | ||
123 | /* | 124 | /* |
diff --git a/kernel/freezer.c b/kernel/freezer.c index 95a123844241..b1e7a7b3d2cd 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c | |||
@@ -171,3 +171,28 @@ void __thaw_task(struct task_struct *p) | |||
171 | } | 171 | } |
172 | spin_unlock_irqrestore(&freezer_lock, flags); | 172 | spin_unlock_irqrestore(&freezer_lock, flags); |
173 | } | 173 | } |
174 | |||
175 | /** | ||
176 | * __set_freezable - make %current freezable | ||
177 | * @with_signal: do we want %TIF_SIGPENDING for notification too? | ||
178 | * | ||
179 | * Mark %current freezable and enter refrigerator if necessary. | ||
180 | */ | ||
181 | bool __set_freezable(bool with_signal) | ||
182 | { | ||
183 | might_sleep(); | ||
184 | |||
185 | /* | ||
186 | * Modify flags while holding freezer_lock. This ensures the | ||
187 | * freezer notices that we aren't frozen yet or the freezing | ||
188 | * condition is visible to try_to_freeze() below. | ||
189 | */ | ||
190 | spin_lock_irq(&freezer_lock); | ||
191 | current->flags &= ~PF_NOFREEZE; | ||
192 | if (with_signal) | ||
193 | current->flags &= ~PF_FREEZER_NOSIG; | ||
194 | spin_unlock_irq(&freezer_lock); | ||
195 | |||
196 | return try_to_freeze(); | ||
197 | } | ||
198 | EXPORT_SYMBOL(__set_freezable); | ||