All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers
@ 2022-09-27  4:29 Andrii Nakryiko
  2022-09-27  4:29 ` [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test Andrii Nakryiko
  2022-09-27 11:43 ` [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Toke Høiland-Jørgensen
  0 siblings, 2 replies; 4+ messages in thread
From: Andrii Nakryiko @ 2022-09-27  4:29 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Toke Høiland-Jørgensen

Drop the requirement for system-wide kernel UAPI headers to provide full
struct btf_enum64 definition. This is an unexpected requirement that
slipped in libbpf 1.0 and put unnecessary pressure ([0]) on users to have
a bleeding-edge kernel UAPI header from unreleased Linux 6.0.

To achieve this, we forward declare struct btf_enum64. But that's not
enough as there is btf_enum64_value() helper that expects to know the
layout of struct btf_enum64. So we get a bit creative with
reinterpreting memory layout as array of __u32 and accesing lo32/hi32
fields as array elements. Alternative way would be to have a local
pointer variable for anonymous struct with exactly the same layout as
struct btf_enum64, but that gets us into C++ compiler errors complaining
about invalid type casts. So play it safe, if ugly.

  [0] Closes: https://github.com/libbpf/libbpf/issues/562

Reported-by: Toke Høiland-Jørgensen <toke@toke.dk>
Fixes: d90ec262b35b ("libbpf: Add enum64 support for btf_dump")
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 tools/lib/bpf/btf.h | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index ae543144ee30..8e6880d91c84 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -486,6 +486,8 @@ static inline struct btf_enum *btf_enum(const struct btf_type *t)
 	return (struct btf_enum *)(t + 1);
 }
 
