From: Yonghong Song <yhs@fb.com>
To: Eelco Chaudron <echaudro@redhat.com>, <bpf@vger.kernel.org>
Cc: <netdev@vger.kernel.org>, <ast@kernel.org>,
<daniel@iogearbox.net>, <kafai@fb.com>, <songliubraving@fb.com>,
<andriin@fb.com>, <toke@redhat.com>
Subject: Re: fentry/fexit attach to EXT type XDP program does not work
Date: Mon, 8 Jun 2020 09:58:46 -0700 [thread overview]
Message-ID: <42b0c8d3-e855-7531-b01c-a05414360aff@fb.com> (raw)
In-Reply-To: <159162546868.10791.12432342618156330247.stgit@ebuild>
On 6/8/20 7:11 AM, Eelco Chaudron wrote:
> I'm trying for a while to do a fentry/fexit trace an EXT program
> attached to an XDP program. To make it easier to explain I've
> created a test case (see patch below) to show the issue.
>
> Without the changes to test_xdp_bpf2bpf.c I'll get the following error:
>
> libbpf: -- BEGIN DUMP LOG ---
> libbpf:
> arg#0 type is not a struct
> Unrecognized arg#0 type PTR
> ; int BPF_PROG(trace_on_entry, struct xdp_buff *xdp)
> 0: (79) r6 = *(u64 *)(r1 +0)
> invalid bpf_context access off=0 size=8
> processed 1 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
>
> libbpf: -- END LOG --
> libbpf: failed to load program 'fentry/FUNC'
> libbpf: failed to load object 'test_xdp_bpf2bpf'
> libbpf: failed to load BPF skeleton 'test_xdp_bpf2bpf': -4007
> test_xdp_fentry_ext:FAIL:__load ftrace skeleton failed
> #91 xdp_fentry_ext:FAIL
> Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED
>
> With the change I get the following (but I do feel this change
> should not be needed):
>
> libbpf: -- BEGIN DUMP LOG ---
> libbpf:
> Unrecognized arg#0 type PTR
> ; int trace_on_entry(struct xdp_buff *xdp)
> 0: (bf) r6 = r1
> ; void *data = (void *)(long)xdp->data;
> 1: (79) r1 = *(u64 *)(r6 +0)
> invalid bpf_context access off=0 size=8
> processed 2 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
>
> libbpf: -- END LOG --
> libbpf: failed to load program 'fentry/FUNC'
> libbpf: failed to load object 'test_xdp_bpf2bpf'
> libbpf: failed to load BPF skeleton 'test_xdp_bpf2bpf': -4007
> test_xdp_fentry_ext:FAIL:__load ftrace skeleton failed
> #91 xdp_fentry_ext:FAIL
> Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED
>
> Any idea what could be the case here? The same fentry/fexit attach
> code works fine in the xdp_bpf2bpf.c tests case.
>
>
> Cheers,
>
>
> Eelco
> ---
> .../selftests/bpf/prog_tests/xdp_fentry_ext.c | 95 ++++++++++++++++++++
> 1 file changed, 95 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_fentry_ext.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_fentry_ext.c b/tools/testing/selftests/bpf/prog_tests/xdp_fentry_ext.c
> new file mode 100644
> index 000000000000..68cd83fad632
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_fentry_ext.c
> @@ -0,0 +1,95 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <test_progs.h>
> +#include <network_helpers.h>
> +
> +#include "test_xdp_ext.skel.h"
> +#include "test_xdp_bpf2bpf.skel.h"
> +#include "xdp_dummy.skel.h"
> +
> +void test_xdp_fentry_ext(void)
> +{
> + /* Using the skeleton framework does not work, as it does not like
> + * like the prog_replace() function to be noinline
> + */
> +
> + __u32 duration = 0, retval, size;
> + const char *file = "./test_xdp_ext.o";
> + const char *ext_file = "./xdp_dummy.o";
> + struct bpf_program *prog;
> + struct bpf_program *ext_prog;
> + struct bpf_object *xdp_obj, *ext_obj = NULL;
> + struct test_xdp_bpf2bpf *ftrace_skel = NULL;
> + int err, xdp_fd, ext_fd;
> + char buf[128];
> +
> + err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &xdp_obj, &xdp_fd);
> + if (CHECK_FAIL(err))
> + return;
> +
> + /* Load the EXT program to attach to replace existing function */
> + ext_obj = bpf_object__open_file(ext_file, NULL);
> + if (CHECK(IS_ERR_OR_NULL(ext_obj), "obj_open",
> + "failed to open %s: %ld\n",
> + ext_file, PTR_ERR(ext_obj)))
> + goto out;
> +
> + ext_prog = bpf_object__find_program_by_title(ext_obj, "xdp_dummy");
> + if (CHECK(!ext_prog, "find_prog", "xdp_dummy_prog not found\n"))
> + goto out;
> +
> + err = bpf_program__set_attach_target(ext_prog, xdp_fd, "prog_replace");
> + if (CHECK(err, "set_attach", "err %d, errno %d\n", err, errno))
> + goto out;
> +
> + bpf_program__set_type(ext_prog, BPF_PROG_TYPE_EXT);
> +
> + err = bpf_object__load(ext_obj);
> + if (CHECK(err, "obj_load", "err %d\n", err))
> + goto out;
> +
> + bpf_program__attach_trace(ext_prog);
> +
> + ext_fd = bpf_program__fd(ext_prog);
> +
> + /* Now try to attach an fentry trace to the EXT program above */
> +
> + ftrace_skel = test_xdp_bpf2bpf__open();
> + if (CHECK(!ftrace_skel, "__open", "ftrace skeleton failed\n"))
> + goto out;
I think this is not supported now. That is, you cannot attach a fentry trace
to the EXT program. The current implementation for fentry program simply
trying to find and match the signature of freplace program which by default
is a pointer to void.
It is doable in that in kernel we could recognize to-be-attached program is
a freplace and further trace down to find the real signature. The related
kernel function is btf_get_prog_ctx_type(). You can try to implement by
yourself
or I can have a patch for this once bpf-next opens.
> +
> + prog = ftrace_skel->progs.trace_on_entry;
> + bpf_program__set_expected_attach_type(prog, BPF_TRACE_FENTRY);
> + bpf_program__set_attach_target(prog, ext_fd, "xdp_dummy_prog");
> +
> + prog = ftrace_skel->progs.trace_on_exit;
> + bpf_program__set_expected_attach_type(prog, BPF_TRACE_FEXIT);
> + bpf_program__set_attach_target(prog, ext_fd, "xdp_dummy_prog");
> +
> + err = test_xdp_bpf2bpf__load(ftrace_skel);
> + if (CHECK(err, "__load", "ftrace skeleton failed\n"))
> + goto out;
> +
> + err = test_xdp_bpf2bpf__attach(ftrace_skel);
> + if (CHECK(err, "ftrace_attach", "ftrace attach failed: %d\n", err))
> + goto out;
> +
> +
> + /* Execute the xdp program by sending a dummy packet */
> + err = bpf_prog_test_run(xdp_fd, 1, &pkt_v4, sizeof(pkt_v4),
> + buf, &size, &retval, &duration);
> +
> + if (CHECK(err || retval != XDP_PASS , "packet",
> + "err %d, errno %d, retval %d %c= %d\n",
> + err, errno, retval, retval != XDP_PASS ? '!' : '=', XDP_PASS))
> + goto out;
> +
> +out:
> + bpf_object__close(xdp_obj);
> + if (ext_obj)
> + bpf_object__close(ext_obj);
> + if (ftrace_skel)
> + test_xdp_bpf2bpf__destroy(ftrace_skel);
> +
> +}
> +
> diff --git a/tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c b/tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c
> index a038e827f850..41b2a103c7ca 100644
> --- a/tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c
> +++ b/tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c
> @@ -42,7 +42,8 @@ struct {
>
> __u64 test_result_fentry = 0;
> SEC("fentry/FUNC")
> -int BPF_PROG(trace_on_entry, struct xdp_buff *xdp)
> +//int BPF_PROG(trace_on_entry, struct xdp_buff *xdp)
> +int trace_on_entry(struct xdp_buff *xdp)
> {
> struct meta meta;
> void *data_end = (void *)(long)xdp->data_end;
> @@ -61,7 +62,8 @@ int BPF_PROG(trace_on_entry, struct xdp_buff *xdp)
>
> __u64 test_result_fexit = 0;
> SEC("fexit/FUNC")
> -int BPF_PROG(trace_on_exit, struct xdp_buff *xdp, int ret)
> +//int BPF_PROG(trace_on_exit, struct xdp_buff *xdp, int ret)
> +int trace_on_exit(struct xdp_buff *xdp, int ret)
> {
> test_result_fexit = ret;
> return 0;
> diff --git a/tools/testing/selftests/bpf/progs/test_xdp_ext.c b/tools/testing/selftests/bpf/progs/test_xdp_ext.c
> new file mode 100644
> index 000000000000..37bd16c95b36
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/test_xdp_ext.c
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
> +
> +__u64 xdp_ext_called = 0;
> +
> +__attribute__ ((noinline))
> +int prog_replace(struct xdp_md *ctx) {
> + volatile int ret = XDP_ABORTED;
> +
> + return ret;
> +}
> +
> +SEC("xdp_ext_call")
> +int xdp_ext_call_func(struct xdp_md *ctx)
> +{
> +
> + return prog_replace(ctx);
> +}
> +
> +char _license[] SEC("license") = "GPL";
>
next prev parent reply other threads:[~2020-06-08 16:59 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-08 14:11 fentry/fexit attach to EXT type XDP program does not work Eelco Chaudron
2020-06-08 16:58 ` Yonghong Song [this message]
2020-06-09 8:52 ` Eelco Chaudron
2020-07-26 12:24 ` Jiri Olsa
2020-07-27 7:59 ` Eelco Chaudron
2020-07-27 14:53 ` Jiri Olsa
2020-07-29 6:23 ` Eelco Chaudron
2020-07-29 8:09 ` Jiri Olsa
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=42b0c8d3-e855-7531-b01c-a05414360aff@fb.com \
--to=yhs@fb.com \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=echaudro@redhat.com \
--cc=kafai@fb.com \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=toke@redhat.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.