Skip to content

Commit

Permalink
nfp: Avoid -Wflex-array-member-not-at-end warnings
Browse files Browse the repository at this point in the history
-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
ready to enable it globally.

There is currently an object (`tl`), at the beginning of multiple
structures, that contains a flexible structure (`struct nfp_dump_tl`),
for example:

struct nfp_dumpspec_csr {
        struct nfp_dump_tl tl;

        ...

        __be32 register_width;  /* in bits */
};

So, in order to avoid ending up with flexible-array members in the
middle of multiple other structs, we use the `struct_group_tagged()`
helper to separate the flexible array from the rest of the members
in the flexible structure:

struct nfp_dump_tl {
	struct_group_tagged(nfp_dump_tl_hdr, hdr,

	... the rest of members

	);
        char data[];
};

With the change described above, we now declare objects of the type of
the tagged struct, in this case `struct nfp_dump_tl_hdr`, without
embedding flexible arrays in the middle of another struct:

struct nfp_dumpspec_csr {
        struct nfp_dump_tl_hdr tl;

	...

        __be32 register_width;  /* in bits */
};

Also, use `container_of()` whenever we need to retrieve a pointer to
the flexible structure, through which we can access the flexible
array if needed.

So, with these changes, fix 33 of the following warnings:
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:58:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:64:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:70:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:78:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:87:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c:92:28: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Link: KSPP/linux#202
Signed-off-by: Gustavo A. R. Silva <[email protected]>
Link: https://lore.kernel.org/r/ZgYWlkxdrrieDYIu@neat
Signed-off-by: Jakub Kicinski <[email protected]>
[Ryno: backport and add compat]
Signed-off-by: Ryno Swart <[email protected]>
Signed-off-by: Louis Peens <[email protected]>
  • Loading branch information
