All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roman Gushchin <guro@fb.com>
To: <netdev@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <kernel-team@fb.com>,
	Roman Gushchin <guro@fb.com>, Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>
Subject: [PATCH v3 bpf-next 04/14] bpf: allocate cgroup storage entries on attaching bpf programs
Date: Fri, 20 Jul 2018 10:45:48 -0700	[thread overview]
Message-ID: <20180720174558.5829-5-guro@fb.com> (raw)
In-Reply-To: <20180720174558.5829-1-guro@fb.com>

If a bpf program is using cgroup local storage, allocate
a bpf_cgroup_storage structure automatically on attaching the program
to a cgroup and save the pointer into the corresponding bpf_prog_list
entry.
Analogically, release the cgroup local storage on detaching
of the bpf program.

Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
 include/linux/bpf-cgroup.h |  1 +
 kernel/bpf/cgroup.c        | 28 ++++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 1b1b4e94d77d..f37347331fdb 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -42,6 +42,7 @@ struct bpf_cgroup_storage {
 struct bpf_prog_list {
 	struct list_head node;
 	struct bpf_prog *prog;
+	struct bpf_cgroup_storage *storage;
 };
 
 struct bpf_prog_array;
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index badabb0b435c..986ff18ef92e 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -34,6 +34,8 @@ void cgroup_bpf_put(struct cgroup *cgrp)
 		list_for_each_entry_safe(pl, tmp, progs, node) {
 			list_del(&pl->node);
 			bpf_prog_put(pl->prog);
+			bpf_cgroup_storage_unlink(pl->storage);
+			bpf_cgroup_storage_free(pl->storage);
 			kfree(pl);
 			static_branch_dec(&cgroup_bpf_enabled_key);
 		}
@@ -188,6 +190,7 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 {
 	struct list_head *progs = &cgrp->bpf.progs[type];
 	struct bpf_prog *old_prog = NULL;
+	struct bpf_cgroup_storage *storage, *old_storage = NULL;
 	struct cgroup_subsys_state *css;
 	struct bpf_prog_list *pl;
 	bool pl_was_allocated;
@@ -210,6 +213,10 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 	if (prog_list_length(progs) >= BPF_CGROUP_MAX_PROGS)
 		return -E2BIG;
 
+	storage = bpf_cgroup_storage_alloc(prog);
+	if (IS_ERR(storage))
+		return -ENOMEM;
+
 	if (flags & BPF_F_ALLOW_MULTI) {
 		list_for_each_entry(pl, progs, node)
 			if (pl->prog == prog)
@@ -217,24 +224,33 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 				return -EINVAL;
 
 		pl = kmalloc(sizeof(*pl), GFP_KERNEL);
-		if (!pl)
+		if (!pl) {
+			bpf_cgroup_storage_free(storage);
 			return -ENOMEM;
+		}
+
 		pl_was_allocated = true;
 		pl->prog = prog;
+		pl->storage = storage;
 		list_add_tail(&pl->node, progs);
 	} else {
 		if (list_empty(progs)) {
 			pl = kmalloc(sizeof(*pl), GFP_KERNEL);
-			if (!pl)
+			if (!pl) {
+				bpf_cgroup_storage_free(storage);
 				return -ENOMEM;
+			}
 			pl_was_allocated = true;
 			list_add_tail(&pl->node, progs);
 		} else {
 			pl = list_first_entry(progs, typeof(*pl), node);
 			old_prog = pl->prog;
+			old_storage = pl->storage;
+			bpf_cgroup_storage_unlink(old_storage);
 			pl_was_allocated = false;
 		}
 		pl->prog = prog;
+		pl->storage = storage;
 	}
 
 	cgrp->bpf.flags[type] = flags;
@@ -257,10 +273,13 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 	}
 
 	static_branch_inc(&cgroup_bpf_enabled_key);
+	if (old_storage)
+		bpf_cgroup_storage_free(old_storage);
 	if (old_prog) {
 		bpf_prog_put(old_prog);
 		static_branch_dec(&cgroup_bpf_enabled_key);
 	}
+	bpf_cgroup_storage_link(storage, cgrp, type);
 	return 0;
 
 cleanup:
@@ -276,6 +295,9 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 
 	/* and cleanup the prog list */
 	pl->prog = old_prog;
+	bpf_cgroup_storage_free(pl->storage);
+	pl->storage = old_storage;
+	bpf_cgroup_storage_link(old_storage, cgrp, type);
 	if (pl_was_allocated) {
 		list_del(&pl->node);
 		kfree(pl);
@@ -356,6 +378,8 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 
 	/* now can actually delete it from this cgroup list */
 	list_del(&pl->node);
+	bpf_cgroup_storage_unlink(pl->storage);
+	bpf_cgroup_storage_free(pl->storage);
 	kfree(pl);
 	if (list_empty(progs))
 		/* last program was detached, reset flags to zero */
-- 
2.14.4


  parent reply	other threads:[~2018-07-20 17:46 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-20 17:45 [PATCH v3 bpf-next 00/14] bpf: cgroup local storage Roman Gushchin
2018-07-20 17:45 ` Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 01/14] bpf: add ability to charge bpf maps memory dynamically Roman Gushchin
2018-07-27 18:01   ` Daniel Borkmann
2018-07-20 17:45 ` [PATCH v3 bpf-next 02/14] bpf: introduce cgroup storage maps Roman Gushchin
2018-07-20 17:45   ` Roman Gushchin
2018-07-27  4:11   ` Daniel Borkmann
2018-07-27 17:12     ` Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 03/14] bpf: pass a pointer to a cgroup storage using pcpu variable Roman Gushchin
2018-07-20 17:45 ` Roman Gushchin [this message]
2018-07-27  4:21   ` [PATCH v3 bpf-next 04/14] bpf: allocate cgroup storage entries on attaching bpf programs Daniel Borkmann
2018-07-20 17:45 ` [PATCH v3 bpf-next 05/14] bpf: extend bpf_prog_array to store pointers to the cgroup storage Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 06/14] bpf/verifier: introduce BPF_PTR_TO_MAP_VALUE Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 07/14] bpf: don't allow create maps of cgroup local storages Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 08/14] bpf: introduce the bpf_get_local_storage() helper function Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 09/14] bpf: sync bpf.h to tools/ Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 10/14] bpftool: add support for CGROUP_STORAGE maps Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 11/14] bpf/test_run: support cgroup local storage Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 12/14] selftests/bpf: add verifier cgroup storage tests Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 13/14] selftests/bpf: add a cgroup storage test Roman Gushchin
2018-07-20 17:45 ` [PATCH v3 bpf-next 14/14] samples/bpf: extend test_cgrp2_attach2 test to use cgroup storage Roman Gushchin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180720174558.5829-5-guro@fb.com \
    --to=guro@fb.com \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@fb.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.