]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bridge: provide lockless access to p->config_pending
authorEric Dumazet <edumazet@google.com>
Thu, 4 Jun 2026 14:13:42 +0000 (14:13 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 6 Jun 2026 00:46:18 +0000 (17:46 -0700)
Needed for sysfs show_config_pending(), BRCTL_GET_PORT_INFO
and upcoming RTNL avoidance in "ip link" dumps (cf br_port_fill_attrs()).

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260604141343.2124500-11-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/bridge/br_ioctl.c
net/bridge/br_netlink.c
net/bridge/br_stp.c
net/bridge/br_stp_if.c
net/bridge/br_sysfs_if.c

index a017374c6e659498d98c6af3f8d8e46a8b93570e..39f3ffcfa2d33f15cec6e61490100925eefc7e68 100644 (file)
@@ -263,7 +263,7 @@ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
                p.designated_cost = READ_ONCE(pt->designated_cost);
                p.state = pt->state;
                p.top_change_ack = pt->topology_change_ack;
-               p.config_pending = pt->config_pending;
+               p.config_pending = READ_ONCE(pt->config_pending);
                p.message_age_timer_value = br_timer_value(&pt->message_age_timer);
                p.forward_delay_timer_value = br_timer_value(&pt->forward_delay_timer);
                p.hold_timer_value = br_timer_value(&pt->hold_timer);
index f8266a7a9e2b910f1b4e08792b2940ae0fd2bba2..ead66dbe1bb7679af18d5f0c2fdea6be2574727d 100644 (file)
@@ -271,7 +271,7 @@ static int br_port_fill_attrs(struct sk_buff *skb,
            nla_put_u16(skb, IFLA_BRPORT_NO, p->port_no) ||
            nla_put_u8(skb, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
                       p->topology_change_ack) ||
-           nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
+           nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, READ_ONCE(p->config_pending)) ||
            nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
                                                        BR_VLAN_TUNNEL)) ||
            nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
index cbc48197c3db5e225ead7425b2cee46acc9768f3..b33eb085d9b6cb4cd4f3aff2aa4793d027bbc0f8 100644 (file)
@@ -220,7 +220,7 @@ void br_transmit_config(struct net_bridge_port *p)
        struct net_bridge *br;
 
        if (timer_pending(&p->hold_timer)) {
-               p->config_pending = 1;
+               WRITE_ONCE(p->config_pending, 1);
                return;
        }
 
@@ -247,7 +247,7 @@ void br_transmit_config(struct net_bridge_port *p)
        if (bpdu.message_age < br->max_age) {
                br_send_config_bpdu(p, &bpdu);
                p->topology_change_ack = 0;
-               p->config_pending = 0;
+               WRITE_ONCE(p->config_pending, 0);
                if (p->br->stp_enabled == BR_KERNEL_STP)
                        mod_timer(&p->hold_timer,
                                  round_jiffies(jiffies + BR_HOLD_TIME));
@@ -490,14 +490,14 @@ void br_port_state_selection(struct net_bridge *br)
                /* Don't change port states if userspace is handling STP */
                if (br->stp_enabled != BR_USER_STP) {
                        if (p->port_no == br->root_port) {
-                               p->config_pending = 0;
+                               WRITE_ONCE(p->config_pending, 0);
                                p->topology_change_ack = 0;
                                br_make_forwarding(p);
                        } else if (br_is_designated_port(p)) {
                                timer_delete(&p->message_age_timer);
                                br_make_forwarding(p);
                        } else {
-                               p->config_pending = 0;
+                               WRITE_ONCE(p->config_pending, 0);
                                p->topology_change_ack = 0;
                                br_make_blocking(p);
                        }
index 8a418f6af423ccba88fae57d2254e35e1ae4a1a0..a7e5422eb5d140b501a7dcebf0238d5a77c5f4a1 100644 (file)
@@ -38,7 +38,7 @@ void br_init_port(struct net_bridge_port *p)
        br_become_designated_port(p);
        br_set_state(p, BR_STATE_BLOCKING);
        p->topology_change_ack = 0;
-       p->config_pending = 0;
+       WRITE_ONCE(p->config_pending, 0);
 
        err = __set_ageing_time(p->dev, p->br->ageing_time);
        if (err)
@@ -105,7 +105,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
        br_become_designated_port(p);
        br_set_state(p, BR_STATE_DISABLED);
        p->topology_change_ack = 0;
-       p->config_pending = 0;
+       WRITE_ONCE(p->config_pending, 0);
 
        br_ifinfo_notify(RTM_NEWLINK, NULL, p);
 
index 1cc474ed0fdc02234a9f9d6b936247c34cbb127d..1923c004f0d2b746902f5b6de1bbb72f7f824125 100644 (file)
@@ -160,7 +160,7 @@ static BRPORT_ATTR(change_ack, 0444, show_change_ack, NULL);
 
 static ssize_t show_config_pending(struct net_bridge_port *p, char *buf)
 {
-       return sysfs_emit(buf, "%d\n", p->config_pending);
+       return sysfs_emit(buf, "%d\n", READ_ONCE(p->config_pending));
 }
 static BRPORT_ATTR(config_pending, 0444, show_config_pending, NULL);