-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Support libbpf v1 compliant section names #228
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Donald Hunter <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the approach is OK, with some comments below. Also, the documentation needs to be updated to match, in particular the protocol description in protocol.org; and we should probably solicit comments from others implementing the protocol (Cc @dave-tucker)
echo "PRODUCTION:=${PRODUCTION}" >>$CONFIG | ||
echo "DYNAMIC_LIBXDP:=${DYNAMIC_LIBXDP}" >>$CONFIG | ||
echo "MAX_DISPATCHER_ACTIONS:=${MAX_DISPATCHER_ACTIONS}" >>$CONFIG | ||
echo "BPF_TARGET:=${BPF_TARGET}" >>$CONFIG | ||
echo "LIBBPF_V1_COMPLIANT:=${LIBBPF_V1_COMPLIANT}" >>$CONFIG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it makes sense to have a configure knob for this? See below, we can just set the define unconditionally...
#else | ||
#define XDP_METADATA_SECTION XDP_METADATA_SECTION_ORIG | ||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the dispatcher we should really just define both sections until we can retire the old one; so no need for this ifdef, just define both and duplicate the line adding dispatcher_version in the dispatcher code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicating the dispatcher_version line results in:
xdp-dispatcher.c:201:52: error: section does not match previous declaration [-Werror,-Wsection]
__uint(dispatcher_version, XDP_DISPATCHER_VERSION) SEC(XDP_METADATA_SECTION_NEW)
So it would also require a different variable name to avoid the collision. That's another protocol change that I guess libxdp can handle, but has consequences for other implementations as well.
But I was thinking that the libxdp and dispatcher version on a system would match and would either be old or new, so only need the dispatcher_version declared in 1 section. It's legacy and new programs that we'd need to be able to read old or new metadata from. Or am I missing something?
@@ -5,7 +5,15 @@ | |||
|
|||
#include <linux/types.h> | |||
|
|||
#define XDP_METADATA_SECTION "xdp_metadata" | |||
#define XDP_METADATA_SECTION_ORIG "xdp_metadata" | |||
#define XDP_METADATA_SECTION_NEW ".data.xdp_metadata" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use _DATA
as suffix instead of _NEW
?
#define XDP_RUN_CONFIG_SECTION_ORIG "xdp_run_config" | ||
#define XDP_RUN_CONFIG_SECTION_NEW ".data.xdp_run_config" | ||
|
||
#if defined(USE_LIBBPF_V1_SECTION_NAMES) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This define will be a user-facing API (as this header is meant to be included by user programs), so I guess we should document it somewhere. I'm not too fond of the name, but I can't think of anything better off the top of my head...
@@ -38,6 +38,10 @@ ifeq ($(SYSTEM_LIBBPF),y) | |||
DEFINES += -DLIBBPF_DYNAMIC | |||
endif | |||
|
|||
ifeq ($(LIBBPF_V1_COMPLIANT),y) | |||
DEFINES += -DUSE_LIBBPF_V1_SECTION_NAMES | |||
endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just set this unconditionally; this will only affect the BPF programs built as part of xdp-tools, and the assumption here is that those will only be used with the same version of the library (which will then understand the new section names straight away)...
@@ -5,7 +5,15 @@ | |||
|
|||
#include <linux/types.h> | |||
|
|||
#define XDP_METADATA_SECTION "xdp_metadata" | |||
#define XDP_METADATA_SECTION_ORIG "xdp_metadata" | |||
#define XDP_METADATA_SECTION_NEW ".data.xdp_metadata" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely this doesn't need to be renamed since this is not a program section name - therefore libbpf should ignore it.
Otherwise this is a libbpf bug IMHO.
On Fri, 23 Sept 2022 at 16:39, Dave Tucker ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In headers/xdp/prog_dispatcher.h
<#228 (comment)>:
> @@ -5,7 +5,15 @@
#include <linux/types.h>
-#define XDP_METADATA_SECTION "xdp_metadata"
+#define XDP_METADATA_SECTION_ORIG "xdp_metadata"
+#define XDP_METADATA_SECTION_NEW ".data.xdp_metadata"
Surely this doesn't need to be renamed since this is not a program section
name - therefore libbpf should ignore it.
Otherwise this is a libbpf bug IMHO.
Agree that this is a tiresome, long-winded and disruptive solution to
resolving a warning emitted by libbpf.
Toke has tried getting libbpf to fix this before:
I tried getting a patch into libbpf to demote the warning, but that got
shot down.
Perhaps we should try again.
|
My intention (in Aya) is to iterate over the symbol table to discover programs (since one section can contain multiple progs, and it's the symbol name - C function name - that uniquely identifies a program anyway)... from there it's possible to get the section, and use the section name as a hint to what the program type should be. Adopting that approach in libbpf would solve the problem since it wouldn't be assuming that any ELF section that matches a magic prefix like "xdp", "cgroup" etc... is a loadable program - which I guess is what is generating the warning here. That, or perhaps any sections that aren't SHF_EXECINSTR should be ignored (if they aren't anyway) which would prevent this from triggering warnings. See below:
|
Looking at the discussion from back then, it seems Andrii would be OK with allowing section names that don't start with a dot, as long as they are marked as "non-allocatable": https://lore.kernel.org/r/CAEf4BzY9WxjBX65sa=8SJh4XGLGfHgxGKciRGiSUMJAxbQWWYg@mail.gmail.com Sadly I have no idea how to convince the compiler to mark the sections as such, which is why the discussion stalled back then. If any of you have any ideas, maybe taking this route is better (i.e., getting rid of the warning in libbpf)? |
I have done some initial exploration and it can be done either by ld with a linker script, or later with objcopy. The libxdp build currently does this:
It is also possible to do:
|
Right, since there's no linking step for BPF object files, I guess it'll have to be objcopy. That still leaves I'm actually thinking we could just drop the section entirely? We don't really use the section itself for anything, we just need the DATASEC info to be written into the BTF. And I think that will survive even if we remove the section from the ELF file afterwards? May be worth trying out; we could do that for both the XSK programs and the dispatcher. A bit harder for user programs using the Not sure if there's some macro magic that will make the compiler emit BTF without actually putting anything into the section itself in the object file? |
Since I've been looking at LLVM lately I figured that perhaps there would be some
Thinking about this... do we actually need a #define __uint(name, val) int (*name)[val]
struct {
__uint(priority, 10);
__uint(XDP_PASS, 1);
__uint(XDP_DROP, 1);
} __attribute__((btf_decl_tag("xdp_metadata"))) xdp_metadata; for which the BTF is:
(ok I lied, there is a .bss ELF section, but that's a problem for another day 🤣 ) libxdp can the lookup the DECL_TAG of |
Hmm, yeah, this does seem kinda reasonable, however...
...this we may have to deal with. Without putting stuff in a separate section, this variable will show up in the .bss section, which will at least be something that's user-visible when people use the skeleton generation to consume those vars. So in that sense it would be better if we could avoid having the actual variables in the data sections an just generate the BTF. This actually goes for the Also, what version constraints (on libbpf and/or compiler) do we impose if we start using |
Marking as
Clang 15, libbpf 0.6.0 - there are no kernel constraints as libbpf will sanitize BTF before uploading to the kernel. |
Yeah, would be cool if we could just add some BTF information without the variable...
Hmm, clang 15 is not even a month old... may be a bit premature to incur a hard dependency on that? :) |
I was wrong, It's in clang 14 too: https://releases.llvm.org/14.0.0/tools/clang/docs/AttributeReference.html#btf-decl-tag |
Submitting this as an RFC to get feedback. If the approach looks sane then I will add tests and docs then resubmit.
Signed-off-by: Donald Hunter [email protected]