Message ID | 20220712232556.248863-1-james.hilliard1@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | [v3] bpf/scripts: Generate GCC compatible helpers | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
bpf/vmtest-bpf-next-VM_Test-3 | success | Logs for Kernel LATEST on z15 with gcc |
bpf/vmtest-bpf-next-VM_Test-2 | success | Logs for Kernel LATEST on ubuntu-latest with llvm-15 |
bpf/vmtest-bpf-next-PR | success | PR summary |
bpf/vmtest-bpf-next-VM_Test-1 | success | Logs for Kernel LATEST on ubuntu-latest with gcc |
On Tue, Jul 12, 2022 at 4:26 PM James Hilliard <james.hilliard1@gmail.com> wrote: > > The current bpf_helper_defs.h helpers are llvm specific and don't work > correctly with gcc. > > GCC appears to required kernel helper funcs to have the following > attribute set: __attribute__((kernel_helper(NUM))) > > Generate gcc compatible headers based on the format in bpf-helpers.h. > > This generates GCC/Clang compatible helpers, for example: > /* Helper macro for GCC/Clang compatibility */ > #define NOARG > #if __GNUC__ && !__clang__ > #define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \ > ret_type ret_star name(__VA_ARGS__) __attribute__((kernel_helper(num))); > #else > #define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \ > static ret_type ret_star(*name)(__VA_ARGS__) = (void *) num; > #endif > > BPF_HELPER_DEF(1, *, void, bpf_map_lookup_elem, void *map, const void *key) > > BPF_HELPER_DEF(2, NOARG, long, bpf_map_update_elem, void *map, const void *key, const void *value, __u64 flags) > > See: > https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.1.0/gcc/config/bpf/bpf-helpers.h#L24-L27 > > This fixes the following build error: > error: indirect call in function, which are not supported by eBPF > > Signed-off-by: James Hilliard <james.hilliard1@gmail.com> > --- > Changes v2 -> v3: > - use a conditional helper macro > Changes v1 -> v2: > - more details in commit log > --- > scripts/bpf_doc.py | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py > index a0ec321469bd..45f51ff1318c 100755 > --- a/scripts/bpf_doc.py > +++ b/scripts/bpf_doc.py > @@ -717,6 +717,16 @@ class PrinterHelpers(Printer): > header = '''\ > /* This is auto-generated file. See bpf_doc.py for details. */ > > +/* Helper macro for GCC/Clang compatibility */ > +#define NOARG > +#if __GNUC__ && !__clang__ > +#define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \\ > +ret_type ret_star name(__VA_ARGS__) __attribute__((kernel_helper(num))); > +#else > +#define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \\ > +static ret_type ret_star(*name)(__VA_ARGS__) = (void *) num; > +#endif Nack for the reasons stated earlier.
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index a0ec321469bd..45f51ff1318c 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -717,6 +717,16 @@ class PrinterHelpers(Printer): header = '''\ /* This is auto-generated file. See bpf_doc.py for details. */ +/* Helper macro for GCC/Clang compatibility */ +#define NOARG +#if __GNUC__ && !__clang__ +#define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \\ +ret_type ret_star name(__VA_ARGS__) __attribute__((kernel_helper(num))); +#else +#define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \\ +static ret_type ret_star(*name)(__VA_ARGS__) = (void *) num; +#endif + /* Forward declarations of BPF structs */''' print(header) @@ -746,6 +756,11 @@ class PrinterHelpers(Printer): return self.seen_helpers.add(proto['name']) + if proto['ret_star']: + ret_star = proto['ret_star'] + else: + ret_star = 'NOARG' + print('/*') print(" * %s" % proto['name']) print(" *") @@ -762,8 +777,8 @@ class PrinterHelpers(Printer): print(' *{}{}'.format(' \t' if line else '', line)) print(' */') - print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), - proto['ret_star'], proto['name']), end='') + print('BPF_HELPER_DEF(%d, %s, %s, %s, ' % (len(self.seen_helpers), + ret_star, self.map_type(proto['ret_type']), proto['name']), end='') comma = '' for i, a in enumerate(proto['args']): t = a['type'] @@ -781,7 +796,7 @@ class PrinterHelpers(Printer): comma = ', ' print(one_arg, end='') - print(') = (void *) %d;' % len(self.seen_helpers)) + print(')') print('') ###############################################################################
The current bpf_helper_defs.h helpers are llvm specific and don't work correctly with gcc. GCC appears to required kernel helper funcs to have the following attribute set: __attribute__((kernel_helper(NUM))) Generate gcc compatible headers based on the format in bpf-helpers.h. This generates GCC/Clang compatible helpers, for example: /* Helper macro for GCC/Clang compatibility */ #define NOARG #if __GNUC__ && !__clang__ #define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \ ret_type ret_star name(__VA_ARGS__) __attribute__((kernel_helper(num))); #else #define BPF_HELPER_DEF(num, ret_star, ret_type, name, ...) \ static ret_type ret_star(*name)(__VA_ARGS__) = (void *) num; #endif BPF_HELPER_DEF(1, *, void, bpf_map_lookup_elem, void *map, const void *key) BPF_HELPER_DEF(2, NOARG, long, bpf_map_update_elem, void *map, const void *key, const void *value, __u64 flags) See: https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.1.0/gcc/config/bpf/bpf-helpers.h#L24-L27 This fixes the following build error: error: indirect call in function, which are not supported by eBPF Signed-off-by: James Hilliard <james.hilliard1@gmail.com> --- Changes v2 -> v3: - use a conditional helper macro Changes v1 -> v2: - more details in commit log --- scripts/bpf_doc.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)