[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <0017945a4297a296c87a65d62cc4bd9948f6c20c.1763457705.git.zhuhui@kylinos.cn>
Date: Wed, 19 Nov 2025 09:34:07 +0800
From: Hui Zhu <hui.zhu@...ux.dev>
To: Andrew Morton <akpm@...ux-foundation.org>,
Johannes Weiner <hannes@...xchg.org>,
Michal Hocko <mhocko@...nel.org>,
Roman Gushchin <roman.gushchin@...ux.dev>,
Shakeel Butt <shakeel.butt@...ux.dev>,
Muchun Song <muchun.song@...ux.dev>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <martin.lau@...ux.dev>,
Eduard Zingerman <eddyz87@...il.com>,
Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>,
John Fastabend <john.fastabend@...il.com>,
KP Singh <kpsingh@...nel.org>,
Stanislav Fomichev <sdf@...ichev.me>,
Hao Luo <haoluo@...gle.com>,
Jiri Olsa <jolsa@...nel.org>,
Shuah Khan <shuah@...nel.org>,
Peter Zijlstra <peterz@...radead.org>,
Miguel Ojeda <ojeda@...nel.org>,
Nathan Chancellor <nathan@...nel.org>,
Kees Cook <kees@...nel.org>,
Tejun Heo <tj@...nel.org>,
Jeff Xu <jeffxu@...omium.org>,
mkoutny@...e.com,
Jan Hendrik Farr <kernel@...rr.cc>,
Christian Brauner <brauner@...nel.org>,
Randy Dunlap <rdunlap@...radead.org>,
Brian Gerst <brgerst@...il.com>,
Masahiro Yamada <masahiroy@...nel.org>,
linux-kernel@...r.kernel.org,
linux-mm@...ck.org,
cgroups@...r.kernel.org,
bpf@...r.kernel.org,
linux-kselftest@...r.kernel.org
Cc: Hui Zhu <zhuhui@...inos.cn>,
Geliang Tang <geliang@...nel.org>
Subject: [RFC PATCH 2/3] selftests/bpf: add memcg eBPF struct ops test
From: Hui Zhu <zhuhui@...inos.cn>
Add comprehensive selftest suite for memory controller eBPF
support. The tests validate the core functionality of the
memcg_ops struct ops implementation.
Test coverage includes:
1. test_memcg_ops_load: Validates that the eBPF object file
can be successfully loaded by libbpf.
2. test_memcg_ops_attach: Tests attaching the memcg_ops struct
ops to the kernel, verifying the basic attachment mechanism
works correctly.
3. test_memcg_ops_double_attach: Validates that only one
memcg_ops instance can be attached at a time. Attempts to
attach a second program should fail, ensuring the
single-handler design constraint is enforced.
The test suite includes:
- prog_tests/memcg_ops.c: Test entry point with individual
test functions using standard BPF test framework helpers
like ASSERT_OK_PTR and ASSERT_ERR_PTR
- progs/memcg_ops.bpf.c: Simple eBPF program implementing
the struct ops interface
Uses standard test_progs framework macros for consistent error
reporting and handling. All tests properly clean up resources
in error paths.
Signed-off-by: Geliang Tang <geliang@...nel.org>
Signed-off-by: Hui Zhu <zhuhui@...inos.cn>
---
MAINTAINERS | 1 +
.../selftests/bpf/prog_tests/memcg_ops.c | 117 ++++++++++++++++++
tools/testing/selftests/bpf/progs/memcg_ops.c | 20 +++
3 files changed, 138 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/memcg_ops.c
create mode 100644 tools/testing/selftests/bpf/progs/memcg_ops.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 498d01c9a48e..dc3aa53d2346 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6356,6 +6356,7 @@ F: mm/memcontrol_bpf.h
F: mm/page_counter.c
F: mm/swap_cgroup.c
F: samples/cgroup/*
+F: tools/testing/selftests/bpf/*/memcg_ops.c
F: tools/testing/selftests/cgroup/memcg_protection.m
F: tools/testing/selftests/cgroup/test_hugetlb_memcg.c
F: tools/testing/selftests/cgroup/test_kmem.c
diff --git a/tools/testing/selftests/bpf/prog_tests/memcg_ops.c b/tools/testing/selftests/bpf/prog_tests/memcg_ops.c
new file mode 100644
index 000000000000..3f989bcfb8c4
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/memcg_ops.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Memory controller eBPF struct ops test
+ */
+
+#include <test_progs.h>
+#include <bpf/btf.h>
+
+void test_memcg_ops_load(void)
+{
+ struct bpf_object *obj;
+ int err;
+
+ obj = bpf_object__open_file("memcg_ops.bpf.o", NULL);
+ err = libbpf_get_error(obj);
+ if (CHECK_FAIL(err)) {
+ obj = NULL;
+ goto out;
+ }
+
+ err = bpf_object__load(obj);
+ if (CHECK_FAIL(err))
+ goto out;
+
+out:
+ if (obj)
+ bpf_object__close(obj);
+}
+
+void test_memcg_ops_attach(void)
+{
+ struct bpf_object *obj;
+ struct bpf_map *map;
+ struct bpf_link *link = NULL;
+ int err;
+
+ obj = bpf_object__open_file("memcg_ops.bpf.o", NULL);
+ err = libbpf_get_error(obj);
+ if (CHECK_FAIL(err)) {
+ obj = NULL;
+ goto out;
+ }
+
+ err = bpf_object__load(obj);
+ if (CHECK_FAIL(err))
+ goto out;
+
+ map = bpf_object__find_map_by_name(obj, "mcg_ops");
+ if (!ASSERT_OK_PTR(map, "bpf_object__find_map_by_name"))
+ goto out;
+
+ link = bpf_map__attach_struct_ops(map);
+ if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops"))
+ goto out;
+
+out:
+ if (link)
+ bpf_link__destroy(link);
+ if (obj)
+ bpf_object__close(obj);
+}
+
+void test_memcg_ops_double_attach(void)
+{
+ struct bpf_object *obj, *obj2;
+ struct bpf_map *map, *map2;
+ struct bpf_link *link = NULL, *link2 = NULL;
+ int err;
+
+ obj = bpf_object__open_file("memcg_ops.bpf.o", NULL);
+ err = libbpf_get_error(obj);
+ if (CHECK_FAIL(err)) {
+ obj = NULL;
+ goto out;
+ }
+
+ err = bpf_object__load(obj);
+ if (CHECK_FAIL(err))
+ goto out;
+
+ map = bpf_object__find_map_by_name(obj, "mcg_ops");
+ if (!ASSERT_OK_PTR(map, "bpf_object__find_map_by_name"))
+ goto out;
+
+ link = bpf_map__attach_struct_ops(map);
+ if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops"))
+ goto out;
+
+ obj2 = bpf_object__open_file("memcg_ops.bpf.o", NULL);
+ err = libbpf_get_error(obj2);
+ if (CHECK_FAIL(err)) {
+ obj2 = NULL;
+ goto out;
+ }
+
+ err = bpf_object__load(obj2);
+ if (CHECK_FAIL(err))
+ goto out;
+
+ map2 = bpf_object__find_map_by_name(obj2, "mcg_ops");
+ if (!ASSERT_OK_PTR(map, "bpf_object__find_map_by_name"))
+ goto out;
+
+ link2 = bpf_map__attach_struct_ops(map2);
+ if (!ASSERT_ERR_PTR(link2, "bpf_map__attach_struct_ops")) {
+ bpf_link__destroy(link2);
+ goto out;
+ }
+
+out:
+ if (link)
+ bpf_link__destroy(link);
+ if (obj)
+ bpf_object__close(obj);
+ if (obj2)
+ bpf_object__close(obj2);
+}
diff --git a/tools/testing/selftests/bpf/progs/memcg_ops.c b/tools/testing/selftests/bpf/progs/memcg_ops.c
new file mode 100644
index 000000000000..a21fbe859fd3
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/memcg_ops.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "vmlinux.h"
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+SEC("struct_ops/try_charge_memcg")
+int BPF_PROG(test_try_charge_memcg,
+ struct try_charge_memcg *tcm)
+{
+ return 0;
+}
+
+SEC(".struct_ops")
+struct memcg_ops mcg_ops = {
+ .try_charge_memcg = (void *)test_try_charge_memcg,
+};
--
2.43.0
Powered by blists - more mailing lists