1
2#ifndef _LINUX_CGROUP_H
3#define _LINUX_CGROUP_H
4
5
6
7
8
9
10
11
12#include <linux/sched.h>
13#include <linux/cpumask.h>
14#include <linux/nodemask.h>
15#include <linux/rculist.h>
16#include <linux/cgroupstats.h>
17#include <linux/fs.h>
18#include <linux/seq_file.h>
19#include <linux/kernfs.h>
20#include <linux/jump_label.h>
21#include <linux/types.h>
22#include <linux/ns_common.h>
23#include <linux/nsproxy.h>
24#include <linux/user_namespace.h>
25#include <linux/refcount.h>
26#include <linux/kernel_stat.h>
27
28#include <linux/cgroup-defs.h>
29
30#ifdef CONFIG_CGROUPS
31
32
33
34
35
36
37#define CGROUP_WEIGHT_MIN 1
38#define CGROUP_WEIGHT_DFL 100
39#define CGROUP_WEIGHT_MAX 10000
40
41
42#define CSS_TASK_ITER_PROCS (1U << 0)
43
44#define CSS_TASK_ITER_THREADED (1U << 1)
45
46
47struct css_task_iter {
48 struct cgroup_subsys *ss;
49 unsigned int flags;
50
51 struct list_head *cset_pos;
52 struct list_head *cset_head;
53
54 struct list_head *tcset_pos;
55 struct list_head *tcset_head;
56
57 struct list_head *task_pos;
58 struct list_head *tasks_head;
59 struct list_head *mg_tasks_head;
60
61 struct css_set *cur_cset;
62 struct css_set *cur_dcset;
63 struct task_struct *cur_task;
64 struct list_head iters_node;
65};
66
67extern struct cgroup_root cgrp_dfl_root;
68extern struct css_set init_css_set;
69
70#define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
71#include <linux/cgroup_subsys.h>
72#undef SUBSYS
73
74#define SUBSYS(_x) \
75 extern struct static_key_true _x ## _cgrp_subsys_enabled_key; \
76 extern struct static_key_true _x ## _cgrp_subsys_on_dfl_key;
77#include <linux/cgroup_subsys.h>
78#undef SUBSYS
79
80
81
82
83
84#define cgroup_subsys_enabled(ss) \
85 static_branch_likely(&ss ## _enabled_key)
86
87
88
89
90
91#define cgroup_subsys_on_dfl(ss) \
92 static_branch_likely(&ss ## _on_dfl_key)
93
94bool css_has_online_children(struct cgroup_subsys_state *css);
95struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
96struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup,
97 struct cgroup_subsys *ss);
98struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
99 struct cgroup_subsys *ss);
100
101struct cgroup *cgroup_get_from_path(const char *path);
102struct cgroup *cgroup_get_from_fd(int fd);
103
104int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
105int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
106
107int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
108int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
109int cgroup_rm_cftypes(struct cftype *cfts);
110void cgroup_file_notify(struct cgroup_file *cfile);
111
112int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
113int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
114int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
115 struct pid *pid, struct task_struct *tsk);
116
117void cgroup_fork(struct task_struct *p);
118extern int cgroup_can_fork(struct task_struct *p);
119extern void cgroup_cancel_fork(struct task_struct *p);
120extern void cgroup_post_fork(struct task_struct *p);
121void cgroup_exit(struct task_struct *p);
122void cgroup_free(struct task_struct *p);
123
124int cgroup_init_early(void);
125int cgroup_init(void);
126
127
128
129
130
131struct cgroup_subsys_state *css_next_child(struct cgroup_subsys_state *pos,
132 struct cgroup_subsys_state *parent);
133struct cgroup_subsys_state *css_next_descendant_pre(struct cgroup_subsys_state *pos,
134 struct cgroup_subsys_state *css);
135struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state *pos);
136struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos,
137 struct cgroup_subsys_state *css);
138
139struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
140 struct cgroup_subsys_state **dst_cssp);
141struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
142 struct cgroup_subsys_state **dst_cssp);
143
144void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags,
145 struct css_task_iter *it);
146struct task_struct *css_task_iter_next(struct css_task_iter *it);
147void css_task_iter_end(struct css_task_iter *it);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167#define css_for_each_child(pos, parent) \
168 for ((pos) = css_next_child(NULL, (parent)); (pos); \
169 (pos) = css_next_child((pos), (parent)))
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227#define css_for_each_descendant_pre(pos, css) \
228 for ((pos) = css_next_descendant_pre(NULL, (css)); (pos); \
229 (pos) = css_next_descendant_pre((pos), (css)))
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250#define css_for_each_descendant_post(pos, css) \
251 for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \
252 (pos) = css_next_descendant_post((pos), (css)))
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272#define cgroup_taskset_for_each(task, dst_css, tset) \
273 for ((task) = cgroup_taskset_first((tset), &(dst_css)); \
274 (task); \
275 (task) = cgroup_taskset_next((tset), &(dst_css)))
276
277
278
279
280
281
282
283
284
285
286#define cgroup_taskset_for_each_leader(leader, dst_css, tset) \
287 for ((leader) = cgroup_taskset_first((tset), &(dst_css)); \
288 (leader); \
289 (leader) = cgroup_taskset_next((tset), &(dst_css))) \
290 if ((leader) != (leader)->group_leader) \
291 ; \
292 else
293
294
295
296
297
298
299
300
301
302
303
304static inline void css_get(struct cgroup_subsys_state *css)
305{
306 if (!(css->flags & CSS_NO_REF))
307 percpu_ref_get(&css->refcnt);
308}
309
310
311
312
313
314
315
316
317static inline void css_get_many(struct cgroup_subsys_state *css, unsigned int n)
318{
319 if (!(css->flags & CSS_NO_REF))
320 percpu_ref_get_many(&css->refcnt, n);
321}
322
323
324
325
326
327
328
329
330
331
332
333
334static inline bool css_tryget(struct cgroup_subsys_state *css)
335{
336 if (!(css->flags & CSS_NO_REF))
337 return percpu_ref_tryget(&css->refcnt);
338 return true;
339}
340
341
342
343
344
345
346
347
348
349
350
351static inline bool css_tryget_online(struct cgroup_subsys_state *css)
352{
353 if (!(css->flags & CSS_NO_REF))
354 return percpu_ref_tryget_live(&css->refcnt);
355 return true;
356}
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373static inline bool css_is_dying(struct cgroup_subsys_state *css)
374{
375 return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt);
376}
377
378
379
380
381
382
383
384static inline void css_put(struct cgroup_subsys_state *css)
385{
386 if (!(css->flags & CSS_NO_REF))
387 percpu_ref_put(&css->refcnt);
388}
389
390
391
392
393
394
395
396
397static inline void css_put_many(struct cgroup_subsys_state *css, unsigned int n)
398{
399 if (!(css->flags & CSS_NO_REF))
400 percpu_ref_put_many(&css->refcnt, n);
401}
402
403static inline void cgroup_get(struct cgroup *cgrp)
404{
405 css_get(&cgrp->self);
406}
407
408static inline bool cgroup_tryget(struct cgroup *cgrp)
409{
410 return css_tryget(&cgrp->self);
411}
412
413static inline void cgroup_put(struct cgroup *cgrp)
414{
415 css_put(&cgrp->self);
416}
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431#ifdef CONFIG_PROVE_RCU
432extern struct mutex cgroup_mutex;
433extern spinlock_t css_set_lock;
434#define task_css_set_check(task, __c) \
435 rcu_dereference_check((task)->cgroups, \
436 lockdep_is_held(&cgroup_mutex) || \
437 lockdep_is_held(&css_set_lock) || \
438 ((task)->flags & PF_EXITING) || (__c))
439#else
440#define task_css_set_check(task, __c) \
441 rcu_dereference((task)->cgroups)
442#endif
443
444
445
446
447
448
449
450
451
452
453#define task_css_check(task, subsys_id, __c) \
454 task_css_set_check((task), (__c))->subsys[(subsys_id)]
455
456
457
458
459
460
461
462static inline struct css_set *task_css_set(struct task_struct *task)
463{
464 return task_css_set_check(task, false);
465}
466
467
468
469
470
471
472
473
474static inline struct cgroup_subsys_state *task_css(struct task_struct *task,
475 int subsys_id)
476{
477 return task_css_check(task, subsys_id, false);
478}
479
480
481
482
483
484
485
486
487
488
489static inline struct cgroup_subsys_state *
490task_get_css(struct task_struct *task, int subsys_id)
491{
492 struct cgroup_subsys_state *css;
493
494 rcu_read_lock();
495 while (true) {
496 css = task_css(task, subsys_id);
497 if (likely(css_tryget_online(css)))
498 break;
499 cpu_relax();
500 }
501 rcu_read_unlock();
502 return css;
503}
504
505
506
507
508
509
510
511
512
513static inline bool task_css_is_root(struct task_struct *task, int subsys_id)
514{
515 return task_css_check(task, subsys_id, true) ==
516 init_css_set.subsys[subsys_id];
517}
518
519static inline struct cgroup *task_cgroup(struct task_struct *task,
520 int subsys_id)
521{
522 return task_css(task, subsys_id)->cgroup;
523}
524
525static inline struct cgroup *task_dfl_cgroup(struct task_struct *task)
526{
527 return task_css_set(task)->dfl_cgrp;
528}
529
530static inline struct cgroup *cgroup_parent(struct cgroup *cgrp)
531{
532 struct cgroup_subsys_state *parent_css = cgrp->self.parent;
533
534 if (parent_css)
535 return container_of(parent_css, struct cgroup, self);
536 return NULL;
537}
538
539
540
541
542
543
544
545
546
547
548static inline bool cgroup_is_descendant(struct cgroup *cgrp,
549 struct cgroup *ancestor)
550{
551 if (cgrp->root != ancestor->root || cgrp->level < ancestor->level)
552 return false;
553 return cgrp->ancestor_ids[ancestor->level] == ancestor->id;
554}
555
556
557
558
559
560
561
562
563
564
565static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
566 struct cgroup *ancestor)
567{
568 struct css_set *cset = task_css_set(task);
569
570 return cgroup_is_descendant(cset->dfl_cgrp, ancestor);
571}
572
573
574static inline bool cgroup_is_populated(struct cgroup *cgrp)
575{
576 return cgrp->nr_populated_csets + cgrp->nr_populated_domain_children +
577 cgrp->nr_populated_threaded_children;
578}
579
580
581static inline ino_t cgroup_ino(struct cgroup *cgrp)
582{
583 return cgrp->kn->id.ino;
584}
585
586
587static inline struct cftype *of_cft(struct kernfs_open_file *of)
588{
589 return of->kn->priv;
590}
591
592struct cgroup_subsys_state *of_css(struct kernfs_open_file *of);
593
594
595static inline struct cftype *seq_cft(struct seq_file *seq)
596{
597 return of_cft(seq->private);
598}
599
600static inline struct cgroup_subsys_state *seq_css(struct seq_file *seq)
601{
602 return of_css(seq->private);
603}
604
605
606
607
608
609
610static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen)
611{
612 return kernfs_name(cgrp->kn, buf, buflen);
613}
614
615static inline int cgroup_path(struct cgroup *cgrp, char *buf, size_t buflen)
616{
617 return kernfs_path(cgrp->kn, buf, buflen);
618}
619
620static inline void pr_cont_cgroup_name(struct cgroup *cgrp)
621{
622 pr_cont_kernfs_name(cgrp->kn);
623}
624
625static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
626{
627 pr_cont_kernfs_path(cgrp->kn);
628}
629
630static inline void cgroup_init_kthreadd(void)
631{
632
633
634
635
636
637 current->no_cgroup_migration = 1;
638}
639
640static inline void cgroup_kthread_ready(void)
641{
642
643
644
645
646 current->no_cgroup_migration = 0;
647}
648
649static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp)
650{
651 return &cgrp->kn->id;
652}
653
654void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
655 char *buf, size_t buflen);
656#else
657
658struct cgroup_subsys_state;
659struct cgroup;
660
661static inline void css_put(struct cgroup_subsys_state *css) {}
662static inline int cgroup_attach_task_all(struct task_struct *from,
663 struct task_struct *t) { return 0; }
664static inline int cgroupstats_build(struct cgroupstats *stats,
665 struct dentry *dentry) { return -EINVAL; }
666
667static inline void cgroup_fork(struct task_struct *p) {}
668static inline int cgroup_can_fork(struct task_struct *p) { return 0; }
669static inline void cgroup_cancel_fork(struct task_struct *p) {}
670static inline void cgroup_post_fork(struct task_struct *p) {}
671static inline void cgroup_exit(struct task_struct *p) {}
672static inline void cgroup_free(struct task_struct *p) {}
673
674static inline int cgroup_init_early(void) { return 0; }
675static inline int cgroup_init(void) { return 0; }
676static inline void cgroup_init_kthreadd(void) {}
677static inline void cgroup_kthread_ready(void) {}
678static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp)
679{
680 return NULL;
681}
682
683static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
684 struct cgroup *ancestor)
685{
686 return true;
687}
688
689static inline void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
690 char *buf, size_t buflen) {}
691#endif
692
693#ifdef CONFIG_CGROUPS
694
695
696
697void cgroup_rstat_updated(struct cgroup *cgrp, int cpu);
698void cgroup_rstat_flush(struct cgroup *cgrp);
699void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp);
700void cgroup_rstat_flush_hold(struct cgroup *cgrp);
701void cgroup_rstat_flush_release(void);
702
703
704
705
706#ifdef CONFIG_CGROUP_CPUACCT
707void cpuacct_charge(struct task_struct *tsk, u64 cputime);
708void cpuacct_account_field(struct task_struct *tsk, int index, u64 val);
709#else
710static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
711static inline void cpuacct_account_field(struct task_struct *tsk, int index,
712 u64 val) {}
713#endif
714
715void __cgroup_account_cputime(struct cgroup *cgrp, u64 delta_exec);
716void __cgroup_account_cputime_field(struct cgroup *cgrp,
717 enum cpu_usage_stat index, u64 delta_exec);
718
719static inline void cgroup_account_cputime(struct task_struct *task,
720 u64 delta_exec)
721{
722 struct cgroup *cgrp;
723
724 cpuacct_charge(task, delta_exec);
725
726 rcu_read_lock();
727 cgrp = task_dfl_cgroup(task);
728 if (cgroup_parent(cgrp))
729 __cgroup_account_cputime(cgrp, delta_exec);
730 rcu_read_unlock();
731}
732
733static inline void cgroup_account_cputime_field(struct task_struct *task,
734 enum cpu_usage_stat index,
735 u64 delta_exec)
736{
737 struct cgroup *cgrp;
738
739 cpuacct_account_field(task, index, delta_exec);
740
741 rcu_read_lock();
742 cgrp = task_dfl_cgroup(task);
743 if (cgroup_parent(cgrp))
744 __cgroup_account_cputime_field(cgrp, index, delta_exec);
745 rcu_read_unlock();
746}
747
748#else
749
750static inline void cgroup_account_cputime(struct task_struct *task,
751 u64 delta_exec) {}
752static inline void cgroup_account_cputime_field(struct task_struct *task,
753 enum cpu_usage_stat index,
754 u64 delta_exec) {}
755
756#endif
757
758
759
760
761
762#ifdef CONFIG_SOCK_CGROUP_DATA
763
764#if defined(CONFIG_CGROUP_NET_PRIO) || defined(CONFIG_CGROUP_NET_CLASSID)
765extern spinlock_t cgroup_sk_update_lock;
766#endif
767
768void cgroup_sk_alloc_disable(void);
769void cgroup_sk_alloc(struct sock_cgroup_data *skcd);
770void cgroup_sk_free(struct sock_cgroup_data *skcd);
771
772static inline struct cgroup *sock_cgroup_ptr(struct sock_cgroup_data *skcd)
773{
774#if defined(CONFIG_CGROUP_NET_PRIO) || defined(CONFIG_CGROUP_NET_CLASSID)
775 unsigned long v;
776
777
778
779
780
781 v = READ_ONCE(skcd->val);
782
783 if (v & 1)
784 return &cgrp_dfl_root.cgrp;
785
786 return (struct cgroup *)(unsigned long)v ?: &cgrp_dfl_root.cgrp;
787#else
788 return (struct cgroup *)(unsigned long)skcd->val;
789#endif
790}
791
792#else
793
794static inline void cgroup_sk_alloc(struct sock_cgroup_data *skcd) {}
795static inline void cgroup_sk_free(struct sock_cgroup_data *skcd) {}
796
797#endif
798
799struct cgroup_namespace {
800 refcount_t count;
801 struct ns_common ns;
802 struct user_namespace *user_ns;
803 struct ucounts *ucounts;
804 struct css_set *root_cset;
805};
806
807extern struct cgroup_namespace init_cgroup_ns;
808
809#ifdef CONFIG_CGROUPS
810
811void free_cgroup_ns(struct cgroup_namespace *ns);
812
813struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
814 struct user_namespace *user_ns,
815 struct cgroup_namespace *old_ns);
816
817int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
818 struct cgroup_namespace *ns);
819
820#else
821
822static inline void free_cgroup_ns(struct cgroup_namespace *ns) { }
823static inline struct cgroup_namespace *
824copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns,
825 struct cgroup_namespace *old_ns)
826{
827 return old_ns;
828}
829
830#endif
831
832static inline void get_cgroup_ns(struct cgroup_namespace *ns)
833{
834 if (ns)
835 refcount_inc(&ns->count);
836}
837
838static inline void put_cgroup_ns(struct cgroup_namespace *ns)
839{
840 if (ns && refcount_dec_and_test(&ns->count))
841 free_cgroup_ns(ns);
842}
843
844#endif
845