Branch data Line data Source code
1 : : /*
2 : : * kernel/freezer.c - Function to freeze a process
3 : : *
4 : : * Originally from kernel/power/process.c
5 : : */
6 : :
7 : : #include <linux/interrupt.h>
8 : : #include <linux/suspend.h>
9 : : #include <linux/export.h>
10 : : #include <linux/syscalls.h>
11 : : #include <linux/freezer.h>
12 : : #include <linux/kthread.h>
13 : :
14 : : /* total number of freezing conditions in effect */
15 : : atomic_t system_freezing_cnt = ATOMIC_INIT(0);
16 : : EXPORT_SYMBOL(system_freezing_cnt);
17 : :
18 : : /* indicate whether PM freezing is in effect, protected by pm_mutex */
19 : : bool pm_freezing;
20 : : bool pm_nosig_freezing;
21 : :
22 : : /*
23 : : * Temporary export for the deadlock workaround in ata_scsi_hotplug().
24 : : * Remove once the hack becomes unnecessary.
25 : : */
26 : : EXPORT_SYMBOL_GPL(pm_freezing);
27 : :
28 : : /* protects freezing and frozen transitions */
29 : : static DEFINE_SPINLOCK(freezer_lock);
30 : :
31 : : /**
32 : : * freezing_slow_path - slow path for testing whether a task needs to be frozen
33 : : * @p: task to be tested
34 : : *
35 : : * This function is called by freezing() if system_freezing_cnt isn't zero
36 : : * and tests whether @p needs to enter and stay in frozen state. Can be
37 : : * called under any context. The freezers are responsible for ensuring the
38 : : * target tasks see the updated state.
39 : : */
40 : 0 : bool freezing_slow_path(struct task_struct *p)
41 : : {
42 [ # # ]: 0 : if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
43 : : return false;
44 : :
45 [ # # ]: 0 : if (pm_nosig_freezing || cgroup_freezing(p))
46 : : return true;
47 : :
48 [ # # ][ # # ]: 0 : if (pm_freezing && !(p->flags & PF_KTHREAD))
49 : : return true;
50 : :
51 : 0 : return false;
52 : : }
53 : : EXPORT_SYMBOL(freezing_slow_path);
54 : :
55 : : /* Refrigerator is place where frozen processes are stored :-). */
56 : 0 : bool __refrigerator(bool check_kthr_stop)
57 : : {
58 : : /* Hmm, should we be allowed to suspend when there are realtime
59 : : processes around? */
60 : : bool was_frozen = false;
61 : 0 : long save = current->state;
62 : :
63 : : pr_debug("%s entered refrigerator\n", current->comm);
64 : :
65 : : for (;;) {
66 : 0 : set_current_state(TASK_UNINTERRUPTIBLE);
67 : :
68 : : spin_lock_irq(&freezer_lock);
69 : 0 : current->flags |= PF_FROZEN;
70 [ # # ][ # # ]: 0 : if (!freezing(current) ||
71 [ # # ]: 0 : (check_kthr_stop && kthread_should_stop()))
72 : 0 : current->flags &= ~PF_FROZEN;
73 : : spin_unlock_irq(&freezer_lock);
74 : :
75 [ # # ]: 0 : if (!(current->flags & PF_FROZEN))
76 : : break;
77 : : was_frozen = true;
78 : 0 : schedule();
79 : 0 : }
80 : :
81 : : pr_debug("%s left refrigerator\n", current->comm);
82 : :
83 : : /*
84 : : * Restore saved task state before returning. The mb'd version
85 : : * needs to be used; otherwise, it might silently break
86 : : * synchronization which depends on ordered task state change.
87 : : */
88 : 0 : set_current_state(save);
89 : :
90 : 0 : return was_frozen;
91 : : }
92 : : EXPORT_SYMBOL(__refrigerator);
93 : :
94 : 0 : static void fake_signal_wake_up(struct task_struct *p)
95 : : {
96 : : unsigned long flags;
97 : :
98 [ # # ]: 0 : if (lock_task_sighand(p, &flags)) {
99 : : signal_wake_up(p, 0);
100 : 0 : unlock_task_sighand(p, &flags);
101 : : }
102 : 0 : }
103 : :
104 : : /**
105 : : * freeze_task - send a freeze request to given task
106 : : * @p: task to send the request to
107 : : *
108 : : * If @p is freezing, the freeze request is sent either by sending a fake
109 : : * signal (if it's not a kernel thread) or waking it up (if it's a kernel
110 : : * thread).
111 : : *
112 : : * RETURNS:
113 : : * %false, if @p is not freezing or already frozen; %true, otherwise
114 : : */
115 : 0 : bool freeze_task(struct task_struct *p)
116 : : {
117 : : unsigned long flags;
118 : :
119 : : /*
120 : : * This check can race with freezer_do_not_count, but worst case that
121 : : * will result in an extra wakeup being sent to the task. It does not
122 : : * race with freezer_count(), the barriers in freezer_count() and
123 : : * freezer_should_skip() ensure that either freezer_count() sees
124 : : * freezing == true in try_to_freeze() and freezes, or
125 : : * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task
126 : : * normally.
127 : : */
128 [ # # ]: 0 : if (freezer_should_skip(p))
129 : : return false;
130 : :
131 : 0 : spin_lock_irqsave(&freezer_lock, flags);
132 [ # # ][ # # ]: 0 : if (!freezing(p) || frozen(p)) {
133 : : spin_unlock_irqrestore(&freezer_lock, flags);
134 : 0 : return false;
135 : : }
136 : :
137 [ # # ]: 0 : if (!(p->flags & PF_KTHREAD))
138 : 0 : fake_signal_wake_up(p);
139 : : else
140 : 0 : wake_up_state(p, TASK_INTERRUPTIBLE);
141 : :
142 : : spin_unlock_irqrestore(&freezer_lock, flags);
143 : 0 : return true;
144 : : }
145 : :
146 : 0 : void __thaw_task(struct task_struct *p)
147 : : {
148 : : unsigned long flags;
149 : :
150 : : /*
151 : : * Clear freezing and kick @p if FROZEN. Clearing is guaranteed to
152 : : * be visible to @p as waking up implies wmb. Waking up inside
153 : : * freezer_lock also prevents wakeups from leaking outside
154 : : * refrigerator.
155 : : */
156 : 0 : spin_lock_irqsave(&freezer_lock, flags);
157 [ # # ]: 0 : if (frozen(p))
158 : 0 : wake_up_process(p);
159 : : spin_unlock_irqrestore(&freezer_lock, flags);
160 : 0 : }
161 : :
162 : : /**
163 : : * set_freezable - make %current freezable
164 : : *
165 : : * Mark %current freezable and enter refrigerator if necessary.
166 : : */
167 : 0 : bool set_freezable(void)
168 : : {
169 : : might_sleep();
170 : :
171 : : /*
172 : : * Modify flags while holding freezer_lock. This ensures the
173 : : * freezer notices that we aren't frozen yet or the freezing
174 : : * condition is visible to try_to_freeze() below.
175 : : */
176 : : spin_lock_irq(&freezer_lock);
177 : 2 : current->flags &= ~PF_NOFREEZE;
178 : : spin_unlock_irq(&freezer_lock);
179 : :
180 : 2 : return try_to_freeze();
181 : : }
182 : : EXPORT_SYMBOL(set_freezable);
|