From: Eric Dumazet Date: Thu, 4 Jun 2026 14:13:41 +0000 (+0000) Subject: bridge: provide lockless access to p->port_id X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d39b5d080094f2224284fd54a86d8c79ef14e27;p=thirdparty%2Flinux.git bridge: provide lockless access to p->port_id sysfs show_port_id() and BRCTL_GET_PORT_INFO need this. This will be needed for 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-10-edumazet@google.com Signed-off-by: Jakub Kicinski --- diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 2be802991f70a..a017374c6e659 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -257,7 +257,7 @@ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, memset(&p, 0, sizeof(struct __port_info)); memcpy(&p.designated_root, &pt->designated_root, 8); memcpy(&p.designated_bridge, &pt->designated_bridge, 8); - p.port_id = pt->port_id; + p.port_id = READ_ONCE(pt->port_id); p.designated_port = READ_ONCE(pt->designated_port); p.path_cost = READ_ONCE(pt->path_cost); p.designated_cost = READ_ONCE(pt->designated_cost); diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index fc25c6b6cc971..f8266a7a9e2b9 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -267,7 +267,7 @@ static int br_port_fill_attrs(struct sk_buff *skb, READ_ONCE(p->designated_port)) || nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_COST, READ_ONCE(p->designated_cost)) || - nla_put_u16(skb, IFLA_BRPORT_ID, p->port_id) || + nla_put_u16(skb, IFLA_BRPORT_ID, READ_ONCE(p->port_id)) || nla_put_u16(skb, IFLA_BRPORT_NO, p->port_no) || nla_put_u8(skb, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK, p->topology_change_ack) || diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 3524bb7e87f05..8a418f6af423c 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -34,7 +34,7 @@ void br_init_port(struct net_bridge_port *p) { int err; - p->port_id = br_make_port_id(p->priority, p->port_no); + WRITE_ONCE(p->port_id, br_make_port_id(p->priority, p->port_no)); br_become_designated_port(p); br_set_state(p, BR_STATE_BLOCKING); p->topology_change_ack = 0; @@ -322,7 +322,7 @@ int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio) if (br_is_designated_port(p)) WRITE_ONCE(p->designated_port, new_port_id); - p->port_id = new_port_id; + WRITE_ONCE(p->port_id, new_port_id); WRITE_ONCE(p->priority, newprio); if (!memcmp(&p->br->bridge_id, &p->designated_bridge, 8) && p->port_id < p->designated_port) { diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 3f666d4fef423..1cc474ed0fdc0 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -141,7 +141,7 @@ static BRPORT_ATTR(designated_cost, 0444, show_designated_cost, NULL); static ssize_t show_port_id(struct net_bridge_port *p, char *buf) { - return sysfs_emit(buf, "0x%x\n", p->port_id); + return sysfs_emit(buf, "0x%x\n", READ_ONCE(p->port_id)); } static BRPORT_ATTR(port_id, 0444, show_port_id, NULL);