]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bridge: provide lockless access to p->port_id
authorEric Dumazet <edumazet@google.com>
Thu, 4 Jun 2026 14:13:41 +0000 (14:13 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 6 Jun 2026 00:46:18 +0000 (17:46 -0700)
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 <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260604141343.2124500-10-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_if.c
net/bridge/br_sysfs_if.c

index 2be802991f70ab3ce48ade5da6d1488e072dbec6..a017374c6e659498d98c6af3f8d8e46a8b93570e 100644 (file)
@@ -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);
index fc25c6b6cc9713080873976f443da1fbd764aafe..f8266a7a9e2b910f1b4e08792b2940ae0fd2bba2 100644 (file)
@@ -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) ||
index 3524bb7e87f0586774a883720be9fa8eb60f0370..8a418f6af423ccba88fae57d2254e35e1ae4a1a0 100644 (file)
@@ -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) {
index 3f666d4fef42324a4751779153ecc48bdb44b85a..1cc474ed0fdc02234a9f9d6b936247c34cbb127d 100644 (file)
@@ -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);