From: Eric Dumazet Date: Thu, 4 Jun 2026 14:13:42 +0000 (+0000) Subject: bridge: provide lockless access to p->config_pending X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f51657cd7227ece7ada209447f7698409802c814;p=thirdparty%2Flinux.git bridge: provide lockless access to p->config_pending 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 Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20260604141343.2124500-11-edumazet@google.com Signed-off-by: Jakub Kicinski --- diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index a017374c6e65..39f3ffcfa2d3 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -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); diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f8266a7a9e2b..ead66dbe1bb7 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -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) || diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index cbc48197c3db..b33eb085d9b6 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -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); } diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 8a418f6af423..a7e5422eb5d1 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -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); diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 1cc474ed0fdc..1923c004f0d2 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -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);