diff mbox series

[bpf-next,v4,5/8] libbpf: Add helper macro to clear opts structs

Message ID 20230710201218.19460-6-daniel@iogearbox.net (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series BPF link support for tc BPF programs | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-32 success Logs for veristat
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers warning 5 maintainers not CCed: yhs@fb.com kpsingh@kernel.org song@kernel.org jolsa@kernel.org haoluo@google.com
netdev/build_clang fail Errors and warnings before: 18 this patch: 18
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch warning CHECK: Macro argument 'NAME' may be better as '(NAME)' to avoid precedence issues
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-6 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on s390x with gcc

Commit Message

Daniel Borkmann July 10, 2023, 8:12 p.m. UTC
Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears
an opts structure and reinitializes its .sz member to place the structure
size. I found this very useful when developing selftests, but it is also
generic enough as a macro next to the existing LIBBPF_OPTS() which hides
the .sz initialization, too.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 tools/lib/bpf/libbpf_common.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Andrii Nakryiko July 11, 2023, 4:02 a.m. UTC | #1
On Mon, Jul 10, 2023 at 1:12 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears
> an opts structure and reinitializes its .sz member to place the structure
> size. I found this very useful when developing selftests, but it is also
> generic enough as a macro next to the existing LIBBPF_OPTS() which hides
> the .sz initialization, too.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> ---
>  tools/lib/bpf/libbpf_common.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h
> index 9a7937f339df..eb180023aa97 100644
> --- a/tools/lib/bpf/libbpf_common.h
> +++ b/tools/lib/bpf/libbpf_common.h
> @@ -70,4 +70,15 @@
>                 };                                                          \
>         })
>
> +/* Helper macro to clear a libbpf options struct
> + *
> + * Small helper macro to reset all fields and to reinitialize the common
> + * structure size member.
> + */
> +#define LIBBPF_OPTS_CLEAR(NAME)                                                    \
> +       do {                                                                \
> +               memset(&NAME, 0, sizeof(NAME));                             \
> +               NAME.sz = sizeof(NAME);                                     \
> +       } while (0)
> +

This is fine, but I think you can go a half-step further and have
something even more universal and useful. Something like this:


#define LIBBPF_OPTS_RESET(NAME, ...)
    do {
        memset(&NAME, 0, sizeof(NAME));
        NAME = (typeof(NAME)) {
            .sz = sizeof(struct TYPE),
            __VA_ARGS__
        };
     while (0);

I actually haven't tried if that typeof() trick works, but I hope it does :)


Then your LIBBPF_OPTS_CLEAR() is just LIBBPF_OPTS_RESET(x). But you
can also re-initialize:

LIBBPF_OPTS_RESET(x, .flags = 123, .prog_fd = 456);

It's more in line with LIBBPF_OPTS() itself in capabilities, except it
works on existing variable.


>  #endif /* __LIBBPF_LIBBPF_COMMON_H */
> --
> 2.34.1
>
Daniel Borkmann July 11, 2023, 9:42 a.m. UTC | #2
On 7/11/23 6:02 AM, Andrii Nakryiko wrote:
> On Mon, Jul 10, 2023 at 1:12 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>>
>> Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears
>> an opts structure and reinitializes its .sz member to place the structure
>> size. I found this very useful when developing selftests, but it is also
>> generic enough as a macro next to the existing LIBBPF_OPTS() which hides
>> the .sz initialization, too.
>>
>> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>> ---
>>   tools/lib/bpf/libbpf_common.h | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>
>> diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h
>> index 9a7937f339df..eb180023aa97 100644
>> --- a/tools/lib/bpf/libbpf_common.h
>> +++ b/tools/lib/bpf/libbpf_common.h
>> @@ -70,4 +70,15 @@
>>                  };                                                          \
>>          })
>>
>> +/* Helper macro to clear a libbpf options struct
>> + *
>> + * Small helper macro to reset all fields and to reinitialize the common
>> + * structure size member.
>> + */
>> +#define LIBBPF_OPTS_CLEAR(NAME)                                                    \
>> +       do {                                                                \
>> +               memset(&NAME, 0, sizeof(NAME));                             \
>> +               NAME.sz = sizeof(NAME);                                     \
>> +       } while (0)
>> +
> 
> This is fine, but I think you can go a half-step further and have
> something even more universal and useful. Something like this:
> 
> 
> #define LIBBPF_OPTS_RESET(NAME, ...)
>      do {
>          memset(&NAME, 0, sizeof(NAME));
>          NAME = (typeof(NAME)) {
>              .sz = sizeof(struct TYPE),
>              __VA_ARGS__
>          };
>       while (0);
> 
> I actually haven't tried if that typeof() trick works, but I hope it does :)

It does, I've used this in BPF code for Cilium, too. ;)

> Then your LIBBPF_OPTS_CLEAR() is just LIBBPF_OPTS_RESET(x). But you
> can also re-initialize:
> 
> LIBBPF_OPTS_RESET(x, .flags = 123, .prog_fd = 456);
> 
> It's more in line with LIBBPF_OPTS() itself in capabilities, except it
> works on existing variable.

Agree, changed into ...

/* Helper macro to clear and optionally reinitialize libbpf options struct
  *
  * Small helper macro to reset all fields and to reinitialize the common
  * structure size member. Values provided by users in struct initializer-
  * syntax as varargs can be provided as well to reinitialize options struct
  * specific members.
  */
#define LIBBPF_OPTS_RESET(NAME, ...)                                        \
         do {                                                                \
                 memset(&NAME, 0, sizeof(NAME));                             \
                 NAME = (typeof(NAME)) {                                     \
                         .sz = sizeof(NAME),                                 \
                         __VA_ARGS__                                         \
                 };                                                          \
         } while (0)

... and updated all the test cases.

Thanks,
Daniel
diff mbox series

Patch

diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h
index 9a7937f339df..eb180023aa97 100644
--- a/tools/lib/bpf/libbpf_common.h
+++ b/tools/lib/bpf/libbpf_common.h
@@ -70,4 +70,15 @@ 
 		};							    \
 	})
 
+/* Helper macro to clear a libbpf options struct
+ *
+ * Small helper macro to reset all fields and to reinitialize the common
+ * structure size member.
+ */
+#define LIBBPF_OPTS_CLEAR(NAME)						    \
+	do {								    \
+		memset(&NAME, 0, sizeof(NAME));				    \
+		NAME.sz = sizeof(NAME);					    \
+	} while (0)
+
 #endif /* __LIBBPF_LIBBPF_COMMON_H */