Skip to contentSkip to conversation

wifi: ath11k: fix rx completion meta data corruption

PATCH Applied Johan Hovold 5 participants 8 messages Mar 21, 2025 – May 16, 2025

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 wifi: ath11k: fix rx completion meta data corruption

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

	ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

---

As I reported here:

https://lore.kernel.org/lkml/[email protected]/

the ath11k and ath12k appear to be missing a number of memory barriers that are required on weakly ordered architectures like aarch64 to avoid memory corruption issues.

Here's a fix for one more such case which people already seem to be hitting.

Note that I've seen one "msdu_done" bit not set warning also with this patch so whether it helps with that at all remains to be seen. I'm CCing Jens and Steev that see these warnings frequently and that may be able to help out with testing.

Johan

 drivers/net/wireless/ath/ath11k/dp_rx.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +16 -9
index 029ecf51c9ef..0a57b337e4c6 100644
@@ -2646,7 +2646,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 	struct ath11k *ar;
 	struct hal_reo_dest_ring *desc;
 	enum hal_reo_dest_ring_push_reason push_reason;
-	u32 cookie;
+	u32 cookie, info0, rx_msdu_info0, rx_mpdu_info0;
 	int i;
 
 	for (i = 0; i < MAX_RADIOS; i++)
@@ -2659,11 +2659,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 try_again:
 	ath11k_hal_srng_access_begin(ab, srng);
 
+	/* Make sure descriptor is read after the head pointer. */
+	dma_rmb();
+
 	while (likely(desc =
 	      (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
 									     srng))) {
 		cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
-				   desc->buf_addr_info.info1);
+				   READ_ONCE(desc->buf_addr_info.info1));
 		buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
 				   cookie);
 		mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
@@ -2692,8 +2695,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 
 		num_buffs_reaped[mac_id]++;
 
+		info0 = READ_ONCE(desc->info0);
 		push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
-					desc->info0);
+					info0);
 		if (unlikely(push_reason !=
 			     HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
 			dev_kfree_skb_any(msdu);
@@ -2701,18 +2705,21 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 			continue;
 		}
 
-		rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
+		rx_msdu_info0 = READ_ONCE(desc->rx_msdu_info.info0);
+		rx_mpdu_info0 = READ_ONCE(desc->rx_mpdu_info.info0);
+
+		rxcb->is_first_msdu = !!(rx_msdu_info0 &
 					 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
-		rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
+		rxcb->is_last_msdu = !!(rx_msdu_info0 &
 					RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
-		rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
+		rxcb->is_continuation = !!(rx_msdu_info0 &
 					   RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
 		rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
-					  desc->rx_mpdu_info.meta_data);
+					  READ_ONCE(desc->rx_mpdu_info.meta_data));
 		rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
-					 desc->rx_mpdu_info.info0);
+					 rx_mpdu_info0);
 		rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
-				      desc->info0);
+				      info0);
 
 		rxcb->mac_id = mac_id;
 		__skb_queue_tail(&msdu_list[mac_id], msdu);
Signature · 1 line
2.48.1
#1 lore raw

Hi Johan,

Quoted 111 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

        ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

---

As I reported here:

https://lore.kernel.org/lkml/[email protected]/

the ath11k and ath12k appear to be missing a number of memory barriers that are required on weakly ordered architectures like aarch64 to avoid memory corruption issues.

Here's a fix for one more such case which people already seem to be hitting.

Note that I've seen one "msdu_done" bit not set warning also with this patch so whether it helps with that at all remains to be seen. I'm CCing Jens and Steev that see these warnings frequently and that may be able to help out with testing.

Johan

 drivers/net/wireless/ath/ath11k/dp_rx.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +16 -10
index 029ecf51c9ef..0a57b337e4c6 100644
@@ -2646,7 +2646,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
        struct ath11k *ar;
        struct hal_reo_dest_ring *desc;
        enum hal_reo_dest_ring_push_reason push_reason;
-       u32 cookie;
+       u32 cookie, info0, rx_msdu_info0, rx_mpdu_info0;
        int i;
 
        for (i = 0; i < MAX_RADIOS; i++)
@@ -2659,11 +2659,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 try_again:
        ath11k_hal_srng_access_begin(ab, srng);
 
+       /* Make sure descriptor is read after the head pointer. */
+       dma_rmb();
+
        while (likely(desc =
              (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
                                                                             srng))) {
                cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
-                                  desc->buf_addr_info.info1);
+                                  READ_ONCE(desc->buf_addr_info.info1));
                buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
                                   cookie);
                mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
@@ -2692,8 +2695,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 
                num_buffs_reaped[mac_id]++;
 
+               info0 = READ_ONCE(desc->info0);
                push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
-                                       desc->info0);
+                                       info0);
                if (unlikely(push_reason !=
                             HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
                        dev_kfree_skb_any(msdu);
@@ -2701,18 +2705,21 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
                        continue;
                }
 
-               rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
+               rx_msdu_info0 = READ_ONCE(desc->rx_msdu_info.info0);
+               rx_mpdu_info0 = READ_ONCE(desc->rx_mpdu_info.info0);
+
+               rxcb->is_first_msdu = !!(rx_msdu_info0 &
                                         RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
-               rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
+               rxcb->is_last_msdu = !!(rx_msdu_info0 &
                                        RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
-               rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
+               rxcb->is_continuation = !!(rx_msdu_info0 &
                                           RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
                rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
-                                         desc->rx_mpdu_info.meta_data);
+                                         READ_ONCE(desc->rx_mpdu_info.meta_data));
                rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
-                                        desc->rx_mpdu_info.info0);
+                                        rx_mpdu_info0);
                rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
