From: Hao Luo <haoluo@google.com>
To: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
Yonghong Song <yhs@fb.com>, KP Singh <kpsingh@kernel.org>,
Shakeel Butt <shakeelb@google.com>,
Joe Burton <jevburton.kernel@gmail.com>,
Stanislav Fomichev <sdf@google.com>,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
Hao Luo <haoluo@google.com>
Subject: [PATCH RFC bpf-next v2 3/5] bpf: cgroup_view iter
Date: Tue, 1 Feb 2022 12:55:32 -0800 [thread overview]
Message-ID: <20220201205534.1962784-4-haoluo@google.com> (raw)
In-Reply-To: <20220201205534.1962784-1-haoluo@google.com>
Introduce a new type of iter prog: 'cgroup_view'. It prints out cgroup's
state.
Cgroup_view is supposed to be used together with directory tagging. When
cgroup_view is pinned in a directory, it tags that directory as
KERNFS_REP, i.e. a replicate of the cgroup hierarchy. Whenever a
subdirectory is created, if there is a child cgroup of the same name
exists, the subdirectory inherits the pinned cgroup_view object from
its parent and holds a reference of the corresponding kernfs node.
The cgroup_view prog takes a pointer to the cgroup and can use family
of seq_print helpers to print out cgroup state. A typical use case of
cgroup_view is to extend the cgroupfs interface.
Signed-off-by: Hao Luo <haoluo@google.com>
---
include/linux/bpf.h | 2 +
kernel/bpf/Makefile | 2 +-
kernel/bpf/bpf_iter.c | 11 ++++
kernel/bpf/cgroup_view_iter.c | 114 ++++++++++++++++++++++++++++++++++
4 files changed, 128 insertions(+), 1 deletion(-)
create mode 100644 kernel/bpf/cgroup_view_iter.c
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 6eb0b180d33b..494927b2b3c2 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1610,6 +1610,7 @@ typedef const struct bpf_func_proto *
enum bpf_iter_feature {
BPF_ITER_RESCHED = BIT(0),
+ BPF_ITER_INHERIT = BIT(1),
};
#define BPF_ITER_CTX_ARG_MAX 2
@@ -1647,6 +1648,7 @@ bpf_iter_get_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog);
int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_prog *prog);
int bpf_iter_new_fd(struct bpf_link *link);
bool bpf_link_is_iter(struct bpf_link *link);
+bool bpf_link_support_inherit(struct bpf_link *link);
struct bpf_prog *bpf_iter_get_info(struct bpf_iter_meta *meta, bool in_stop);
int bpf_iter_run_prog(struct bpf_prog *prog, void *ctx);
void bpf_iter_map_show_fdinfo(const struct bpf_iter_aux_info *aux,
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index c1a9be6a4b9f..d9d2b8541ba7 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -8,7 +8,7 @@ CFLAGS_core.o += $(call cc-disable-warning, override-init) $(cflags-nogcse-yy)
obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o bpf_iter.o map_iter.o task_iter.o prog_iter.o
obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o
-obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o
+obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o cgroup_view_iter.o
obj-$(CONFIG_BPF_SYSCALL) += bpf_local_storage.o bpf_task_storage.o
obj-${CONFIG_BPF_LSM} += bpf_inode_storage.o
obj-$(CONFIG_BPF_SYSCALL) += disasm.o
diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c
index 110029ede71e..ff5577a5f73a 100644
--- a/kernel/bpf/bpf_iter.c
+++ b/kernel/bpf/bpf_iter.c
@@ -496,6 +496,17 @@ bool bpf_link_is_iter(struct bpf_link *link)
return link->ops == &bpf_iter_link_lops;
}
+bool bpf_link_support_inherit(struct bpf_link *link)
+{
+ struct bpf_iter_link *iter_link;
+
+ if (!bpf_link_is_iter(link))
+ return false;
+
+ iter_link = container_of(link, struct bpf_iter_link, link);
+ return iter_link->tinfo->reg_info->feature & BPF_ITER_INHERIT;
+}
+
int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
struct bpf_prog *prog)
{
diff --git a/kernel/bpf/cgroup_view_iter.c b/kernel/bpf/cgroup_view_iter.c
new file mode 100644
index 000000000000..a44d115235c4
--- /dev/null
+++ b/kernel/bpf/cgroup_view_iter.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2022 Google */
+#include <linux/bpf.h>
+#include <linux/fs.h>
+#include <linux/filter.h>
+#include <linux/kernel.h>
+#include <linux/btf_ids.h>
+#include <linux/cgroup.h>
+#include <linux/kernfs.h>
+#include "inode.h"
+
+static void *cgroup_view_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct bpf_dir_tag *tag;
+ struct kernfs_node *kn;
+ struct cgroup *cgroup;
+ struct inode *dir;
+
+ /* Only one session is supported. */
+ if (*pos > 0)
+ return NULL;
+
+ dir = d_inode(seq->file->f_path.dentry->d_parent);
+ tag = dir->i_private;
+ if (!tag)
+ return NULL;
+
+ kn = tag->private;
+
+ rcu_read_lock();
+ cgroup = rcu_dereference(*(void __rcu __force **)&kn->priv);
+ if (!cgroup || !cgroup_tryget(cgroup))
+ cgroup = NULL;
+ rcu_read_unlock();
+
+ if (!cgroup)
+ return NULL;
+
+ if (*pos == 0)
+ ++*pos;
+ return cgroup;
+}
+
+static void *cgroup_view_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+struct bpf_iter__cgroup_view {
+ __bpf_md_ptr(struct bpf_iter_meta *, meta);
+ __bpf_md_ptr(struct cgroup *, cgroup);
+};
+
+DEFINE_BPF_ITER_FUNC(cgroup_view, struct bpf_iter_meta *meta, struct cgroup *cgroup)
+
+static int cgroup_view_seq_show(struct seq_file *seq, void *v)
+{
+ struct bpf_iter__cgroup_view ctx;
+ struct bpf_iter_meta meta;
+ struct bpf_prog *prog;
+ int ret = 0;
+
+ ctx.meta = &meta;
+ ctx.cgroup = v;
+ meta.seq = seq;
+ prog = bpf_iter_get_info(&meta, false);
+ if (prog)
+ ret = bpf_iter_run_prog(prog, &ctx);
+
+ return ret;
+}
+
+static void cgroup_view_seq_stop(struct seq_file *seq, void *v)
+{
+ if (v)
+ cgroup_put(v);
+}
+
+static const struct seq_operations cgroup_view_seq_ops = {
+ .start = cgroup_view_seq_start,
+ .next = cgroup_view_seq_next,
+ .stop = cgroup_view_seq_stop,
+ .show = cgroup_view_seq_show,
+};
+
+BTF_ID_LIST(btf_cgroup_id)
+BTF_ID(struct, cgroup)
+
+static const struct bpf_iter_seq_info cgroup_view_seq_info = {
+ .seq_ops = &cgroup_view_seq_ops,
+ .init_seq_private = NULL,
+ .fini_seq_private = NULL,
+ .seq_priv_size = 0,
+};
+
+static struct bpf_iter_reg cgroup_view_reg_info = {
+ .target = "cgroup_view",
+ .feature = BPF_ITER_INHERIT,
+ .ctx_arg_info_size = 1,
+ .ctx_arg_info = {
+ { offsetof(struct bpf_iter__cgroup_view, cgroup),
+ PTR_TO_BTF_ID },
+ },
+ .seq_info = &cgroup_view_seq_info,
+};
+
+static int __init cgroup_view_init(void)
+{
+ cgroup_view_reg_info.ctx_arg_info[0].btf_id = *btf_cgroup_id;
+ return bpf_iter_reg_target(&cgroup_view_reg_info);
+}
+
+late_initcall(cgroup_view_init);
--
2.35.0.rc2.247.g8bbb082509-goog
next prev parent reply other threads:[~2022-02-01 20:55 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-01 20:55 [PATCH RFC bpf-next v2 0/5] Extend cgroup interface with bpf Hao Luo
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 1/5] bpf: Bpffs directory tag Hao Luo
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag Hao Luo
2022-02-01 20:55 ` Hao Luo [this message]
2022-02-02 1:17 ` [PATCH RFC bpf-next v2 3/5] bpf: cgroup_view iter kernel test robot
2022-02-02 3:39 ` kernel test robot
2022-02-02 3:39 ` kernel test robot
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 4/5] bpf: Pin cgroup_view Hao Luo
2022-02-02 4:20 ` kernel test robot
2022-02-02 5:11 ` kernel test robot
2022-02-02 5:11 ` kernel test robot
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 5/5] selftests/bpf: test for pinning for cgroup_view link Hao Luo
2022-02-03 18:04 ` Alexei Starovoitov
2022-02-03 22:46 ` Hao Luo
2022-02-04 3:33 ` Alexei Starovoitov
2022-02-04 18:26 ` Hao Luo
2022-02-06 4:29 ` Alexei Starovoitov
2022-02-08 20:07 ` Hao Luo
2022-02-08 21:20 ` Alexei Starovoitov
2022-02-08 21:34 ` Hao Luo
2022-02-14 18:29 ` Hao Luo
2022-02-14 19:24 ` Alexei Starovoitov
2022-02-14 20:23 ` Hao Luo
2022-02-14 20:27 ` Alexei Starovoitov
2022-02-14 20:39 ` Hao Luo
-- strict thread matches above, loose matches on Subject: below --
2022-02-02 9:15 [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag kernel test robot
2022-02-02 9:32 ` Dan Carpenter
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=20220201205534.1962784-4-haoluo@google.com \
--to=haoluo@google.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=jevburton.kernel@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sdf@google.com \
--cc=shakeelb@google.com \
--cc=songliubraving@fb.com \
--cc=yhs@fb.com \
/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.