Skip to content

Commit 00c4edd

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
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 <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent aa131ed commit 00c4edd

File tree

1 file changed

+72
-46
lines changed

1 file changed

+72
-46
lines changed

kernel/bpf/cgroup.c

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,58 @@ void cgroup_bpf_offline(struct cgroup *cgrp)
2828
percpu_ref_kill(&cgrp->bpf.refcnt);
2929
}
3030

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+
3183
/**
3284
* cgroup_bpf_release() - put references of all bpf programs and
3385
* release all cgroup bpf data
@@ -37,7 +89,6 @@ static void cgroup_bpf_release(struct work_struct *work)
3789
{
3890
struct cgroup *p, *cgrp = container_of(work, struct cgroup,
3991
bpf.release_work);
40-
enum bpf_cgroup_storage_type stype;
4192
struct bpf_prog_array *old_array;
4293
unsigned int type;
4394

@@ -50,10 +101,8 @@ static void cgroup_bpf_release(struct work_struct *work)
50101
list_for_each_entry_safe(pl, tmp, progs, node) {
51102
list_del(&pl->node);
52103
bpf_prog_put(pl->prog);
53-
for_each_cgroup_storage_type(stype) {
54-
bpf_cgroup_storage_unlink(pl->storage[stype]);
55-
bpf_cgroup_storage_free(pl->storage[stype]);
56-
}
104+
bpf_cgroup_storages_unlink(pl->storage);
105+
bpf_cgroup_storages_free(pl->storage);
57106
kfree(pl);
58107
static_branch_dec(&cgroup_bpf_enabled_key);
59108
}
@@ -138,7 +187,7 @@ static int compute_effective_progs(struct cgroup *cgrp,
138187
enum bpf_attach_type type,
139188
struct bpf_prog_array **array)
140189
{
141-
enum bpf_cgroup_storage_type stype;
190+
struct bpf_prog_array_item *item;
142191
struct bpf_prog_array *progs;
143192
struct bpf_prog_list *pl;
144193
struct cgroup *p = cgrp;
@@ -166,10 +215,10 @@ static int compute_effective_progs(struct cgroup *cgrp,
166215
if (!pl->prog)
167216
continue;
168217

169-
progs->items[cnt].prog = pl->prog;
170-
for_each_cgroup_storage_type(stype)
171-
progs->items[cnt].cgroup_storage[stype] =
172-
pl->storage[stype];
218+
item = &progs->items[cnt];
219+
item->prog = pl->prog;
220+
bpf_cgroup_storages_assign(item->cgroup_storage,
221+
pl->storage);
173222
cnt++;
174223
}
175224
} while ((p = cgroup_parent(p)));
@@ -305,7 +354,6 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
305354
struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE],
306355
*old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL};
307356
struct bpf_prog_list *pl, *replace_pl = NULL;
308-
enum bpf_cgroup_storage_type stype;
309357
int err;
310358

311359
if (((flags & BPF_F_ALLOW_OVERRIDE) && (flags & BPF_F_ALLOW_MULTI)) ||
@@ -341,65 +389,46 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
341389
replace_pl = list_first_entry(progs, typeof(*pl), node);
342390
}
343391

344-
for_each_cgroup_storage_type(stype) {
345-
storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
346-
if (IS_ERR(storage[stype])) {
347-
storage[stype] = NULL;
348-
for_each_cgroup_storage_type(stype)
349-
bpf_cgroup_storage_free(storage[stype]);
350-
return -ENOMEM;
351-
}
352-
}
392+
if (bpf_cgroup_storages_alloc(storage, prog))
393+
return -ENOMEM;
353394

354395
if (replace_pl) {
355396
pl = replace_pl;
356397
old_prog = pl->prog;
357-
for_each_cgroup_storage_type(stype) {
358-
old_storage[stype] = pl->storage[stype];
359-
bpf_cgroup_storage_unlink(old_storage[stype]);
360-
}
398+
bpf_cgroup_storages_unlink(pl->storage);
399+
bpf_cgroup_storages_assign(old_storage, pl->storage);
361400
} else {
362401
pl = kmalloc(sizeof(*pl), GFP_KERNEL);
363402
if (!pl) {
364-
for_each_cgroup_storage_type(stype)
365-
bpf_cgroup_storage_free(storage[stype]);
403+
bpf_cgroup_storages_free(storage);
366404
return -ENOMEM;
367405
}
368406
list_add_tail(&pl->node, progs);
369407
}
370408

371409
pl->prog = prog;
372-
for_each_cgroup_storage_type(stype)
373-
pl->storage[stype] = storage[stype];
374-
410+
bpf_cgroup_storages_assign(pl->storage, storage);
375411
cgrp->bpf.flags[type] = saved_flags;
376412

377413
err = update_effective_progs(cgrp, type);
378414
if (err)
379415
goto cleanup;
380416

381417
static_branch_inc(&cgroup_bpf_enabled_key);
382-
for_each_cgroup_storage_type(stype) {
383-
if (!old_storage[stype])
384-
continue;
385-
bpf_cgroup_storage_free(old_storage[stype]);
386-
}
418+
bpf_cgroup_storages_free(old_storage);
387419
if (old_prog) {
388420
bpf_prog_put(old_prog);
389421
static_branch_dec(&cgroup_bpf_enabled_key);
390422
}
391-
for_each_cgroup_storage_type(stype)
392-
bpf_cgroup_storage_link(storage[stype], cgrp, type);
423+
bpf_cgroup_storages_link(storage, cgrp, type);
393424
return 0;
394425

395426
cleanup:
396427
/* and cleanup the prog list */
397428
pl->prog = old_prog;
398-
for_each_cgroup_storage_type(stype) {
399-
bpf_cgroup_storage_free(pl->storage[stype]);
400-
pl->storage[stype] = old_storage[stype];
401-
bpf_cgroup_storage_link(old_storage[stype], cgrp, type);
402-
}
429+
bpf_cgroup_storages_free(pl->storage);
430+
bpf_cgroup_storages_assign(pl->storage, old_storage);
431+
bpf_cgroup_storages_link(pl->storage, cgrp, type);
403432
if (!replace_pl) {
404433
list_del(&pl->node);
405434
kfree(pl);
@@ -420,7 +449,6 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
420449
enum bpf_attach_type type)
421450
{
422451
struct list_head *progs = &cgrp->bpf.progs[type];
423-
enum bpf_cgroup_storage_type stype;
424452
u32 flags = cgrp->bpf.flags[type];
425453
struct bpf_prog *old_prog = NULL;
426454
struct bpf_prog_list *pl;
@@ -467,10 +495,8 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
467495

468496
/* now can actually delete it from this cgroup list */
469497
list_del(&pl->node);
470-
for_each_cgroup_storage_type(stype) {
471-
bpf_cgroup_storage_unlink(pl->storage[stype]);
472-
bpf_cgroup_storage_free(pl->storage[stype]);
473-
}
498+
bpf_cgroup_storages_unlink(pl->storage);
499+
bpf_cgroup_storages_free(pl->storage);
474500
kfree(pl);
475501
if (list_empty(progs))
476502
/* last program was detached, reset flags to zero */

0 commit comments

Comments
 (0)