diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-08-31 08:10:27 +0000 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-09-01 12:26:52 +0200 |
| commit | bc93419130bb70fabf6561e197054caae85c160c (patch) | |
| tree | 5dfea030a3d8ccbbbed068c81eaa41bee6e0382a | |
| parent | c037915f80c4db47f7d061d68e703ffd551b1a34 (diff) | |
| download | linux-bc93419130bb70fabf6561e197054caae85c160c.tar.gz linux-bc93419130bb70fabf6561e197054caae85c160c.zip | |
net: bonding: annotate lockless writes with WRITE_ONCE()
Several fields in bonding are read locklessly using READ_ONCE()
(or ACCESS_ONCE() previously) but have corresponding writes that
do not use WRITE_ONCE().
Add WRITE_ONCE() annotations to:
- bond->send_peer_notif decrements in bond_peer_notify_may_events()
and reset in bond_close().
- bond->slave_cnt increments and decrements in bond_enslave() and
__bond_release_one().
- bond->recv_probe updates in bond_open(), bond_option_arp_interval_set()
and rlb_initialize().
- slaves->count decrement in bond_skip_slave().
Fixes: 4d97480b1806 ("bonding: use local function pointer of bond->recv_probe in bond_handle_frame")
Fixes: 9a72c2da690d ("bonding: fix div by zero while enslaving and transmitting")
Fixes: ee6377147409 ("bonding: Simplify the xmit function for modes that use xmit_hash")
Fixes: 429208aab9db ("net: bonding: add the READ_ONCE/WRITE_ONCE for outside lock accessing")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jay Vosburgh <jv@jvosburgh.net>
Reviewed-by: Xuanqiang Luo<luoxuanqiang@kylinos.cn>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260831081027.3209554-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
| -rw-r--r-- | drivers/net/bonding/bond_alb.c | 2 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 14 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.c | 4 |
3 files changed, 10 insertions, 10 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 839f7482dc18..d2fb67a47cf9 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -875,7 +875,7 @@ static int rlb_initialize(struct bonding *bond) spin_unlock_bh(&bond->mode_lock); /* register to receive ARPs */ - bond->recv_probe = rlb_arp_recv; + WRITE_ONCE(bond->recv_probe, rlb_arp_recv); return 0; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ef9eb0c53c66..947d92a669b6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1245,7 +1245,7 @@ static void bond_peer_notify_may_events(struct bonding *bond, bool force) } if (notified || force) - bond->send_peer_notif--; + WRITE_ONCE(bond->send_peer_notif, bond->send_peer_notif - 1); } /** @@ -2284,7 +2284,7 @@ skip_mac_set: } } - bond->slave_cnt++; + WRITE_ONCE(bond->slave_cnt, bond->slave_cnt + 1); netdev_compute_master_upper_features(bond->dev, true); bond_set_carrier(bond); @@ -2533,7 +2533,7 @@ static int __bond_release_one(struct net_device *bond_dev, unblock_netpoll_tx(); synchronize_rcu(); - bond->slave_cnt--; + WRITE_ONCE(bond->slave_cnt, bond->slave_cnt - 1); if (!bond_has_slaves(bond)) { call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); @@ -4385,13 +4385,13 @@ static int bond_open(struct net_device *bond_dev) if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ queue_delayed_work(bond->wq, &bond->arp_work, 0); - bond->recv_probe = bond_rcv_validate; + WRITE_ONCE(bond->recv_probe, bond_rcv_validate); } if (BOND_MODE(bond) == BOND_MODE_8023AD) { queue_delayed_work(bond->wq, &bond->ad_work, 0); /* register to receive LACPDUs */ - bond->recv_probe = bond_3ad_lacpdu_recv; + WRITE_ONCE(bond->recv_probe, bond_3ad_lacpdu_recv); bond_3ad_initiate_agg_selection(bond, 1); bond_for_each_slave(bond, slave, iter) @@ -4413,7 +4413,7 @@ static int bond_close(struct net_device *bond_dev) struct slave *slave; bond_work_cancel_all(bond); - bond->send_peer_notif = 0; + WRITE_ONCE(bond->send_peer_notif, 0); WRITE_ONCE(bond->recv_probe, NULL); /* Wait for any in-flight RX handlers */ @@ -5118,7 +5118,7 @@ static void bond_skip_slave(struct bond_up_slave *slaves, if (skipslave == slaves->arr[idx]) { slaves->arr[idx] = slaves->arr[slaves->count - 1]; - slaves->count--; + WRITE_ONCE(slaves->count, slaves->count - 1); break; } } diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 36b8d89387ee..9efadeff6a22 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1147,11 +1147,11 @@ static int bond_option_arp_interval_set(struct bonding *bond, */ if (!newval->value) { if (bond->params.arp_validate) - bond->recv_probe = NULL; + WRITE_ONCE(bond->recv_probe, NULL); cancel_delayed_work_sync(&bond->arp_work); } else { /* arp_validate can be set only in active-backup mode */ - bond->recv_probe = bond_rcv_validate; + WRITE_ONCE(bond->recv_probe, bond_rcv_validate); cancel_delayed_work_sync(&bond->mii_work); queue_delayed_work(bond->wq, &bond->arp_work, 0); } |
