Message ID | 20240719094119.35c62455087d.I68eb9c0f02545b364b79a59f2110f2cf5682a8e2@changeid (mailing list archive) |
---|---|
State | Accepted |
Commit | 3ba359c0cd6eb5ea772125a7aededb4a2d516684 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] net: bonding: correctly annotate RCU in bond_should_notify_peers() | expand |
Johannes Berg <johannes@sipsolutions.net> wrote: >From: Johannes Berg <johannes.berg@intel.com> > >RCU use in bond_should_notify_peers() looks wrong, since it does >rcu_dereference(), leaves the critical section, and uses the >pointer after that. > >Luckily, it's called either inside a nested RCU critical section >or with the RTNL held. > >Annotate it with rcu_dereference_rtnl() instead, and remove the >inner RCU critical section. > >Fixes: 4cb4f97b7e36 ("bonding: rebuild the lock use for bond_mii_monitor()") >Reviewed-by: Jiri Pirko <jiri@nvidia.com> >Signed-off-by: Johannes Berg <johannes.berg@intel.com> Acked-by: Jay Vosburgh <jv@jvosburgh.net> >--- > drivers/net/bonding/bond_main.c | 7 ++----- > 1 file changed, 2 insertions(+), 5 deletions(-) > >diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c >index d19aabf5d4fb..2ed0da068490 100644 >--- a/drivers/net/bonding/bond_main.c >+++ b/drivers/net/bonding/bond_main.c >@@ -1121,13 +1121,10 @@ static struct slave *bond_find_best_slave(struct bonding *bond) > return bestslave; > } > >+/* must be called in RCU critical section or with RTNL held */ > static bool bond_should_notify_peers(struct bonding *bond) > { >- struct slave *slave; >- >- rcu_read_lock(); >- slave = rcu_dereference(bond->curr_active_slave); >- rcu_read_unlock(); >+ struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); > > if (!slave || !bond->send_peer_notif || > bond->send_peer_notif % >-- >2.45.2 >
On 7/19/24 18:41, Johannes Berg wrote: > From: Johannes Berg <johannes.berg@intel.com> > > RCU use in bond_should_notify_peers() looks wrong, since it does > rcu_dereference(), leaves the critical section, and uses the > pointer after that. > > Luckily, it's called either inside a nested RCU critical section > or with the RTNL held. > > Annotate it with rcu_dereference_rtnl() instead, and remove the > inner RCU critical section. > > Fixes: 4cb4f97b7e36 ("bonding: rebuild the lock use for bond_mii_monitor()") > Reviewed-by: Jiri Pirko <jiri@nvidia.com> > Signed-off-by: Johannes Berg <johannes.berg@intel.com> Any special reasons to target net-next? this looks like a legit net fix to me. If you want to target net, no need to re-post, otherwise it will have to wait the merge window end. Thanks, Paolo
On Tue, 2024-07-23 at 12:25 +0200, Paolo Abeni wrote: > > On 7/19/24 18:41, Johannes Berg wrote: > > From: Johannes Berg <johannes.berg@intel.com> > > > > RCU use in bond_should_notify_peers() looks wrong, since it does > > rcu_dereference(), leaves the critical section, and uses the > > pointer after that. > > > > Luckily, it's called either inside a nested RCU critical section > > or with the RTNL held. > > > > Annotate it with rcu_dereference_rtnl() instead, and remove the > > inner RCU critical section. > > > > Fixes: 4cb4f97b7e36 ("bonding: rebuild the lock use for bond_mii_monitor()") > > Reviewed-by: Jiri Pirko <jiri@nvidia.com> > > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > > Any special reasons to target net-next? this looks like a legit net fix > to me. If you want to target net, no need to re-post, otherwise it will > have to wait the merge window end. Well, I guess it's kind of a fix, but functionally all it really does is remove the RCU critical section which isn't necessary because either we hold the lock or there's already one around it. So locally the function _looks_ wrong (using the pointer outside the section it uses to deref it), but because of other reasons in how the function is used, it's not really wrong. I'd really prefer not to have to resend it though ;-) johannes
On 7/23/24 13:30, Johannes Berg wrote: > On Tue, 2024-07-23 at 12:25 +0200, Paolo Abeni wrote: >> >> On 7/19/24 18:41, Johannes Berg wrote: >>> From: Johannes Berg <johannes.berg@intel.com> >>> >>> RCU use in bond_should_notify_peers() looks wrong, since it does >>> rcu_dereference(), leaves the critical section, and uses the >>> pointer after that. >>> >>> Luckily, it's called either inside a nested RCU critical section >>> or with the RTNL held. >>> >>> Annotate it with rcu_dereference_rtnl() instead, and remove the >>> inner RCU critical section. >>> >>> Fixes: 4cb4f97b7e36 ("bonding: rebuild the lock use for bond_mii_monitor()") >>> Reviewed-by: Jiri Pirko <jiri@nvidia.com> >>> Signed-off-by: Johannes Berg <johannes.berg@intel.com> >> >> Any special reasons to target net-next? this looks like a legit net fix >> to me. If you want to target net, no need to re-post, otherwise it will >> have to wait the merge window end. > > Well, I guess it's kind of a fix, but functionally all it really does is > remove the RCU critical section which isn't necessary because either we > hold the lock or there's already one around it. So locally the function > _looks_ wrong (using the pointer outside the section it uses to deref > it), but because of other reasons in how the function is used, it's not > really wrong. I think we are better off with this applied on net. No need to resend. Thanks, Paolo
Hello: This patch was applied to netdev/net.git (main) by Paolo Abeni <pabeni@redhat.com>: On Fri, 19 Jul 2024 09:41:18 -0700 you wrote: > From: Johannes Berg <johannes.berg@intel.com> > > RCU use in bond_should_notify_peers() looks wrong, since it does > rcu_dereference(), leaves the critical section, and uses the > pointer after that. > > Luckily, it's called either inside a nested RCU critical section > or with the RTNL held. > > [...] Here is the summary with links: - [net-next] net: bonding: correctly annotate RCU in bond_should_notify_peers() https://git.kernel.org/netdev/net/c/3ba359c0cd6e You are awesome, thank you!
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d19aabf5d4fb..2ed0da068490 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1121,13 +1121,10 @@ static struct slave *bond_find_best_slave(struct bonding *bond) return bestslave; } +/* must be called in RCU critical section or with RTNL held */ static bool bond_should_notify_peers(struct bonding *bond) { - struct slave *slave; - - rcu_read_lock(); - slave = rcu_dereference(bond->curr_active_slave); - rcu_read_unlock(); + struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); if (!slave || !bond->send_peer_notif || bond->send_peer_notif %