From: Emil Tsalapatis <emil@etsalapatis.com>
To: bpf@vger.kernel.org
Cc: andrii@kernel.org, ast@kernel.org, daniel@iogearbox.net,
eddyz87@gmail.com, martin.lau@kernel.org, memxor@gmail.com,
song@kernel.org, yonghong.song@linux.dev,
Emil Tsalapatis <emil@etsalapatis.com>
Subject: [PATCH bpf-next v4 2/2] bpf: Add deep call stack selftests
Date: Mon, 9 Mar 2026 16:44:30 -0400 [thread overview]
Message-ID: <20260309204430.201219-3-emil@etsalapatis.com> (raw)
In-Reply-To: <20260309204430.201219-1-emil@etsalapatis.com>
Add tests that demonstrate the verifier support for deep call stacks
while still enforcing maximum stack size limits.
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
.../bpf/prog_tests/test_global_funcs.c | 2 +
.../bpf/progs/test_global_func_deep_stack.c | 83 +++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/test_global_func_deep_stack.c
diff --git a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
index e905cbaf6b3d..500446808908 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
@@ -18,6 +18,7 @@
#include "test_global_func15.skel.h"
#include "test_global_func16.skel.h"
#include "test_global_func17.skel.h"
+#include "test_global_func_deep_stack.skel.h"
#include "test_global_func_ctx_args.skel.h"
#include "bpf/libbpf_internal.h"
@@ -155,6 +156,7 @@ void test_test_global_funcs(void)
RUN_TESTS(test_global_func15);
RUN_TESTS(test_global_func16);
RUN_TESTS(test_global_func17);
+ RUN_TESTS(test_global_func_deep_stack);
RUN_TESTS(test_global_func_ctx_args);
if (test__start_subtest("ctx_arg_rewrite"))
diff --git a/tools/testing/selftests/bpf/progs/test_global_func_deep_stack.c b/tools/testing/selftests/bpf/progs/test_global_func_deep_stack.c
new file mode 100644
index 000000000000..733c3334b7b1
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_global_func_deep_stack.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2026 Meta Platforms, Inc and affiliates. */
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+/*
+ * Macro tricks to tersely define for long non-recursive call chains. Add
+ * computation to the functions prevent tail recursion from reducing the
+ * stack size to 0.
+ */
+
+#define CAT(a, b) a ## b
+#define XCAT(a, b) CAT(a, b)
+
+#define F_0 \
+__attribute__((noinline)) \
+int f0(unsigned long a) { volatile long b = a + 16; if (a == 0) return 0; return b; }
+
+#define FN(n, prev) \
+__attribute__((noinline)) \
+int XCAT(f, n)(unsigned long a) { volatile long b = XCAT(f, prev)(a - 1); if (!b) return 0; return b + 1; }
+
+/* Call chain 33 levels deep. */
+#define F_1 F_0 FN(1, 0)
+#define F_2 F_1 FN(2, 1)
+#define F_3 F_2 FN(3, 2)
+#define F_4 F_3 FN(4, 3)
+#define F_5 F_4 FN(5, 4)
+#define F_6 F_5 FN(6, 5)
+#define F_7 F_6 FN(7, 6)
+#define F_8 F_7 FN(8, 7)
+#define F_9 F_8 FN(9, 8)
+#define F_10 F_9 FN(10, 9)
+#define F_11 F_10 FN(11, 10)
+#define F_12 F_11 FN(12, 11)
+#define F_13 F_12 FN(13, 12)
+#define F_14 F_13 FN(14, 13)
+#define F_15 F_14 FN(15, 14)
+#define F_16 F_15 FN(16, 15)
+#define F_17 F_16 FN(17, 16)
+#define F_18 F_17 FN(18, 17)
+#define F_19 F_18 FN(19, 18)
+#define F_20 F_19 FN(20, 19)
+#define F_21 F_20 FN(21, 20)
+#define F_22 F_21 FN(22, 21)
+#define F_23 F_22 FN(23, 22)
+#define F_24 F_23 FN(24, 23)
+#define F_25 F_24 FN(25, 24)
+#define F_26 F_25 FN(26, 25)
+#define F_27 F_26 FN(27, 26)
+#define F_28 F_27 FN(28, 27)
+#define F_29 F_28 FN(29, 28)
+#define F_30 F_29 FN(30, 29)
+#define F_31 F_30 FN(31, 30)
+#define F_32 F_31 FN(32, 31)
+
+#define CAT2(a, b) a ## b
+#define XCAT2(a, b) CAT2(a, b)
+
+#define F(n) XCAT2(F_, n)
+
+F(32)
+
+/* Ensure that even 32 levels deep, the function verifies. */
+SEC("syscall")
+__success
+int global_func_deep_stack_success(struct __sk_buff *skb)
+{
+ return f31(55);
+}
+
+/*
+ * Check we actually honor stack limits (33 * 16 = 528 > 512 = MAX_STACK_DEPTH).
+ * The stack depth is 16 because the verifier calls round_up_stack_depth() on
+ * the size.
+ */
+SEC("syscall")
+__failure __msg("combined stack size of 34 calls")
+int global_func_deep_stack_fail(struct __sk_buff *skb)
+{
+ return f32(123);
+}
--
2.49.0
next prev parent reply other threads:[~2026-03-09 20:44 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 20:44 [PATCH bpf-next v4 0/2] bpf: Relax 8 frame limitation for global subprogs Emil Tsalapatis
2026-03-09 20:44 ` [PATCH bpf-next v4 1/2] bpf: Only enforce 8 frame call stack limit for all-static stacks Emil Tsalapatis
2026-03-09 21:23 ` bot+bpf-ci
2026-03-09 21:37 ` Eduard Zingerman
2026-03-10 19:07 ` Alexei Starovoitov
2026-03-10 14:04 ` Mykyta Yatsenko
2026-03-09 20:44 ` Emil Tsalapatis [this message]
2026-03-11 2:59 ` [PATCH bpf-next v4 2/2] bpf: Add deep call stack selftests Yonghong Song
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=20260309204430.201219-3-emil@etsalapatis.com \
--to=emil@etsalapatis.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=martin.lau@kernel.org \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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.