-                                     desc->info0);
+                                     info0);
 
                rxcb->mac_id = mac_id;
                __skb_queue_tail(&msdu_list[mac_id], msdu);
--
Quoted 2 lines

2.48.1

While the fix is definitely a fix, it does not seem to help with the msdu_done bit in attention is not set message as I have seen it 43 times in the last 12 hours.

-- Steev

#2 lore raw
Quoted 32 lines · Steev Klimaszewski
Quoted 31 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

        ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

---

As I reported here:

https://lore.kernel.org/lkml/[email protected]/

the ath11k and ath12k appear to be missing a number of memory barriers that are required on weakly ordered architectures like aarch64 to avoid memory corruption issues.

Here's a fix for one more such case which people already seem to be hitting.

Quoted 8 lines
Quoted 4 lines

Note that I've seen one "msdu_done" bit not set warning also with this patch so whether it helps with that at all remains to be seen. I'm CCing Jens and Steev that see these warnings frequently and that may be able to help out with testing.

While the fix is definitely a fix, it does not seem to help with the msdu_done bit in attention is not set message as I have seen it 43 times in the last 12 hours.

Thanks for testing, Steev. Given that that the patch makes the warnings go away in Clayton's setup it seems we may be dealing with more than once root cause here.

Johan

Tested-by on v1 1/1
#3 lore raw
In reply to Johan Hovold
Quoted 27 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

	ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

---

As I reported here:

https://lore.kernel.org/lkml/[email protected]/

the ath11k and ath12k appear to be missing a number of memory barriers that are required on weakly ordered architectures like aarch64 to avoid memory corruption issues.

Quoted 8 lines

Here's a fix for one more such case which people already seem to be hitting.

Note that I've seen one "msdu_done" bit not set warning also with this patch so whether it helps with that at all remains to be seen. I'm CCing Jens and Steev that see these warnings frequently and that may be able to help out with testing.

Before this patch I was seeing this "msdu_done bit" an average of about 40 times per hour... e.g. a recent boot period of 43hrs saw 1600 of these msgs. I've been testing this patch for about 10 hours now connected to the same network etc, and haven't seen this "msdu_done bit" message once. So, even if it's not completely resolving this for everyone, it seems to be a huge improvement for me.

0006:01:00.0 Network controller: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter (rev 01)
ath11k_pci 0006:01:00.0: chip_id 0x2 chip_family 0xb board_id 0x8c soc_id 0x400c0210
ath11k_pci 0006:01:00.0: fw_version 0x11088c35 fw_build_timestamp 2024-04-17 08:34 fw_build_id WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

#4 lore raw
Quoted 51 lines · Clayton Craft
Quoted 27 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

	ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

---

As I reported here:

https://lore.kernel.org/lkml/[email protected]/

the ath11k and ath12k appear to be missing a number of memory barriers that are required on weakly ordered architectures like aarch64 to avoid memory corruption issues.

Quoted 7 lines

Here's a fix for one more such case which people already seem to be hitting.

Note that I've seen one "msdu_done" bit not set warning also with this patch so whether it helps with that at all remains to be seen. I'm CCing Jens and Steev that see these warnings frequently and that may be able to help out with testing.

Before this patch I was seeing this "msdu_done bit" an average of about 40 times per hour... e.g. a recent boot period of 43hrs saw 1600 of these msgs. I've been testing this patch for about 10 hours now connected to the same network etc, and haven't seen this "msdu_done bit" message once. So, even if it's not completely resolving this for everyone, it seems to be a huge improvement for me.

0006:01:00.0 Network controller: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter (rev 01)
ath11k_pci 0006:01:00.0: chip_id 0x2 chip_family 0xb board_id 0x8c soc_id 0x400c0210
ath11k_pci 0006:01:00.0: fw_version 0x11088c35 fw_build_timestamp 2024-04-17 08:34 fw_build_id WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Quoted 1 line

Thanks for testing and confirming my suspicion.

Johan

#5 lore raw
In reply to Johan Hovold
Quoted 9 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

Quoted 8 lines
	ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

Does this supersede:
[PATCH] wifi: ath11k: fix ring-buffer corruption

#6 lore raw
Quoted 14 lines · Jeff Johnson
Quoted 13 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

	ath11k_pci 0006:01:00.0: msdu_done bit in attention is not set

Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41

Quoted 7 lines
Quoted 4 lines
Fixes d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")

Does this supersede:
[PATCH] wifi: ath11k: fix ring-buffer corruption

No, this is a separate fix. There are more places where barriers are missing, I'll try send some further fixes during the week as well.

Johan

Applied
#7 lore raw
In reply to Johan Hovold
Quoted 10 lines · Johan Hovold

Add the missing memory barrier to make sure that the REO dest ring descriptor is read after the head pointer to avoid using stale data on weakly ordered architectures like aarch64.

This may fix the ring-buffer corruption worked around by commit f9fff67d2d7c ("wifi: ath11k: Fix SKB corruption in REO destination ring") by silently discarding data, and may possibly also address user reported errors like:

[...]

Applied, thanks!

[1/1] wifi: ath11k: fix rx completion meta data corruption

      commit: ab52e3e44fe9b666281752e2481d11e25b0e3fdd

Best regards,

Signature · 1 line
Jeff Johnson <[email protected]>