~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/core/netclassid_cgroup.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * net/core/netclassid_cgroup.c Classid Cgroupfs Handling
  4  *
  5  * Authors:     Thomas Graf <tgraf@suug.ch>
  6  */
  7 
  8 #include <linux/slab.h>
  9 #include <linux/cgroup.h>
 10 #include <linux/fdtable.h>
 11 #include <linux/sched/task.h>
 12 
 13 #include <net/cls_cgroup.h>
 14 #include <net/sock.h>
 15 
 16 static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
 17 {
 18         return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
 19 }
 20 
 21 struct cgroup_cls_state *task_cls_state(struct task_struct *p)
 22 {
 23         return css_cls_state(task_css_check(p, net_cls_cgrp_id,
 24                                             rcu_read_lock_bh_held()));
 25 }
 26 EXPORT_SYMBOL_GPL(task_cls_state);
 27 
 28 static struct cgroup_subsys_state *
 29 cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
 30 {
 31         struct cgroup_cls_state *cs;
 32 
 33         cs = kzalloc(sizeof(*cs), GFP_KERNEL);
 34         if (!cs)
 35                 return ERR_PTR(-ENOMEM);
 36 
 37         return &cs->css;
 38 }
 39 
 40 static int cgrp_css_online(struct cgroup_subsys_state *css)
 41 {
 42         struct cgroup_cls_state *cs = css_cls_state(css);
 43         struct cgroup_cls_state *parent = css_cls_state(css->parent);
 44 
 45         if (parent)
 46                 cs->classid = parent->classid;
 47 
 48         return 0;
 49 }
 50 
 51 static void cgrp_css_free(struct cgroup_subsys_state *css)
 52 {
 53         kfree(css_cls_state(css));
 54 }
 55 
 56 /*
 57  * To avoid freezing of sockets creation for tasks with big number of threads
 58  * and opened sockets lets release file_lock every 1000 iterated descriptors.
 59  * New sockets will already have been created with new classid.
 60  */
 61 
 62 struct update_classid_context {
 63         u32 classid;
 64         unsigned int batch;
 65 };
 66 
 67 #define UPDATE_CLASSID_BATCH 1000
 68 
 69 static int update_classid_sock(const void *v, struct file *file, unsigned int n)
 70 {
 71         struct update_classid_context *ctx = (void *)v;
 72         struct socket *sock = sock_from_file(file);
 73 
 74         if (sock)
 75                 sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid);
 76         if (--ctx->batch == 0) {
 77                 ctx->batch = UPDATE_CLASSID_BATCH;
 78                 return n + 1;
 79         }
 80         return 0;
 81 }
 82 
 83 static void update_classid_task(struct task_struct *p, u32 classid)
 84 {
 85         struct update_classid_context ctx = {
 86                 .classid = classid,
 87                 .batch = UPDATE_CLASSID_BATCH
 88         };
 89         unsigned int fd = 0;
 90 
 91         /* Only update the leader task, when many threads in this task,
 92          * so it can avoid the useless traversal.
 93          */
 94         if (p != p->group_leader)
 95                 return;
 96 
 97         do {
 98                 task_lock(p);
 99                 fd = iterate_fd(p->files, fd, update_classid_sock, &ctx);
100                 task_unlock(p);
101                 cond_resched();
102         } while (fd);
103 }
104 
105 static void cgrp_attach(struct cgroup_taskset *tset)
106 {
107         struct cgroup_subsys_state *css;
108         struct task_struct *p;
109 
110         cgroup_taskset_for_each(p, css, tset) {
111                 update_classid_task(p, css_cls_state(css)->classid);
112         }
113 }
114 
115 static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
116 {
117         return css_cls_state(css)->classid;
118 }
119 
120 static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
121                          u64 value)
122 {
123         struct cgroup_cls_state *cs = css_cls_state(css);
124         struct css_task_iter it;
125         struct task_struct *p;
126 
127         cs->classid = (u32)value;
128 
129         css_task_iter_start(css, 0, &it);
130         while ((p = css_task_iter_next(&it)))
131                 update_classid_task(p, cs->classid);
132         css_task_iter_end(&it);
133 
134         return 0;
135 }
136 
137 static struct cftype ss_files[] = {
138         {
139                 .name           = "classid",
140                 .read_u64       = read_classid,
141                 .write_u64      = write_classid,
142         },
143         { }     /* terminate */
144 };
145 
146 struct cgroup_subsys net_cls_cgrp_subsys = {
147         .css_alloc              = cgrp_css_alloc,
148         .css_online             = cgrp_css_online,
149         .css_free               = cgrp_css_free,
150         .attach                 = cgrp_attach,
151         .legacy_cftypes         = ss_files,
152 };
153 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php