Re: [PATCH net-next 3/8] lib: packing: add pack_fields() and unpack_fields()

Vladimir Oltean
2024-10-19T12:20:26Z

[-- Attachment #1: Type: text/plain, Size: 745 bytes --]

On Fri, Oct 18, 2024 at 02:50:52PM -0700, Jacob Keller wrote:
> Przemek, Vladimir,
>
> What are your thoughts on the next steps here. Do we need to go back to
> the drawing board for how to handle these static checks?
>
> Do we try to reduce the size somewhat, or try to come up with a
> completely different approach to handling this? Do we revert back to
> run-time checks? Investigate some alternative for static checking that
> doesn't have this limitation requiring thousands of lines of macro?
>
> I'd like to figure out what to do next.

Please see the attached patch for an idea on how to reduce the size
of <include/generated/packing-checks.h>, in a way that should be
satisfactory for both ice and sja1105, as well as future users.

[-- Attachment #2: 0001-lib-packing-conditionally-generate-packing-checks-ba.patch --]
[-- Type: text/x-diff, Size: 22715 bytes --]

From f5321d0a6201827127eddce51ccd69639bc133b1 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Sat, 19 Oct 2024 15:11:37 +0300
Subject: [PATCH] lib: packing: conditionally generate packing checks based on
Kconfig options

Przemek Kitszel complained that the size of the
<include/generated/packing-checks.h> file is large (2 MB).

There is divergence between the ice driver needing only checks for
arrays of 20 and 27 fields, and sja1105 driver needing checks for arrays
up to 40 fields.

Since each driver knows which array sizes it needs (it open-codes those
sizes when calling CHECK_PACKED_FIELDS_N()), introduce selectable bool
options in Kconfig to generate those corresponding checks on demand,
rather than generating them all from 1 to 50.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Kbuild | 155 +++++++++++++
drivers/net/ethernet/intel/Kconfig | 2 +
include/linux/packing.h | 4 +
lib/Kconfig | 361 ++++++++++++++++++++++++++++-
lib/gen_packing_checks.c | 166 ++++++++++++-
5 files changed, 685 insertions(+), 3 deletions(-)

diff --git a/Kbuild b/Kbuild
index 35a8b78b72d9..1a4d31b3eb6c 100644
--- a/Kbuild
+++ b/Kbuild
@@ -34,8 +34,161 @@ arch/$(SRCARCH)/kernel/asm-offsets.s: $(timeconst-file) $(bounds-file)
$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE
$(call filechk,offsets,__ASM_OFFSETS_H__)

+ifdef CONFIG_PACKING_CHECK_FIELDS
+
# Generate packing-checks.h

+ifdef CONFIG_PACKING_CHECK_FIELDS_1
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_1
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_2
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_2
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_3
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_3
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_4
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_4
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_5
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_5
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_6
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_6
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_7
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_7
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_8
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_8
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_9
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_9
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_10
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_10
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_11
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_11
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_12
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_12
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_13
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_13
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_14
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_14
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_15
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_15
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_16
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_16
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_17
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_17
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_18
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_18
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_19
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_19
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_20
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_20
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_21
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_21
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_22
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_22
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_23
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_23
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_24
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_24
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_25
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_25
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_26
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_26
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_27
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_27
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_28
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_28
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_29
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_29
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_30
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_30
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_31
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_31
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_32
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_32
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_33
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_33
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_34
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_34
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_35
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_35
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_36
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_36
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_37
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_37
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_38
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_38
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_39
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_39
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_40
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_40
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_41
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_41
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_42
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_42
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_43
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_43
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_44
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_44
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_45
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_45
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_46
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_46
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_47
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_47
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_48
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_48
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_49
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_49
+endif
+ifdef CONFIG_PACKING_CHECK_FIELDS_50
+HOSTCFLAGS_lib/gen_packing_checks.o += -DPACKING_CHECK_FIELDS_50
+endif
+
hostprogs += lib/gen_packing_checks

packing-checks := include/generated/packing-checks.h
@@ -45,6 +198,8 @@ filechk_gen_packing_checks = lib/gen_packing_checks
$(packing-checks): lib/gen_packing_checks FORCE
$(call filechk,gen_packing_checks)

+endif
+
# Check for missing system calls

quiet_cmd_syscalls = CALL $<
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 24ec9a4f1ffa..c4ea8ae65a95 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -293,6 +293,8 @@ config ICE
select LIBIE
select NET_DEVLINK
select PACKING
+ select PACKING_CHECK_FIELDS_20
+ select PACKING_CHECK_FIELDS_27
select PLDMFW
select DPLL
help
diff --git a/include/linux/packing.h b/include/linux/packing.h
index eeb23d90e5e0..31afee8344a5 100644
--- a/include/linux/packing.h
+++ b/include/linux/packing.h
@@ -54,6 +54,8 @@ struct packed_field_m {
sizeof_field(struct_name, struct_field), \
}

+#if IS_ENABLED(CONFIG_PACKING_CHECK_FIELDS)
+
#define CHECK_PACKED_FIELD(field, pbuflen) \
({ typeof(field) __f = (field); typeof(pbuflen) __len = (pbuflen); \
BUILD_BUG_ON(__f.startbit < __f.endbit); \
@@ -67,6 +69,8 @@ struct packed_field_m {

#include <generated/packing-checks.h>

+#endif
+
void pack_fields_s(void *pbuf, size_t pbuflen, const void *ustruct,
const struct packed_field_s *fields, size_t num_fields,
u8 quirks);
diff --git a/lib/Kconfig b/lib/Kconfig
index 50d85f38b569..68b440d622f6 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -40,9 +40,11 @@ config PACKING

When in doubt, say N.

+if PACKING
+
config PACKING_KUNIT_TEST
tristate "KUnit tests for packing library" if !KUNIT_ALL_TESTS
- depends on PACKING && KUNIT
+ depends on KUNIT
default KUNIT_ALL_TESTS
help
This builds KUnit tests for the packing library.
@@ -52,6 +54,363 @@ config PACKING_KUNIT_TEST

When in doubt, say N.

+config PACKING_CHECK_FIELDS
+ bool
+ help
+ This option generates the <include/generated/packing-checks.h> file.
+
+config PACKING_CHECK_FIELDS_1
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 1 element.
+
+config PACKING_CHECK_FIELDS_2
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 2 elements.
+
+config PACKING_CHECK_FIELDS_3
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 3 elements.
+
+config PACKING_CHECK_FIELDS_4
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 4 elements.
+
+config PACKING_CHECK_FIELDS_5
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 5 elements.
+
+config PACKING_CHECK_FIELDS_6
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 6 elements.
+
+config PACKING_CHECK_FIELDS_7
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 7 elements.
+
+config PACKING_CHECK_FIELDS_8
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 8 elements.
+
+config PACKING_CHECK_FIELDS_9
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 9 elements.
+
+config PACKING_CHECK_FIELDS_10
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 10 elements.
+
+config PACKING_CHECK_FIELDS_11
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 11 elements.
+
+config PACKING_CHECK_FIELDS_12
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 12 elements.
+
+config PACKING_CHECK_FIELDS_13
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 13 elements.
+
+config PACKING_CHECK_FIELDS_14
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 14 elements.
+
+config PACKING_CHECK_FIELDS_15
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 15 elements.
+
+config PACKING_CHECK_FIELDS_16
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 16 elements.
+
+config PACKING_CHECK_FIELDS_17
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 17 elements.
+
+config PACKING_CHECK_FIELDS_18
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 18 elements.
+
+config PACKING_CHECK_FIELDS_19
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 19 elements.
+
+config PACKING_CHECK_FIELDS_20
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 20 elements.
+
+config PACKING_CHECK_FIELDS_21
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 21 elements.
+
+config PACKING_CHECK_FIELDS_22
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 22 elements.
+
+config PACKING_CHECK_FIELDS_23
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 23 elements.
+
+config PACKING_CHECK_FIELDS_24
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 24 elements.
+
+config PACKING_CHECK_FIELDS_25
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 25 elements.
+
+config PACKING_CHECK_FIELDS_26
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 26 elements.
+
+config PACKING_CHECK_FIELDS_27
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 27 elements.
+
+config PACKING_CHECK_FIELDS_28
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 28 elements.
+
+config PACKING_CHECK_FIELDS_29
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 29 elements.
+
+config PACKING_CHECK_FIELDS_30
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 30 elements.
+
+config PACKING_CHECK_FIELDS_31
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 31 elements.
+
+config PACKING_CHECK_FIELDS_32
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 32 elements.
+
+config PACKING_CHECK_FIELDS_33
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 33 elements.
+
+config PACKING_CHECK_FIELDS_34
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 34 elements.
+
+config PACKING_CHECK_FIELDS_35
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 35 elements.
+
+config PACKING_CHECK_FIELDS_36
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 36 elements.
+
+config PACKING_CHECK_FIELDS_37
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 37 elements.
+
+config PACKING_CHECK_FIELDS_38
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 38 elements.
+
+config PACKING_CHECK_FIELDS_39
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 39 elements.
+
+config PACKING_CHECK_FIELDS_40
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 40 elements.
+
+config PACKING_CHECK_FIELDS_41
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 41 elements.
+
+config PACKING_CHECK_FIELDS_42
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 42 elements.
+
+config PACKING_CHECK_FIELDS_43
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 43 elements.
+
+config PACKING_CHECK_FIELDS_44
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 44 elements.
+
+config PACKING_CHECK_FIELDS_45
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 45 elements.
+
+config PACKING_CHECK_FIELDS_46
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 46 elements.
+
+config PACKING_CHECK_FIELDS_47
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 47 elements.
+
+config PACKING_CHECK_FIELDS_48
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 48 elements.
+
+config PACKING_CHECK_FIELDS_49
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 49 elements.
+
+config PACKING_CHECK_FIELDS_50
+ bool
+ select PACKING_CHECK_FIELDS
+ help
+ This option generates compile-time checks for struct packed_field
+ arrays of 50 elements.
+
+endif # PACKING
+
config BITREVERSE
tristate

diff --git a/lib/gen_packing_checks.c b/lib/gen_packing_checks.c
index 3213c858c2fe..5ff346a190c0 100644
--- a/lib/gen_packing_checks.c
+++ b/lib/gen_packing_checks.c
@@ -1,25 +1,187 @@
// SPDX-License-Identifier: GPL-2.0
+#include <stdbool.h>
#include <stdio.h>

+static bool generate_checks[51];
+
+static void parse_defines(void)
+{
+#ifdef PACKING_CHECK_FIELDS_1
+ generate_checks[1] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_2
+ generate_checks[2] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_3
+ generate_checks[3] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_4
+ generate_checks[4] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_5
+ generate_checks[5] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_6
+ generate_checks[6] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_7
+ generate_checks[7] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_8
+ generate_checks[8] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_9
+ generate_checks[9] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_10
+ generate_checks[10] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_11
+ generate_checks[11] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_12
+ generate_checks[12] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_13
+ generate_checks[13] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_14
+ generate_checks[14] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_15
+ generate_checks[15] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_16
+ generate_checks[16] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_17
+ generate_checks[17] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_18
+ generate_checks[18] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_19
+ generate_checks[19] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_20
+ generate_checks[20] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_21
+ generate_checks[21] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_22
+ generate_checks[22] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_23
+ generate_checks[23] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_24
+ generate_checks[24] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_25
+ generate_checks[25] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_26
+ generate_checks[26] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_27
+ generate_checks[27] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_28
+ generate_checks[28] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_29
+ generate_checks[29] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_30
+ generate_checks[30] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_31
+ generate_checks[31] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_32
+ generate_checks[32] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_33
+ generate_checks[33] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_34
+ generate_checks[34] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_35
+ generate_checks[35] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_36
+ generate_checks[36] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_37
+ generate_checks[37] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_38
+ generate_checks[38] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_39
+ generate_checks[39] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_40
+ generate_checks[40] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_41
+ generate_checks[41] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_42
+ generate_checks[42] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_43
+ generate_checks[43] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_44
+ generate_checks[44] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_45
+ generate_checks[45] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_46
+ generate_checks[46] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_47
+ generate_checks[47] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_48
+ generate_checks[48] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_49
+ generate_checks[49] = true;
+#endif
+#ifdef PACKING_CHECK_FIELDS_50
+ generate_checks[50] = true;
+#endif
+}
+
int main(int argc, char **argv)
{
+ parse_defines();
+
printf("/* Automatically generated - do not edit */\n\n");
printf("#ifndef GENERATED_PACKING_CHECKS_H\n");
printf("#define GENERATED_PACKING_CHECKS_H\n\n");

for (int i = 1; i <= 50; i++) {
+ if (!generate_checks[i])
+ continue;
+
printf("#define CHECK_PACKED_FIELDS_%d(fields, pbuflen) \\\n", i);
printf("\t({ typeof(&(fields)[0]) _f = (fields); typeof(pbuflen) _len = (pbuflen); \\\n");
printf("\tBUILD_BUG_ON(ARRAY_SIZE(fields) != %d); \\\n", i);
for (int j = 0; j < i; j++) {
- int final = (i == 1);
+ bool final = (i == 1);

printf("\tCHECK_PACKED_FIELD(_f[%d], _len);%s\n",
j, final ? " })\n" : " \\");
}
for (int j = 1; j < i; j++) {
for (int k = 0; k < j; k++) {
- int final = (j == i - 1) && (k == j - 1);
+ bool final = (j == i - 1) && (k == j - 1);

printf("\tCHECK_PACKED_FIELD_OVERLAP(_f[%d], _f[%d]);%s\n",
k, j, final ? " })\n" : " \\");
--
2.43.0