+struct btf_enum64;
+
 static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
 {
 	return (struct btf_enum64 *)(t + 1);
@@ -493,7 +495,28 @@ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
 
 static inline __u64 btf_enum64_value(const struct btf_enum64 *e)
 {
-	return ((__u64)e->val_hi32 << 32) | e->val_lo32;
+	/* struct btf_enum64 is introduced in Linux 6.0, which is very
+	 * bleeding-edge. Here we are avoiding relying on struct btf_enum64
+	 * definition coming from kernel UAPI headers to support wider range
+	 * of system-wide kernel headers.
+	 *
+	 * Given this header can be also included from C++ applications, that
+	 * further restricts C tricks we can use (like using compatible
+	 * anonymous struct). So just treat struct btf_enum64 as
+	 * a three-element array of u32 and access second (lo32) and third
+	 * (hi32) elements directly.
+	 *
+	 * For reference, here is a struct btf_enum64 definition:
+	 *
+	 * const struct btf_enum64 {
+	 *	__u32	name_off;
+	 *	__u32	val_lo32;
+	 *	__u32	val_hi32;
+	 * };
+	 */
+	const __u32 *e64 = (const __u32 *)e;
+
+	return ((__u64)e64[2] << 32) | e64[1];
 }
 
 static inline struct btf_member *btf_members(const struct btf_type *t)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test
  2022-09-27  4:29 [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Andrii Nakryiko
@ 2022-09-27  4:29 ` Andrii Nakryiko
  2022-09-27 13:28   ` Daniel Borkmann
  2022-09-27 11:43 ` [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Toke Høiland-Jørgensen
  1 sibling, 1 reply; 4+ messages in thread
From: Andrii Nakryiko @ 2022-09-27  4:29 UTC (permalink / raw)
  To: bpf, ast, daniel; +Cc: andrii, kernel-team, Toke Høiland-Jørgensen

Setting -std=c++11 seems to catch more potential C++-only problems. Also
BPF skeleton isn't rely compilable with any older standard due to the
use of nullptr.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 tools/testing/selftests/bpf/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index e6cf21fad69f..d52069c70e49 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -570,7 +570,7 @@ $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
 # Make sure we are able to include and link libbpf against c++.
 $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ)
 	$(call msg,CXX,,$@)
-	$(Q)$(CXX) $(CFLAGS) $(filter %.a %.o %.cpp,$^) $(LDLIBS) -o $@
+	$(Q)$(CXX) $(CFLAGS) -std=c++11 $(filter %.a %.o %.cpp,$^) $(LDLIBS) -o $@
 
 # Benchmark runner
 $(OUTPUT)/bench_%.o: benchs/bench_%.c bench.h $(BPFOBJ)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers
  2022-09-27  4:29 [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Andrii Nakryiko
  2022-09-27  4:29 ` [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test Andrii Nakryiko
@ 2022-09-27 11:43 ` Toke Høiland-Jørgensen
  1 sibling, 0 replies; 4+ messages in thread
From: Toke Høiland-Jørgensen @ 2022-09-27 11:43 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, ast, daniel; +Cc: andrii, kernel-team

Andrii Nakryiko <andrii@kernel.org> writes:

> Drop the requirement for system-wide kernel UAPI headers to provide full
> struct btf_enum64 definition. This is an unexpected requirement that
> slipped in libbpf 1.0 and put unnecessary pressure ([0]) on users to have
> a bleeding-edge kernel UAPI header from unreleased Linux 6.0.
>
> To achieve this, we forward declare struct btf_enum64. But that's not
> enough as there is btf_enum64_value() helper that expects to know the
> layout of struct btf_enum64. So we get a bit creative with
> reinterpreting memory layout as array of __u32 and accesing lo32/hi32
> fields as array elements. Alternative way would be to have a local
> pointer variable for anonymous struct with exactly the same layout as
> struct btf_enum64, but that gets us into C++ compiler errors complaining
> about invalid type casts. So play it safe, if ugly.
>
>   [0] Closes: https://github.com/libbpf/libbpf/issues/562
>
> Reported-by: Toke Høiland-Jørgensen <toke@toke.dk>
> Fixes: d90ec262b35b ("libbpf: Add enum64 support for btf_dump")
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

This seems like a reasonable (and only a bit ugly) workaround; thanks!

Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test
  2022-09-27  4:29 ` [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test Andrii Nakryiko
@ 2022-09-27 13:28   ` Daniel Borkmann
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Borkmann @ 2022-09-27 13:28 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, ast; +Cc: kernel-team, Toke Høiland-Jørgensen

On 9/27/22 6:29 AM, Andrii Nakryiko wrote:
> Setting -std=c++11 seems to catch more potential C++-only problems. Also
> BPF skeleton isn't rely compilable with any older standard due to the
> use of nullptr.
> 
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> ---
>   tools/testing/selftests/bpf/Makefile | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index e6cf21fad69f..d52069c70e49 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -570,7 +570,7 @@ $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
>   # Make sure we are able to include and link libbpf against c++.
>   $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ)
>   	$(call msg,CXX,,$@)
> -	$(Q)$(CXX) $(CFLAGS) $(filter %.a %.o %.cpp,$^) $(LDLIBS) -o $@
> +	$(Q)$(CXX) $(CFLAGS) -std=c++11 $(filter %.a %.o %.cpp,$^) $(LDLIBS) -o $@
>   
>   # Benchmark runner
>   $(OUTPUT)/bench_%.o: benchs/bench_%.c bench.h $(BPFOBJ)
> 

Seems CI triggers build error (https://github.com/kernel-patches/bpf/actions/runs/3133037577/jobs/5085992832) :

     [...]
     GEN-SKEL [test_progs] pyperf180.skel.h
     GEN-SKEL [test_progs] pyperf600.skel.h
     GEN-SKEL [test_progs-no_alu32] pyperf180.skel.h
     GEN-SKEL [test_progs-no_alu32] pyperf600.skel.h
     BINARY   bench
   In file included from test_cpp.cpp:9:
   /tmp/work/bpf/bpf/tools/testing/selftests/bpf/test_core_extern.skel.h:45:3: error: unknown type name '_Bool'
                   _Bool CONFIG_BOOL;
                   ^
   /tmp/work/bpf/bpf/tools/testing/selftests/bpf/test_core_extern.skel.h:46:3: error: unknown type name '_Bool'
                   _Bool CONFIG_BPF_SYSCALL;
                   ^
   2 errors generated.
   make: *** [Makefile:573: /tmp/work/bpf/bpf/tools/testing/selftests/bpf/test_cpp] Error 1
   make: *** Waiting for unfinished jobs....
   make: Leaving directory '/tmp/work/bpf/bpf/tools/testing/selftests/bpf'
   Error: Process completed with exit code 2.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-09-27 13:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-27  4:29 [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Andrii Nakryiko
2022-09-27  4:29 ` [PATCH bpf-next 2/2] selftests/bpf: enforce C++11 mode for test_cpp test Andrii Nakryiko
2022-09-27 13:28   ` Daniel Borkmann
2022-09-27 11:43 ` [PATCH bpf-next 1/2] libbpf: don't require full struct enum64 in UAPI headers Toke Høiland-Jørgensen

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.