diff mbox series

wifi: ath11k: fix RCU documentation in ath11k_mac_op_ipv6_changed()

Message ID 20240531022411.6543-1-quic_bqiang@quicinc.com (mailing list archive)
State Accepted
Commit 53d7c99719e29819eaeb9f373d262a6b56ea7cce
Delegated to: Kalle Valo
Headers show
Series wifi: ath11k: fix RCU documentation in ath11k_mac_op_ipv6_changed() | expand

Commit Message

Baochen Qiang May 31, 2024, 2:24 a.m. UTC
Current documentation on RCU in ath11k_mac_op_ipv6_changed() says:

	/* Note: read_lock_bh() calls rcu_read_lock() */
	read_lock_bh(&idev->lock);

This is wrong because without enabling CONFIG_PREEMPT_RT
rcu_read_lock() is not called by read_lock_bh(). The reason
why current code works even in a CONFIG_PREEMPT_RT=n kernel
is because atomic_notifier_call_chain() already does that for
us, see:

	int atomic_notifier_call_chain()
	{
		...
		rcu_read_lock();
		ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
		rcu_read_unlock();
		...
	}

and backtrace:

	ath11k_mac_op_ipv6_changed
	ieee80211_ifa6_changed
	notifier_call_chain
	atomic_notifier_call_chain

So update the comment to make it correct.

This is found during code review, compile tested only.

Fixes: feafe59c8975 ("wifi: ath11k: use RCU when accessing struct inet6_dev::ac_list")
Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
---
 drivers/net/wireless/ath/ath11k/mac.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)


base-commit: 6e7a5c6d5e38b93f9cc3289d66a597b9a4ca0403

Comments

Jeff Johnson June 3, 2024, 8:06 p.m. UTC | #1
On 5/30/2024 7:24 PM, Baochen Qiang wrote:
> Current documentation on RCU in ath11k_mac_op_ipv6_changed() says:
> 
> 	/* Note: read_lock_bh() calls rcu_read_lock() */
> 	read_lock_bh(&idev->lock);
> 
> This is wrong because without enabling CONFIG_PREEMPT_RT
> rcu_read_lock() is not called by read_lock_bh(). The reason
> why current code works even in a CONFIG_PREEMPT_RT=n kernel
> is because atomic_notifier_call_chain() already does that for
> us, see:
> 
> 	int atomic_notifier_call_chain()
> 	{
> 		...
> 		rcu_read_lock();
> 		ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
> 		rcu_read_unlock();
> 		...
> 	}
> 
> and backtrace:
> 
> 	ath11k_mac_op_ipv6_changed
> 	ieee80211_ifa6_changed
> 	notifier_call_chain
> 	atomic_notifier_call_chain
> 
> So update the comment to make it correct.
> 
> This is found during code review, compile tested only.
> 
> Fixes: feafe59c8975 ("wifi: ath11k: use RCU when accessing struct inet6_dev::ac_list")
> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Kalle Valo June 11, 2024, 6:40 p.m. UTC | #2
Baochen Qiang <quic_bqiang@quicinc.com> wrote:

> Current documentation on RCU in ath11k_mac_op_ipv6_changed() says:
> 
>         /* Note: read_lock_bh() calls rcu_read_lock() */
>         read_lock_bh(&idev->lock);
> 
> This is wrong because without enabling CONFIG_PREEMPT_RT
> rcu_read_lock() is not called by read_lock_bh(). The reason
> why current code works even in a CONFIG_PREEMPT_RT=n kernel
> is because atomic_notifier_call_chain() already does that for
> us, see:
> 
>         int atomic_notifier_call_chain()
>         {
>                 ...
>                 rcu_read_lock();
>                 ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
>                 rcu_read_unlock();
>                 ...
>         }
> 
> and backtrace:
> 
>         ath11k_mac_op_ipv6_changed
>         ieee80211_ifa6_changed
>         notifier_call_chain
>         atomic_notifier_call_chain
> 
> So update the comment to make it correct.
> 
> This is found during code review, compile tested only.
> 
> Fixes: feafe59c8975 ("wifi: ath11k: use RCU when accessing struct inet6_dev::ac_list")
> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>

Patch applied to ath-next branch of ath.git, thanks.

53d7c99719e2 wifi: ath11k: fix RCU documentation in ath11k_mac_op_ipv6_changed()
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index a1800c75d32b..29af015a16f9 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -9020,7 +9020,12 @@  static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,
 	offload = &arvif->arp_ns_offload;
 	count = 0;
 
-	/* Note: read_lock_bh() calls rcu_read_lock() */
+	/* The _ipv6_changed() is called with RCU lock already held in
+	 * atomic_notifier_call_chain(), so we don't need to call
+	 * rcu_read_lock() again here. But note that with CONFIG_PREEMPT_RT
+	 * enabled, read_lock_bh() also calls rcu_read_lock(). This is OK
+	 * because RCU read critical section is allowed to get nested.
+	 */
 	read_lock_bh(&idev->lock);
 
 	memset(offload->ipv6_addr, 0, sizeof(offload->ipv6_addr));