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
565
566
567static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
568 int ancestor_level)
569{
570 if (cgrp->level < ancestor_level)
571 return NULL;
572 while (cgrp && cgrp->level > ancestor_level)
573 cgrp = cgroup_parent(cgrp);
574 return cgrp;
575}
576
577
578
579
580
581
582
583
584
585
586static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
587 struct cgroup *ancestor)
588{
589 struct css_set *cset = task_css_set(task);
590
591 return cgroup_is_descendant(cset->dfl_cgrp, ancestor);
592}
593
594
595static inline bool cgroup_is_populated(struct cgroup *cgrp)
596{
597 return cgrp->nr_populated_csets + cgrp->nr_populated_domain_children +
598 cgrp->nr_populated_threaded_children;
599}
600
601
602static inline ino_t cgroup_ino(struct cgroup *cgrp)
603{
604 return cgrp->kn->id.ino;
605}
606
607
608static inline struct cftype *of_cft(struct kernfs_open_file *of)
609{
610 return of->kn->priv;
611}
612
613struct cgroup_subsys_state *of_css(struct kernfs_open_file *of);
614
615
616static inline struct cftype *seq_cft(struct seq_file *seq)
617{
618 return of_cft(seq->private);
619}
620
621static inline struct cgroup_subsys_state *seq_css(struct seq_file *seq)
622{
623 return of_css(seq->private);
624}
625
626
627
628
629
630
631static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen)
632{
633 return kernfs_name(cgrp->kn, buf, buflen);
634}
635
636static inline int cgroup_path(struct cgroup *cgrp, char *buf, size_t buflen)
637{
638 return kernfs_path(cgrp->kn, buf, buflen);
639}
640
641static inline void pr_cont_cgroup_name(struct cgroup *cgrp)
642{
643 pr_cont_kernfs_name(cgrp->kn);
644}
645
646static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
647{
648 pr_cont_kernfs_path(cgrp->kn);
649}
650
651static inline struct psi_group *cgroup_psi(struct cgroup *cgrp)
652{
653 return &cgrp->psi;
654}
655
656static inline void cgroup_init_kthreadd(void)
657{
658
659
660
661
662
663 current->no_cgroup_migration = 1;
664}
665
666static inline void cgroup_kthread_ready(void)
667{
668
669
670
671
672 current->no_cgroup_migration = 0;
673}
674
675static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp)
676{
677 return &cgrp->kn->id;
678}
679
680void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
681 char *buf, size_t buflen);
682#else
683
684struct cgroup_subsys_state;
685struct cgroup;
686
687static inline void css_put(struct cgroup_subsys_state *css) {}
688static inline int cgroup_attach_task_all(struct task_struct *from,
689 struct task_struct *t) { return 0; }
690static inline int cgroupstats_build(struct cgroupstats *stats,
691 struct dentry *dentry) { return -EINVAL; }
692
693static inline void cgroup_fork(struct task_struct *p) {}
694static inline int cgroup_can_fork(struct task_struct *p) { return 0; }
695static inline void cgroup_cancel_fork(struct task_struct *p) {}
696static inline void cgroup_post_fork(struct task_struct *p) {}
697static inline void cgroup_exit(struct task_struct *p) {}
698static inline void cgroup_free(struct task_struct *p) {}
699
700static inline int cgroup_init_early(void) { return 0; }
701static inline int cgroup_init(void) { return 0; }
702static inline void cgroup_init_kthreadd(void) {}
703static inline void cgroup_kthread_ready(void) {}
704static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp)
705{
706 return NULL;
707}
708
709static inline struct cgroup *cgroup_parent(struct cgroup *cgrp)
710{
711 return NULL;
712}
713
714static inline struct psi_group *cgroup_psi(struct cgroup *cgrp)
715{
716 return NULL;
717}
718
719static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
720 struct cgroup *ancestor)
721{
722 return true;
723}
724
725static inline void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
726 char *buf, size_t buflen) {}
727#endif
728
729#ifdef CONFIG_CGROUPS
730
731
732
733void cgroup_rstat_updated(struct cgroup *cgrp, int cpu);
734void cgroup_rstat_flush(struct cgroup *cgrp);
735void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp);
736void cgroup_rstat_flush_hold(struct cgroup *cgrp);
737void cgroup_rstat_flush_release(void);
738
739
740
741
742#ifdef CONFIG_CGROUP_CPUACCT
743void cpuacct_charge(struct task_struct *tsk, u64 cputime);
744void cpuacct_account_field(struct task_struct *tsk, int index, u64 val);
745#else
746static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
747static inline void cpuacct_account_field(struct task_struct *tsk, int index,
748 u64 val) {}
749#endif
750
751void __cgroup_account_cputime(struct cgroup *cgrp, u64 delta_exec);
752void __cgroup_account_cputime_field(struct cgroup *cgrp,
753 enum cpu_usage_stat index, u64 delta_exec);
754
755static inline void cgroup_account_cputime(struct task_struct *task,
756 u64 delta_exec)
757{
758 struct cgroup *cgrp;
759
760 cpuacct_charge(task, delta_exec);
761
762 rcu_read_lock();
763 cgrp = task_dfl_cgroup(task);
764 if (cgroup_parent(cgrp))
765 __cgroup_account_cputime(cgrp, delta_exec);
766 rcu_read_unlock();
767}
768
769static inline void cgroup_account_cputime_field(struct task_struct *task,
770 enum cpu_usage_stat index,
771 u64 delta_exec)
772{
773 struct cgroup *cgrp;
774
775 cpuacct_account_field(task, index, delta_exec);
776
777 rcu_read_lock();
778 cgrp = task_dfl_cgroup(task);
779 if (cgroup_parent(cgrp))
780 __cgroup_account_cputime_field(cgrp, index, delta_exec);
781 rcu_read_unlock();
782}
783
784#else
785
786static inline void cgroup_account_cputime(struct task_struct *task,
787 u64 delta_exec) {}
788static inline void cgroup_account_cputime_field(struct task_struct *task,
789 enum cpu_usage_stat index,
790 u64 delta_exec) {}
791
792#endif
793
794
795
796
797
798#ifdef CONFIG_SOCK_CGROUP_DATA
799
800#if defined(CONFIG_CGROUP_NET_PRIO) || defined(CONFIG_CGROUP_NET_CLASSID)
801extern spinlock_t cgroup_sk_update_lock;
802#endif
803
804void cgroup_sk_alloc_disable(void);
805void cgroup_sk_alloc(struct sock_cgroup_data *skcd);
806void cgroup_sk_free(struct sock_cgroup_data *skcd);
807
808static inline struct cgroup *sock_cgroup_ptr(struct sock_cgroup_data *skcd)
809{
810#if defined(CONFIG_CGROUP_NET_PRIO) || defined(CONFIG_CGROUP_NET_CLASSID)
811 unsigned long v;
812
813
814
815
816
817 v = READ_ONCE(skcd->val);
818
819 if (v & 1)
820 return &cgrp_dfl_root.cgrp;
821
822 return (struct cgroup *)(unsigned long)v ?: &cgrp_dfl_root.cgrp;
823#else
824 return (struct cgroup *)(unsigned long)skcd->val;
825#endif
826}
827
828#else
829
830static inline void cgroup_sk_alloc(struct sock_cgroup_data *skcd) {}
831static inline void cgroup_sk_free(struct sock_cgroup_data *skcd) {}
832
833#endif
834
835struct cgroup_namespace {
836 refcount_t count;
837 struct ns_common ns;
838 struct user_namespace *user_ns;
839 struct ucounts *ucounts;
840 struct css_set *root_cset;
841};
842
843extern struct cgroup_namespace init_cgroup_ns;
844
845#ifdef CONFIG_CGROUPS
846
847void free_cgroup_ns(struct cgroup_namespace *ns);
848
849struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
850 struct user_namespace *user_ns,
851 struct cgroup_namespace *old_ns);
852
853int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
854 struct cgroup_namespace *ns);
855
856#else
857
858static inline void free_cgroup_ns(struct cgroup_namespace *ns) { }
859static inline struct cgroup_namespace *
860copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns,
861 struct cgroup_namespace *old_ns)
862{
863 return old_ns;
864}
865
866#endif
867
868static inline void get_cgroup_ns(struct cgroup_namespace *ns)
869{
870 if (ns)
871 refcount_inc(&ns->count);
872}
873
874static inline void put_cgroup_ns(struct cgroup_namespace *ns)
875{
876 if (ns && refcount_dec_and_test(&ns->count))
877 free_cgroup_ns(ns);
878}
879
880#endif
881