summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2026-06-04 17:13:42 +0300
committerJakub Kicinski <kuba@kernel.org>2026-06-06 03:46:18 +0300
commitf51657cd7227ece7ada209447f7698409802c814 (patch)
tree0054ace0e28f8063577259cf6a696ff645b73d60
parent6d39b5d080094f2224284fd54a86d8c79ef14e27 (diff)
downloadlinux-f51657cd7227ece7ada209447f7698409802c814.tar.xz
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 <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>
-rw-r--r--net/bridge/br_ioctl.c2
-rw-r--r--net/bridge/br_netlink.c2
-rw-r--r--net/bridge/br_stp.c8
-rw-r--r--net/bridge/br_stp_if.c4
-rw-r--r--net/bridge/br_sysfs_if.c2
5 files changed, 9 insertions, 9 deletions
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);