From: Eduard Zingerman <eddyz87@gmail.com>
To: andrea terzolo <andreaterzolo3@gmail.com>, bpf@vger.kernel.org
Subject: Re: [QUESTION] Check bpf_loop support on kernels < 5.13
Date: Fri, 03 Jan 2025 12:31:13 -0800 [thread overview]
Message-ID: <d58e28b03ecee04dba5c16c588330741c255cc0c.camel@gmail.com> (raw)
In-Reply-To: <CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com>
On Fri, 2025-01-03 at 12:03 +0100, andrea terzolo wrote:
> Hi folks! I would like to check with you if the verifier failure I'm
> facing is expected. The verifier rejects the following eBPF program on
> kernel 5.10.232.
>
> ```
> static long loop_fn(uint32_t index, void *ctx) {
> bpf_printk("handle_exit\n");
> return 0;
> }
>
> SEC("tp/raw_syscalls/sys_enter")
> int test(void *ctx) {
> if (bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
> bpf_printk("loop\n");
> bpf_loop(12, loop_fn, NULL, 0);
> } else {
> bpf_printk("skip loop\n");
> }
> return 0;
> }
> ```
>
> With this error:
>
> ```
> libbpf: prog 'test': BPF program load failed: Invalid argument
> libbpf: prog 'test': -- BEGIN PROG LOAD LOG --
> number of funcs in func_info doesn't match number of subprogs
> processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0
> peak_states 0 mark_read 0
> -- END PROG LOAD LOG --
> libbpf: prog 'test': failed to load: -22
> ```
>
> This sounds like a valid use case. I would like to use bpf_loop if
> supported by the running kernel otherwise I can fall back to a simple
> loop. This issue goes away on kernel 5.13 with the introduction of
> PTR_TO_FUNC [0]. Is there a way I can use CO-RE features to avoid this
> issue? I would expect the verifier to prune the dead code inside the
> `if` but the error seems to be triggered before the control flow
> analysis.
>
> [0]: https://github.com/torvalds/linux/commit/69c087ba6225b574afb6e505b72cb75242a3d844
bpf_loop was introduced by commit [1] and released as a part of 5.17.
The error you see is indeed caused by the lack of PTR_TO_FUNC register
type in an old kernel. In your program the call to bpf_loop would look
like below in the assembly:
...
r2 = loop_fn ;; here function pointer is taken
...
call bpf_loop
Before main verification pass verifier.c:add_subprog_and_kfunc()
discovers subprogram entries by looking at function calls and function
pointer assignments and compares it to function information provided
via bpf_attr->func_info. The kernel that does not know about
PTR_TO_FUNC would not find the loop_fn entry, hence the error message
about mismatch.
Additionally, verifier.c:check_cfg() looks for parts of the program
that can't be reached by jump and call instructions. For this purpose
pointers to functions are treated as function calls. The kernel that
does not know about PTR_TO_FUNC it would seem that loop_fn is unreachable,
this would cause another error message.
Even if you add a dummy call to loop_fn verifier would most likely
reject the program at 'r2 = loop_fn'.
The approach libbpf uses to detect running kernel features is based on
programs accept/reject status [2]. E.g. your program could be simplified to:
static int loop_fn(int i, void *c) { return 0; }
SEC("tp/raw_syscalls/sys_enter")
int test(void *ctx) {
bpf_loop(1, loop_fn, NULL, 0);
return 0;
}
And checked if load is successful.
[1] e6f2dd0f8067 ("bpf: Add bpf_loop helper")
[2] see <kernel>/tools/lib/bpf/features.c
next prev parent reply other threads:[~2025-01-03 20:31 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-03 11:03 [QUESTION] Check bpf_loop support on kernels < 5.13 andrea terzolo
2025-01-03 20:31 ` Eduard Zingerman [this message]
2025-01-06 22:32 ` andrea terzolo
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=d58e28b03ecee04dba5c16c588330741c255cc0c.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=andreaterzolo3@gmail.com \
--cc=bpf@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox