1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/cgroup.h> 3 #include <linux/sched.h> 4 #include <linux/sched/task.h> 5 #include <linux/sched/signal.h> 6 7 #include "cgroup-internal.h" 8 9 #include <trace/events/cgroup.h> 10 11 /* 12 * Update CGRP_FROZEN of cgroup.flag 13 * Return true if flags is updated; false if flags has no change 14 */ 15 static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen) 16 { 17 lockdep_assert_held(&css_set_lock); 18 19 /* Already there? */ 20 if (test_bit(CGRP_FROZEN, &cgrp->flags) == frozen) 21 return false; 22 23 assign_bit(CGRP_FROZEN, &cgrp->flags, frozen); 24 25 cgroup_file_notify(&cgrp->events_file); 26 TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen); 27 return true; 28 } 29 30 /* 31 * Propagate the cgroup frozen state upwards by the cgroup tree. 32 */ 33 static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen) 34 { 35 int desc = 1; 36 37 /* 38 * If the new state is frozen, some freezing ancestor cgroups may change 39 * their state too, depending on if all their descendants are frozen. 40 * 41 * Otherwise, all ancestor cgroups are forced into the non-frozen state. 42 */ 43 while ((cgrp = cgroup_parent(cgrp))) { 44 if (frozen) { 45 cgrp->freezer.nr_frozen_descendants += desc; 46 if (!test_bit(CGRP_FREEZE, &cgrp->flags) || 47 (cgrp->freezer.nr_frozen_descendants != 48 cgrp->nr_descendants)) 49 continue; 50 } else { 51 cgrp->freezer.nr_frozen_descendants -= desc; 52 } 53 54 if (cgroup_update_frozen_flag(cgrp, frozen)) 55 desc++; 56 } 57 } 58 59 /* 60 * Revisit the cgroup frozen state. 61 * Checks if the cgroup is really frozen and perform all state transitions. 62 */ 63 void cgroup_update_frozen(struct cgroup *cgrp) 64 { 65 bool frozen; 66 67 /* 68 * If the cgroup has to be frozen (CGRP_FREEZE bit set), 69 * and all tasks are frozen and/or stopped, let's consider 70 * the cgroup frozen. Otherwise it's not frozen. 71 */ 72 frozen = test_bit(CGRP_FREEZE, &cgrp->flags) && 73 cgrp->freezer.nr_frozen_tasks == __cgroup_task_count(cgrp); 74 75 /* If flags is updated, update the state of ancestor cgroups. */ 76 if (cgroup_update_frozen_flag(cgrp, frozen)) 77 cgroup_propagate_frozen(cgrp, frozen); 78 } 79 80 /* 81 * Increment cgroup's nr_frozen_tasks. 82 */ 83 static void cgroup_inc_frozen_cnt(struct cgroup *cgrp) 84 { 85 cgrp->freezer.nr_frozen_tasks++; 86 } 87 88 /* 89 * Decrement cgroup's nr_frozen_tasks. 90 */ 91 static void cgroup_dec_frozen_cnt(struct cgroup *cgrp) 92 { 93 cgrp->freezer.nr_frozen_tasks--; 94 WARN_ON_ONCE(cgrp->freezer.nr_frozen_tasks < 0); 95 } 96 97 /* 98 * Enter frozen/stopped state, if not yet there. Update cgroup's counters, 99 * and revisit the state of the cgroup, if necessary. 100 */ 101 void cgroup_enter_frozen(void) 102 { 103 struct cgroup *cgrp; 104 105 if (current->frozen) 106 return; 107 108 spin_lock_irq(&css_set_lock); 109 current->frozen = true; 110 cgrp = task_dfl_cgroup(current); 111 cgroup_inc_frozen_cnt(cgrp); 112 cgroup_update_frozen(cgrp); 113 spin_unlock_irq(&css_set_lock); 114 } 115 116 /* 117 * Conditionally leave frozen/stopped state. Update cgroup's counters, 118 * and revisit the state of the cgroup, if necessary. 119 * 120 * If always_leave is not set, and the cgroup is freezing, 121 * we're racing with the cgroup freezing. In this case, we don't 122 * drop the frozen counter to avoid a transient switch to 123 * the unfrozen state. 124 */ 125 void cgroup_leave_frozen(bool always_leave) 126 { 127 struct cgroup *cgrp; 128 129 spin_lock_irq(&css_set_lock); 130 cgrp = task_dfl_cgroup(current); 131 if (always_leave || !test_bit(CGRP_FREEZE, &cgrp->flags)) { 132 cgroup_dec_frozen_cnt(cgrp); 133 cgroup_update_frozen(cgrp); 134 WARN_ON_ONCE(!current->frozen); 135 current->frozen = false; 136 } else if (!(current->jobctl & JOBCTL_TRAP_FREEZE)) { 137 spin_lock(¤t->sighand->siglock); 138 current->jobctl |= JOBCTL_TRAP_FREEZE; 139 set_thread_flag(TIF_SIGPENDING); 140 spin_unlock(¤t->sighand->siglock); 141 } 142 spin_unlock_irq(&css_set_lock); 143 } 144 145 /* 146 * Freeze or unfreeze the task by setting or clearing the JOBCTL_TRAP_FREEZE 147 * jobctl bit. 148 */ 149 static void cgroup_freeze_task(struct task_struct *task, bool freeze) 150 { 151 unsigned long flags; 152 153 /* If the task is about to die, don't bother with freezing it. */ 154 if (!lock_task_sighand(task, &flags)) 155 return; 156 157 if (freeze) { 158 task->jobctl |= JOBCTL_TRAP_FREEZE; 159 signal_wake_up(task, false); 160 } else { 161 task->jobctl &= ~JOBCTL_TRAP_FREEZE; 162 wake_up_process(task); 163 } 164 165 unlock_task_sighand(task, &flags); 166 } 167 168 /* 169 * Freeze or unfreeze all tasks in the given cgroup. 170 */ 171 static void cgroup_do_freeze(struct cgroup *cgrp, bool freeze, u64 ts_nsec) 172 { 173 struct css_task_iter it; 174 struct task_struct *task; 175 176 lockdep_assert_held(&cgroup_mutex); 177 178 spin_lock_irq(&css_set_lock); 179 write_seqcount_begin(&cgrp->freezer.freeze_seq); 180 if (freeze) { 181 set_bit(CGRP_FREEZE, &cgrp->flags); 182 cgrp->freezer.freeze_start_nsec = ts_nsec; 183 } else { 184 clear_bit(CGRP_FREEZE, &cgrp->flags); 185 cgrp->freezer.frozen_nsec += (ts_nsec - 186 cgrp->freezer.freeze_start_nsec); 187 } 188 write_seqcount_end(&cgrp->freezer.freeze_seq); 189 spin_unlock_irq(&css_set_lock); 190 191 if (freeze) 192 TRACE_CGROUP_PATH(freeze, cgrp); 193 else 194 TRACE_CGROUP_PATH(unfreeze, cgrp); 195 196 css_task_iter_start(&cgrp->self, 0, &it); 197 while ((task = css_task_iter_next(&it))) { 198 /* 199 * Ignore kernel threads here. Freezing cgroups containing 200 * kthreads isn't supported. 201 */ 202 if (task->flags & PF_KTHREAD) 203 continue; 204 cgroup_freeze_task(task, freeze); 205 } 206 css_task_iter_end(&it); 207 208 /* 209 * Cgroup state should be revisited here to cover empty leaf cgroups 210 * and cgroups which descendants are already in the desired state. 211 */ 212 spin_lock_irq(&css_set_lock); 213 if (cgrp->nr_descendants == cgrp->freezer.nr_frozen_descendants) 214 cgroup_update_frozen(cgrp); 215 spin_unlock_irq(&css_set_lock); 216 } 217 218 /* 219 * Adjust the task state (freeze or unfreeze) and revisit the state of 220 * source and destination cgroups. 221 */ 222 void cgroup_freezer_migrate_task(struct task_struct *task, 223 struct cgroup *src, struct cgroup *dst) 224 { 225 lockdep_assert_held(&css_set_lock); 226 227 /* 228 * Kernel threads are not supposed to be frozen at all. 229 */ 230 if (task->flags & PF_KTHREAD) 231 return; 232 233 /* 234 * It's not necessary to do changes if both of the src and dst cgroups 235 * are not freezing and task is not frozen. 236 */ 237 if (!test_bit(CGRP_FREEZE, &src->flags) && 238 !test_bit(CGRP_FREEZE, &dst->flags) && 239 !task->frozen) 240 return; 241 242 /* 243 * Adjust counters of freezing and frozen tasks. 244 * Note, that if the task is frozen, but the destination cgroup is not 245 * frozen, we bump both counters to keep them balanced. 246 */ 247 if (task->frozen) { 248 cgroup_inc_frozen_cnt(dst); 249 cgroup_dec_frozen_cnt(src); 250 } 251 cgroup_update_frozen(dst); 252 cgroup_update_frozen(src); 253 254 /* 255 * Force the task to the desired state. 256 */ 257 cgroup_freeze_task(task, test_bit(CGRP_FREEZE, &dst->flags)); 258 } 259 260 void cgroup_freeze(struct cgroup *cgrp, bool freeze) 261 { 262 struct cgroup_subsys_state *css; 263 struct cgroup *parent; 264 struct cgroup *dsct; 265 bool applied = false; 266 u64 ts_nsec; 267 bool old_e; 268 269 lockdep_assert_held(&cgroup_mutex); 270 271 /* 272 * Nothing changed? Just exit. 273 */ 274 if (cgrp->freezer.freeze == freeze) 275 return; 276 277 cgrp->freezer.freeze = freeze; 278 ts_nsec = ktime_get_ns(); 279 280 /* 281 * Propagate changes downwards the cgroup tree. 282 */ 283 css_for_each_descendant_pre(css, &cgrp->self) { 284 dsct = css->cgroup; 285 286 if (cgroup_is_dead(dsct)) 287 continue; 288 289 /* 290 * e_freeze is affected by parent's e_freeze and dst's freeze. 291 * If old e_freeze eq new e_freeze, no change, its children 292 * will not be affected. So do nothing and skip the subtree 293 */ 294 old_e = dsct->freezer.e_freeze; 295 parent = cgroup_parent(dsct); 296 dsct->freezer.e_freeze = (dsct->freezer.freeze || 297 parent->freezer.e_freeze); 298 if (dsct->freezer.e_freeze == old_e) { 299 css = css_rightmost_descendant(css); 300 continue; 301 } 302 303 /* 304 * Do change actual state: freeze or unfreeze. 305 */ 306 cgroup_do_freeze(dsct, freeze, ts_nsec); 307 applied = true; 308 } 309 310 /* 311 * Even if the actual state hasn't changed, let's notify a user. 312 * The state can be enforced by an ancestor cgroup: the cgroup 313 * can already be in the desired state or it can be locked in the 314 * opposite state, so that the transition will never happen. 315 * In both cases it's better to notify a user, that there is 316 * nothing to wait for. 317 */ 318 if (!applied) { 319 TRACE_CGROUP_PATH(notify_frozen, cgrp, 320 test_bit(CGRP_FROZEN, &cgrp->flags)); 321 cgroup_file_notify(&cgrp->events_file); 322 } 323 } 324