Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: Factor out cgroup storages operations

Refactor cgroup attach/detach code to abstract away common operations
performed on all types of cgroup storages. This makes high-level logic more
apparent, plus allows to reuse more code across multiple functions.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200325065746.640559-2-andriin@fb.com

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
00c4eddf aa131ed4

+72 -46
+72 -46
kernel/bpf/cgroup.c
··· 28 28 percpu_ref_kill(&cgrp->bpf.refcnt); 29 29 } 30 30 31 + static void bpf_cgroup_storages_free(struct bpf_cgroup_storage *storages[]) 32 + { 33 + enum bpf_cgroup_storage_type stype; 34 + 35 + for_each_cgroup_storage_type(stype) 36 + bpf_cgroup_storage_free(storages[stype]); 37 + } 38 + 39 + static int bpf_cgroup_storages_alloc(struct bpf_cgroup_storage *storages[], 40 + struct bpf_prog *prog) 41 + { 42 + enum bpf_cgroup_storage_type stype; 43 + 44 + for_each_cgroup_storage_type(stype) { 45 + storages[stype] = bpf_cgroup_storage_alloc(prog, stype); 46 + if (IS_ERR(storages[stype])) { 47 + storages[stype] = NULL; 48 + bpf_cgroup_storages_free(storages); 49 + return -ENOMEM; 50 + } 51 + } 52 + 53 + return 0; 54 + } 55 + 56 + static void bpf_cgroup_storages_assign(struct bpf_cgroup_storage *dst[], 57 + struct bpf_cgroup_storage *src[]) 58 + { 59 + enum bpf_cgroup_storage_type stype; 60 + 61 + for_each_cgroup_storage_type(stype) 62 + dst[stype] = src[stype]; 63 + } 64 + 65 + static void bpf_cgroup_storages_link(struct bpf_cgroup_storage *storages[], 66 + struct cgroup* cgrp, 67 + enum bpf_attach_type attach_type) 68 + { 69 + enum bpf_cgroup_storage_type stype; 70 + 71 + for_each_cgroup_storage_type(stype) 72 + bpf_cgroup_storage_link(storages[stype], cgrp, attach_type); 73 + } 74 + 75 + static void bpf_cgroup_storages_unlink(struct bpf_cgroup_storage *storages[]) 76 + { 77 + enum bpf_cgroup_storage_type stype; 78 + 79 + for_each_cgroup_storage_type(stype) 80 + bpf_cgroup_storage_unlink(storages[stype]); 81 + } 82 + 31 83 /** 32 84 * cgroup_bpf_release() - put references of all bpf programs and 33 85 * release all cgroup bpf data ··· 89 37 { 90 38 struct cgroup *p, *cgrp = container_of(work, struct cgroup, 91 39 bpf.release_work); 92 - enum bpf_cgroup_storage_type stype; 93 40 struct bpf_prog_array *old_array; 94 41 unsigned int type; 95 42 ··· 101 50 list_for_each_entry_safe(pl, tmp, progs, node) { 102 51 list_del(&pl->node); 103 52 bpf_prog_put(pl->prog); 104 - for_each_cgroup_storage_type(stype) { 105 - bpf_cgroup_storage_unlink(pl->storage[stype]); 106 - bpf_cgroup_storage_free(pl->storage[stype]); 107 - } 53 + bpf_cgroup_storages_unlink(pl->storage); 54 + bpf_cgroup_storages_free(pl->storage); 108 55 kfree(pl); 109 56 static_branch_dec(&cgroup_bpf_enabled_key); 110 57 } ··· 187 138 enum bpf_attach_type type, 188 139 struct bpf_prog_array **array) 189 140 { 190 - enum bpf_cgroup_storage_type stype; 141 + struct bpf_prog_array_item *item; 191 142 struct bpf_prog_array *progs; 192 143 struct bpf_prog_list *pl; 193 144 struct cgroup *p = cgrp; ··· 215 166 if (!pl->prog) 216 167 continue; 217 168 218 - progs->items[cnt].prog = pl->prog; 219 - for_each_cgroup_storage_type(stype) 220 - progs->items[cnt].cgroup_storage[stype] = 221 - pl->storage[stype]; 169 + item = &progs->items[cnt]; 170 + item->prog = pl->prog; 171 + bpf_cgroup_storages_assign(item->cgroup_storage, 172 + pl->storage); 222 173 cnt++; 223 174 } 224 175 } while ((p = cgroup_parent(p))); ··· 354 305 struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE], 355 306 *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL}; 356 307 struct bpf_prog_list *pl, *replace_pl = NULL; 357 - enum bpf_cgroup_storage_type stype; 358 308 int err; 359 309 360 310 if (((flags & BPF_F_ALLOW_OVERRIDE) && (flags & BPF_F_ALLOW_MULTI)) || ··· 389 341 replace_pl = list_first_entry(progs, typeof(*pl), node); 390 342 } 391 343 392 - for_each_cgroup_storage_type(stype) { 393 - storage[stype] = bpf_cgroup_storage_alloc(prog, stype); 394 - if (IS_ERR(storage[stype])) { 395 - storage[stype] = NULL; 396 - for_each_cgroup_storage_type(stype) 397 - bpf_cgroup_storage_free(storage[stype]); 398 - return -ENOMEM; 399 - } 400 - } 344 + if (bpf_cgroup_storages_alloc(storage, prog)) 345 + return -ENOMEM; 401 346 402 347 if (replace_pl) { 403 348 pl = replace_pl; 404 349 old_prog = pl->prog; 405 - for_each_cgroup_storage_type(stype) { 406 - old_storage[stype] = pl->storage[stype]; 407 - bpf_cgroup_storage_unlink(old_storage[stype]); 408 - } 350 + bpf_cgroup_storages_unlink(pl->storage); 351 + bpf_cgroup_storages_assign(old_storage, pl->storage); 409 352 } else { 410 353 pl = kmalloc(sizeof(*pl), GFP_KERNEL); 411 354 if (!pl) { 412 - for_each_cgroup_storage_type(stype) 413 - bpf_cgroup_storage_free(storage[stype]); 355 + bpf_cgroup_storages_free(storage); 414 356 return -ENOMEM; 415 357 } 416 358 list_add_tail(&pl->node, progs); 417 359 } 418 360 419 361 pl->prog = prog; 420 - for_each_cgroup_storage_type(stype) 421 - pl->storage[stype] = storage[stype]; 422 - 362 + bpf_cgroup_storages_assign(pl->storage, storage); 423 363 cgrp->bpf.flags[type] = saved_flags; 424 364 425 365 err = update_effective_progs(cgrp, type); ··· 415 379 goto cleanup; 416 380 417 381 static_branch_inc(&cgroup_bpf_enabled_key); 418 - for_each_cgroup_storage_type(stype) { 419 - if (!old_storage[stype]) 420 - continue; 421 - bpf_cgroup_storage_free(old_storage[stype]); 422 - } 382 + bpf_cgroup_storages_free(old_storage); 423 383 if (old_prog) { 424 384 bpf_prog_put(old_prog); 425 385 static_branch_dec(&cgroup_bpf_enabled_key); 426 386 } 427 - for_each_cgroup_storage_type(stype) 428 - bpf_cgroup_storage_link(storage[stype], cgrp, type); 387 + bpf_cgroup_storages_link(storage, cgrp, type); 429 388 return 0; 430 389 431 390 cleanup: 432 391 /* and cleanup the prog list */ 433 392 pl->prog = old_prog; 434 - for_each_cgroup_storage_type(stype) { 435 - bpf_cgroup_storage_free(pl->storage[stype]); 436 - pl->storage[stype] = old_storage[stype]; 437 - bpf_cgroup_storage_link(old_storage[stype], cgrp, type); 438 - } 393 + bpf_cgroup_storages_free(pl->storage); 394 + bpf_cgroup_storages_assign(pl->storage, old_storage); 395 + bpf_cgroup_storages_link(pl->storage, cgrp, type); 439 396 if (!replace_pl) { 440 397 list_del(&pl->node); 441 398 kfree(pl); ··· 449 420 enum bpf_attach_type type) 450 421 { 451 422 struct list_head *progs = &cgrp->bpf.progs[type]; 452 - enum bpf_cgroup_storage_type stype; 453 423 u32 flags = cgrp->bpf.flags[type]; 454 424 struct bpf_prog *old_prog = NULL; 455 425 struct bpf_prog_list *pl; ··· 495 467 496 468 /* now can actually delete it from this cgroup list */ 497 469 list_del(&pl->node); 498 - for_each_cgroup_storage_type(stype) { 499 - bpf_cgroup_storage_unlink(pl->storage[stype]); 500 - bpf_cgroup_storage_free(pl->storage[stype]); 501 - } 470 + bpf_cgroup_storages_unlink(pl->storage); 471 + bpf_cgroup_storages_free(pl->storage); 502 472 kfree(pl); 503 473 if (list_empty(progs)) 504 474 /* last program was detached, reset flags to zero */