aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/cgroup.c')
-rw-r--r--kernel/bpf/cgroup.c74
1 files changed, 52 insertions, 22 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 549f6fbcc461..00f6ed2e4f9a 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -25,6 +25,7 @@ EXPORT_SYMBOL(cgroup_bpf_enabled_key);
25 */ 25 */
26void cgroup_bpf_put(struct cgroup *cgrp) 26void cgroup_bpf_put(struct cgroup *cgrp)
27{ 27{
28 enum bpf_cgroup_storage_type stype;
28 unsigned int type; 29 unsigned int type;
29 30
30 for (type = 0; type < ARRAY_SIZE(cgrp->bpf.progs); type++) { 31 for (type = 0; type < ARRAY_SIZE(cgrp->bpf.progs); type++) {
@@ -34,8 +35,10 @@ void cgroup_bpf_put(struct cgroup *cgrp)
34 list_for_each_entry_safe(pl, tmp, progs, node) { 35 list_for_each_entry_safe(pl, tmp, progs, node) {
35 list_del(&pl->node); 36 list_del(&pl->node);
36 bpf_prog_put(pl->prog); 37 bpf_prog_put(pl->prog);
37 bpf_cgroup_storage_unlink(pl->storage); 38 for_each_cgroup_storage_type(stype) {
38 bpf_cgroup_storage_free(pl->storage); 39 bpf_cgroup_storage_unlink(pl->storage[stype]);
40 bpf_cgroup_storage_free(pl->storage[stype]);
41 }
39 kfree(pl); 42 kfree(pl);
40 static_branch_dec(&cgroup_bpf_enabled_key); 43 static_branch_dec(&cgroup_bpf_enabled_key);
41 } 44 }
@@ -97,6 +100,7 @@ static int compute_effective_progs(struct cgroup *cgrp,
97 enum bpf_attach_type type, 100 enum bpf_attach_type type,
98 struct bpf_prog_array __rcu **array) 101 struct bpf_prog_array __rcu **array)
99{ 102{
103 enum bpf_cgroup_storage_type stype;
100 struct bpf_prog_array *progs; 104 struct bpf_prog_array *progs;
101 struct bpf_prog_list *pl; 105 struct bpf_prog_list *pl;
102 struct cgroup *p = cgrp; 106 struct cgroup *p = cgrp;
@@ -125,7 +129,9 @@ static int compute_effective_progs(struct cgroup *cgrp,
125 continue; 129 continue;
126 130
127 progs->items[cnt].prog = pl->prog; 131 progs->items[cnt].prog = pl->prog;
128 progs->items[cnt].cgroup_storage = pl->storage; 132 for_each_cgroup_storage_type(stype)
133 progs->items[cnt].cgroup_storage[stype] =
134 pl->storage[stype];
129 cnt++; 135 cnt++;
130 } 136 }
131 } while ((p = cgroup_parent(p))); 137 } while ((p = cgroup_parent(p)));
@@ -232,7 +238,9 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
232{ 238{
233 struct list_head *progs = &cgrp->bpf.progs[type]; 239 struct list_head *progs = &cgrp->bpf.progs[type];
234 struct bpf_prog *old_prog = NULL; 240 struct bpf_prog *old_prog = NULL;
235 struct bpf_cgroup_storage *storage, *old_storage = NULL; 241 struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE],
242 *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL};
243 enum bpf_cgroup_storage_type stype;
236 struct bpf_prog_list *pl; 244 struct bpf_prog_list *pl;
237 bool pl_was_allocated; 245 bool pl_was_allocated;
238 int err; 246 int err;
@@ -254,34 +262,44 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
254 if (prog_list_length(progs) >= BPF_CGROUP_MAX_PROGS) 262 if (prog_list_length(progs) >= BPF_CGROUP_MAX_PROGS)
255 return -E2BIG; 263 return -E2BIG;
256 264
257 storage = bpf_cgroup_storage_alloc(prog); 265 for_each_cgroup_storage_type(stype) {
258 if (IS_ERR(storage)) 266 storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
259 return -ENOMEM; 267 if (IS_ERR(storage[stype])) {
268 storage[stype] = NULL;
269 for_each_cgroup_storage_type(stype)
270 bpf_cgroup_storage_free(storage[stype]);
271 return -ENOMEM;
272 }
273 }
260 274
261 if (flags & BPF_F_ALLOW_MULTI) { 275 if (flags & BPF_F_ALLOW_MULTI) {
262 list_for_each_entry(pl, progs, node) { 276 list_for_each_entry(pl, progs, node) {
263 if (pl->prog == prog) { 277 if (pl->prog == prog) {
264 /* disallow attaching the same prog twice */ 278 /* disallow attaching the same prog twice */
265 bpf_cgroup_storage_free(storage); 279 for_each_cgroup_storage_type(stype)
280 bpf_cgroup_storage_free(storage[stype]);
266 return -EINVAL; 281 return -EINVAL;
267 } 282 }
268 } 283 }
269 284
270 pl = kmalloc(sizeof(*pl), GFP_KERNEL); 285 pl = kmalloc(sizeof(*pl), GFP_KERNEL);
271 if (!pl) { 286 if (!pl) {
272 bpf_cgroup_storage_free(storage); 287 for_each_cgroup_storage_type(stype)
288 bpf_cgroup_storage_free(storage[stype]);
273 return -ENOMEM; 289 return -ENOMEM;
274 } 290 }
275 291
276 pl_was_allocated = true; 292 pl_was_allocated = true;
277 pl->prog = prog; 293 pl->prog = prog;
278 pl->storage = storage; 294 for_each_cgroup_storage_type(stype)
295 pl->storage[stype] = storage[stype];
279 list_add_tail(&pl->node, progs); 296 list_add_tail(&pl->node, progs);
280 } else { 297 } else {
281 if (list_empty(progs)) { 298 if (list_empty(progs)) {
282 pl = kmalloc(sizeof(*pl), GFP_KERNEL); 299 pl = kmalloc(sizeof(*pl), GFP_KERNEL);
283 if (!pl) { 300 if (!pl) {
284 bpf_cgroup_storage_free(storage); 301 for_each_cgroup_storage_type(stype)
302 bpf_cgroup_storage_free(storage[stype]);
285 return -ENOMEM; 303 return -ENOMEM;
286 } 304 }
287 pl_was_allocated = true; 305 pl_was_allocated = true;
@@ -289,12 +307,15 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
289 } else { 307 } else {
290 pl = list_first_entry(progs, typeof(*pl), node); 308 pl = list_first_entry(progs, typeof(*pl), node);
291 old_prog = pl->prog; 309 old_prog = pl->prog;
292 old_storage = pl->storage; 310 for_each_cgroup_storage_type(stype) {
293 bpf_cgroup_storage_unlink(old_storage); 311 old_storage[stype] = pl->storage[stype];
312 bpf_cgroup_storage_unlink(old_storage[stype]);
313 }
294 pl_was_allocated = false; 314 pl_was_allocated = false;
295 } 315 }
296 pl->prog = prog; 316 pl->prog = prog;
297 pl->storage = storage; 317 for_each_cgroup_storage_type(stype)
318 pl->storage[stype] = storage[stype];
298 } 319 }
299 320
300 cgrp->bpf.flags[type] = flags; 321 cgrp->bpf.flags[type] = flags;
@@ -304,21 +325,27 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
304 goto cleanup; 325 goto cleanup;
305 326
306 static_branch_inc(&cgroup_bpf_enabled_key); 327 static_branch_inc(&cgroup_bpf_enabled_key);
307 if (old_storage) 328 for_each_cgroup_storage_type(stype) {
308 bpf_cgroup_storage_free(old_storage); 329 if (!old_storage[stype])
330 continue;
331 bpf_cgroup_storage_free(old_storage[stype]);
332 }
309 if (old_prog) { 333 if (old_prog) {
310 bpf_prog_put(old_prog); 334 bpf_prog_put(old_prog);
311 static_branch_dec(&cgroup_bpf_enabled_key); 335 static_branch_dec(&cgroup_bpf_enabled_key);
312 } 336 }
313 bpf_cgroup_storage_link(storage, cgrp, type); 337 for_each_cgroup_storage_type(stype)
338 bpf_cgroup_storage_link(storage[stype], cgrp, type);
314 return 0; 339 return 0;
315 340
316cleanup: 341cleanup:
317 /* and cleanup the prog list */ 342 /* and cleanup the prog list */
318 pl->prog = old_prog; 343 pl->prog = old_prog;
319 bpf_cgroup_storage_free(pl->storage); 344 for_each_cgroup_storage_type(stype) {
320 pl->storage = old_storage; 345 bpf_cgroup_storage_free(pl->storage[stype]);
321 bpf_cgroup_storage_link(old_storage, cgrp, type); 346 pl->storage[stype] = old_storage[stype];
347 bpf_cgroup_storage_link(old_storage[stype], cgrp, type);
348 }
322 if (pl_was_allocated) { 349 if (pl_was_allocated) {
323 list_del(&pl->node); 350 list_del(&pl->node);
324 kfree(pl); 351 kfree(pl);
@@ -339,6 +366,7 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
339 enum bpf_attach_type type, u32 unused_flags) 366 enum bpf_attach_type type, u32 unused_flags)
340{ 367{
341 struct list_head *progs = &cgrp->bpf.progs[type]; 368 struct list_head *progs = &cgrp->bpf.progs[type];
369 enum bpf_cgroup_storage_type stype;
342 u32 flags = cgrp->bpf.flags[type]; 370 u32 flags = cgrp->bpf.flags[type];
343 struct bpf_prog *old_prog = NULL; 371 struct bpf_prog *old_prog = NULL;
344 struct bpf_prog_list *pl; 372 struct bpf_prog_list *pl;
@@ -385,8 +413,10 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
385 413
386 /* now can actually delete it from this cgroup list */ 414 /* now can actually delete it from this cgroup list */
387 list_del(&pl->node); 415 list_del(&pl->node);
388 bpf_cgroup_storage_unlink(pl->storage); 416 for_each_cgroup_storage_type(stype) {
389 bpf_cgroup_storage_free(pl->storage); 417 bpf_cgroup_storage_unlink(pl->storage[stype]);
418 bpf_cgroup_storage_free(pl->storage[stype]);
419 }
390 kfree(pl); 420 kfree(pl);
391 if (list_empty(progs)) 421 if (list_empty(progs))
392 /* last program was detached, reset flags to zero */ 422 /* last program was detached, reset flags to zero */