Skip to contentSkip to conversation

wifi: iwlegacy: Avoid multiple -Wflex-array-member-not-at-end warnings

PATCH In review Gustavo A. R. Silva 2 participants 2 messages Aug 15, 2024 – Aug 22, 2024 Intel wireless 3945ABG/bg, 4965AGN (iwlegacy)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 wifi: iwlegacy: Avoid multiple -Wflex-array-member-not-at-end warnings

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.

So, in order to avoid ending up with a flexible-array member in the middle of multiple other structs, we use the __struct_group() helper to create new tagged structures with the suffix _hdr. These structures group together all the members of the original flexible structures except the flexible arrays.

As a result, the arrays are effectively separated from the rest of the members without modifying the memory layout of the flexible structures. We then change the type of the middle struct members currently causing trouble from the original flex struct to the newly created structs with suffix _hdr.

We also want to ensure that when new members need to be added to the flexible structures, they are always included within the newly created tagged structs. For this, we use static_assert(). This ensures that the memory layout for both the flexible structure and the new tagged struct is the same after any changes.

This approach avoids having to implement the _hdr structures as completely separate structures, thus preventing having to maintain two independent but basically identical structures, closing the door to potential bugs in the future.

We also use container_of() whenever we need to retrieve a pointer to the flexible structure, through which we can access the flexible-array member, if necessary.

Also, remove a couple of unused zero-length arrays and flexible-array members.

So, with these changes, fix the following warnings:

drivers/net/wireless/intel/iwlegacy/commands.h:1196:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:1197:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2505:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2549:26: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2654:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2665:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2673:26: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:3349:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

---
 drivers/net/wireless/intel/iwlegacy/3945.c    |   2 +-
 drivers/net/wireless/intel/iwlegacy/3945.h    |   6 +-
 .../net/wireless/intel/iwlegacy/4965-mac.c    |   2 +-
 .../net/wireless/intel/iwlegacy/commands.h    | 303 +++++++++---------
 drivers/net/wireless/intel/iwlegacy/common.h  |   2 +-
 5 files changed, 165 insertions(+), 150 deletions(-)
drivers/net/wireless/intel/iwlegacy/3945.c +1 -1
index 1fab7849f56d..e95800b77f6b 100644
@@ -527,7 +527,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
 	struct ieee80211_hdr *header;
 	struct ieee80211_rx_status rx_status = {};
 	struct il_rx_pkt *pkt = rxb_addr(rxb);
-	struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt);
+	struct il3945_rx_frame_stats_hdr *rx_stats = IL_RX_STATS(pkt);
 	struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
 	struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);
 	u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg);
drivers/net/wireless/intel/iwlegacy/3945.h +4 -2
index 82e4a4878bc2..ffbe11902628 100644
@@ -157,8 +157,10 @@ struct il3945_ibss_seq {
 };
 
 #define IL_RX_HDR(x) ((struct il3945_rx_frame_hdr *)(\
-		       x->u.rx_frame.stats.payload + \
-		       x->u.rx_frame.stats.phy_count))
+		      container_of(&x->u.rx_frame.stats, \
+				   struct il3945_rx_frame_stats, \
+				   hdr)->payload + \
+		      x->u.rx_frame.stats.phy_count))
 #define IL_RX_END(x) ((struct il3945_rx_frame_end *)(\
 		       IL_RX_HDR(x)->payload + \
 		       le16_to_cpu(IL_RX_HDR(x)->len)))
drivers/net/wireless/intel/iwlegacy/4965-mac.c +1 -1
index 1600c344edbb..fcccde7bb659 100644
@@ -1769,7 +1769,7 @@ il4965_tx_skb(struct il_priv *il,
 	/* Set up first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[q->write_ptr];
 	out_meta = &txq->meta[q->write_ptr];
-	tx_cmd = &out_cmd->cmd.tx;
+	tx_cmd = container_of(&out_cmd->cmd.tx, struct il_tx_cmd, __hdr);
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
 	memset(tx_cmd, 0, sizeof(struct il_tx_cmd));
 
drivers/net/wireless/intel/iwlegacy/commands.h +158 -145

376 lines not on this page · raw message

drivers/net/wireless/intel/iwlegacy/common.h +1 -1
index 69687fcf963f..2147781b5fff 100644
@@ -553,7 +553,7 @@ struct il_device_cmd {
 		u8 val8;
 		u16 val16;
 		u32 val32;
-		struct il_tx_cmd tx;
+		struct il_tx_cmd_hdr tx;
 		u8 payload[DEF_CMD_PAYLOAD_SIZE];
 	} __packed cmd;
 } __packed;
Signature · 1 line
2.34.1
#1 lore raw
Quoted 44 lines · Gustavo A. R. Silva

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.

So, in order to avoid ending up with a flexible-array member in the middle of multiple other structs, we use the __struct_group() helper to create new tagged structures with the suffix _hdr. These structures group together all the members of the original flexible structures except the flexible arrays.

As a result, the arrays are effectively separated from the rest of the members without modifying the memory layout of the flexible structures. We then change the type of the middle struct members currently causing trouble from the original flex struct to the newly created structs with suffix _hdr.

We also want to ensure that when new members need to be added to the flexible structures, they are always included within the newly created tagged structs. For this, we use static_assert(). This ensures that the memory layout for both the flexible structure and the new tagged struct is the same after any changes.

This approach avoids having to implement the _hdr structures as completely separate structures, thus preventing having to maintain two independent but basically identical structures, closing the door to potential bugs in the future.

We also use container_of() whenever we need to retrieve a pointer to the flexible structure, through which we can access the flexible-array member, if necessary.

Also, remove a couple of unused zero-length arrays and flexible-array members.

So, with these changes, fix the following warnings:

drivers/net/wireless/intel/iwlegacy/commands.h:1196:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:1197:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2505:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2549:26: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2654:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2665:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:2673:26: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlegacy/commands.h:3349:30: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Quoted 1 line

Patch applied to wireless-next.git, thanks.

a7e8997ae18c wifi: iwlegacy: Avoid multiple -Wflex-array-member-not-at-end warnings

Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/Zr2gxERA3RL3EwRe@elsanto/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches