aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/freezer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/freezer.h')
-rw-r--r--include/linux/freezer.h69
1 files changed, 56 insertions, 13 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 5e75e26d4787..4631086f5060 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -37,25 +37,25 @@ static inline void do_not_freeze(struct task_struct *p)
37 37
38/* 38/*
39 * Wake up a frozen process 39 * Wake up a frozen process
40 *
41 * task_lock() is taken to prevent the race with refrigerator() which may
42 * occur if the freezing of tasks fails. Namely, without the lock, if the
43 * freezing of tasks failed, thaw_tasks() might have run before a task in
44 * refrigerator() could call frozen_process(), in which case the task would be
45 * frozen and no one would thaw it.
40 */ 46 */
41static inline int thaw_process(struct task_struct *p) 47static inline int thaw_process(struct task_struct *p)
42{ 48{
49 task_lock(p);
43 if (frozen(p)) { 50 if (frozen(p)) {
44 p->flags &= ~PF_FROZEN; 51 p->flags &= ~PF_FROZEN;
52 task_unlock(p);
45 wake_up_process(p); 53 wake_up_process(p);
46 return 1; 54 return 1;
47 } 55 }
48 return 0;
49}
50
51/*
52 * freezing is complete, mark process as frozen
53 */
54static inline void frozen_process(struct task_struct *p)
55{
56 p->flags |= PF_FROZEN;
57 wmb();
58 clear_tsk_thread_flag(p, TIF_FREEZE); 56 clear_tsk_thread_flag(p, TIF_FREEZE);
57 task_unlock(p);
58 return 0;
59} 59}
60 60
61extern void refrigerator(void); 61extern void refrigerator(void);
@@ -71,14 +71,55 @@ static inline int try_to_freeze(void)
71 return 0; 71 return 0;
72} 72}
73 73
74extern void thaw_some_processes(int all); 74/*
75 * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
76 * calls wait_for_completion(&vfork) and reset right after it returns from this
77 * function. Next, the parent should call try_to_freeze() to freeze itself
78 * appropriately in case the child has exited before the freezing of tasks is
79 * complete. However, we don't want kernel threads to be frozen in unexpected
80 * places, so we allow them to block freeze_processes() instead or to set
81 * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
82 * parents. Fortunately, in the ____call_usermodehelper() case the parent won't
83 * really block freeze_processes(), since ____call_usermodehelper() (the child)
84 * does a little before exec/exit and it can't be frozen before waking up the
85 * parent.
86 */
87
88/*
89 * If the current task is a user space one, tell the freezer not to count it as
90 * freezable.
91 */
92static inline void freezer_do_not_count(void)
93{
94 if (current->mm)
95 current->flags |= PF_FREEZER_SKIP;
96}
97
98/*
99 * If the current task is a user space one, tell the freezer to count it as
100 * freezable again and try to freeze it.
101 */
102static inline void freezer_count(void)
103{
104 if (current->mm) {
105 current->flags &= ~PF_FREEZER_SKIP;
106 try_to_freeze();
107 }
108}
109
110/*
111 * Check if the task should be counted as freezeable by the freezer
112 */
113static inline int freezer_should_skip(struct task_struct *p)
114{
115 return !!(p->flags & PF_FREEZER_SKIP);
116}
75 117
76#else 118#else
77static inline int frozen(struct task_struct *p) { return 0; } 119static inline int frozen(struct task_struct *p) { return 0; }
78static inline int freezing(struct task_struct *p) { return 0; } 120static inline int freezing(struct task_struct *p) { return 0; }
79static inline void freeze(struct task_struct *p) { BUG(); } 121static inline void freeze(struct task_struct *p) { BUG(); }
80static inline int thaw_process(struct task_struct *p) { return 1; } 122static inline int thaw_process(struct task_struct *p) { return 1; }
81static inline void frozen_process(struct task_struct *p) { BUG(); }
82 123
83static inline void refrigerator(void) {} 124static inline void refrigerator(void) {}
84static inline int freeze_processes(void) { BUG(); return 0; } 125static inline int freeze_processes(void) { BUG(); return 0; }
@@ -86,5 +127,7 @@ static inline void thaw_processes(void) {}
86 127
87static inline int try_to_freeze(void) { return 0; } 128static inline int try_to_freeze(void) { return 0; }
88 129
89 130static inline void freezer_do_not_count(void) {}
131static inline void freezer_count(void) {}
132static inline int freezer_should_skip(struct task_struct *p) { return 0; }
90#endif 133#endif