GustavoARSilva authored and louis-peens committed Apr 5, 2024
1 parent de2168f commit 4a05860
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/nfp_net_debugdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ enum nfp_dumpspec_type {

/* generic type plus length */
struct nfp_dump_tl {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
/* New members must be added within the struct_group() macro below. */
struct_group_tagged(nfp_dump_tl_hdr, hdr,
__be32 type;
__be32 length; /* chunk length to follow, aligned to 8 bytes */
);
#else
__be32 type;
__be32 length; /* chunk length to follow, aligned to 8 bytes */
#endif
char data[];
};

Expand All @@ -57,27 +65,43 @@ struct nfp_dump_common_cpp {

/* CSR dumpables */
struct nfp_dumpspec_csr {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
struct nfp_dump_common_cpp cpp;
__be32 register_width; /* in bits */
};

struct nfp_dumpspec_rtsym {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
char rtsym[];
};

/* header for register dumpable */
struct nfp_dump_csr {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
struct nfp_dump_common_cpp cpp;
__be32 register_width; /* in bits */
__be32 error; /* error code encountered while reading */
__be32 error_offset; /* offset being read when error occurred */
};

struct nfp_dump_rtsym {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
struct nfp_dump_common_cpp cpp;
__be32 error; /* error code encountered while reading */
u8 padded_name_length; /* pad so data starts at 8 byte boundary */
Expand All @@ -86,12 +110,20 @@ struct nfp_dump_rtsym {
};

struct nfp_dump_prolog {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
__be32 dump_level;
};

struct nfp_dump_error {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl_hdr tl;
#else
struct nfp_dump_tl tl;
#endif
__be32 error;
char padding[4];
char spec[];
Expand Down Expand Up @@ -451,6 +483,10 @@ static int
nfp_dump_csr_range(struct nfp_pf *pf, struct nfp_dumpspec_csr *spec_csr,
struct nfp_dump_state *dump)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl *spec_csr_tl =
container_of(&spec_csr->tl, struct nfp_dump_tl, hdr);
#endif
struct nfp_dump_csr *dump_header = dump->p;
u32 reg_sz, header_size, total_size;
u32 cpp_rd_addr, max_rd_addr;
Expand All @@ -460,15 +496,23 @@ nfp_dump_csr_range(struct nfp_pf *pf, struct nfp_dumpspec_csr *spec_csr,
int err;

if (!nfp_csr_spec_valid(spec_csr))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
return nfp_dump_error_tlv(spec_csr_tl, -EINVAL, dump);
#else
return nfp_dump_error_tlv(&spec_csr->tl, -EINVAL, dump);
#endif

reg_sz = be32_to_cpu(spec_csr->register_width) / BITS_PER_BYTE;
header_size = ALIGN8(sizeof(*dump_header));
total_size = header_size +
ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
dest = dump->p + header_size;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
err = nfp_add_tlv(be32_to_cpu(spec_csr_tl->type), total_size, dump);
#else
err = nfp_add_tlv(be32_to_cpu(spec_csr->tl.type), total_size, dump);
#endif
if (err)
return err;

Expand Down Expand Up @@ -554,6 +598,10 @@ nfp_dump_indirect_csr_range(struct nfp_pf *pf,
struct nfp_dumpspec_csr *spec_csr,
struct nfp_dump_state *dump)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl *spec_csr_tl =
container_of(&spec_csr->tl, struct nfp_dump_tl, hdr);
#endif
struct nfp_dump_csr *dump_header = dump->p;
u32 reg_sz, header_size, total_size;
u32 cpp_rd_addr, max_rd_addr;
Expand All @@ -562,7 +610,11 @@ nfp_dump_indirect_csr_range(struct nfp_pf *pf,
int err;

if (!nfp_csr_spec_valid(spec_csr))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
return nfp_dump_error_tlv(spec_csr_tl, -EINVAL, dump);
#else
return nfp_dump_error_tlv(&spec_csr->tl, -EINVAL, dump);
#endif

reg_sz = be32_to_cpu(spec_csr->register_width) / BITS_PER_BYTE;
header_size = ALIGN8(sizeof(*dump_header));
Expand All @@ -571,7 +623,11 @@ nfp_dump_indirect_csr_range(struct nfp_pf *pf,
total_size = header_size + ALIGN8(reg_data_length);
dest = dump->p + header_size;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
err = nfp_add_tlv(be32_to_cpu(spec_csr_tl->type), total_size, dump);
#else
err = nfp_add_tlv(be32_to_cpu(spec_csr->tl.type), total_size, dump);
#endif
if (err)
return err;

Expand Down Expand Up @@ -599,6 +655,10 @@ static int
nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
struct nfp_dump_state *dump)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
struct nfp_dump_tl *spec_tl =
container_of(&spec->tl, struct nfp_dump_tl, hdr);
#endif
struct nfp_dump_rtsym *dump_header = dump->p;
struct nfp_dumpspec_cpp_isl_id cpp_params;
struct nfp_rtsym_table *rtbl = pf->rtbl;
Expand All @@ -609,22 +669,38 @@ nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
void *dest;
int err;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
tl_len = be32_to_cpu(spec_tl->length);
#else
tl_len = be32_to_cpu(spec->tl.length);
#endif
key_len = strnlen(spec->rtsym, tl_len);
if (key_len == tl_len)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
return nfp_dump_error_tlv(spec_tl, -EINVAL, dump);
#else
return nfp_dump_error_tlv(&spec->tl, -EINVAL, dump);
#endif

sym = nfp_rtsym_lookup(rtbl, spec->rtsym);
if (!sym)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
return nfp_dump_error_tlv(spec_tl, -ENOENT, dump);
#else
return nfp_dump_error_tlv(&spec->tl, -ENOENT, dump);
#endif

sym_size = nfp_rtsym_size(sym);
header_size =
ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1);
total_size = header_size + ALIGN8(sym_size);
dest = dump->p + header_size;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
err = nfp_add_tlv(be32_to_cpu(spec_tl->type), total_size, dump);
#else
err = nfp_add_tlv(be32_to_cpu(spec->tl.type), total_size, dump);
#endif
if (err)
return err;

Expand Down

0 comments on commit 4a05860

Please sign in to comment.