Change net/bridge/br_sysfs_if.c to use atomic operations to read/change bits n p->flags. Signed-off-by: Eric Dumazet --- net/bridge/br_sysfs_if.c | 61 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 1923c004f0d2b746902f5b6de1bbb72f7f824125..738544901563f570355554f49b2b80cf962f8e71 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -44,40 +44,45 @@ const struct brport_attribute brport_attr_##_name = { \ .store = _store, \ }; -#define BRPORT_ATTR_FLAG(_name, _mask) \ +#define BRPORT_ATTR_FLAG(_name, _bitnr) \ static ssize_t show_##_name(struct net_bridge_port *p, char *buf) \ { \ - return sysfs_emit(buf, "%d\n", !!(p->flags & _mask)); \ + return sysfs_emit(buf, "%d\n", test_bit(_bitnr, &p->flags)); \ } \ static int store_##_name(struct net_bridge_port *p, unsigned long v) \ { \ - return store_flag(p, v, _mask); \ + return store_flag(p, v, _bitnr); \ } \ static BRPORT_ATTR(_name, 0644, \ show_##_name, store_##_name) static int store_flag(struct net_bridge_port *p, unsigned long v, - unsigned long mask) + unsigned long bitnr) { + unsigned long oflags, flags = READ_ONCE(p->flags); struct netlink_ext_ack extack = {0}; - unsigned long flags = p->flags; int err; + + oflags = flags; if (v) - flags |= mask; + __set_bit(bitnr, &flags); else - flags &= ~mask; + __clear_bit(bitnr, &flags); - if (flags != p->flags) { - err = br_switchdev_set_port_flag(p, flags, mask, &extack); - if (err) { - netdev_err(p->dev, "%s\n", extack._msg); - return err; - } + if (flags == oflags) + return 0; - p->flags = flags; - br_port_flags_change(p, mask); + err = br_switchdev_set_port_flag(p, flags, BIT(bitnr), &extack); + if (err) { + netdev_err(p->dev, "%s\n", extack._msg); + return err; } + if (v) + set_bit(bitnr, &p->flags); + else + clear_bit(bitnr, &p->flags); + br_port_flags_change(p, BIT(bitnr)); return 0; } @@ -247,17 +252,17 @@ static int store_backup_port(struct net_bridge_port *p, char *buf) } static BRPORT_ATTR_RAW(backup_port, 0644, show_backup_port, store_backup_port); -BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE); -BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD); -BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); -BRPORT_ATTR_FLAG(learning, BR_LEARNING); -BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); -BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); -BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); -BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); -BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); -BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); -BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); +BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE_BIT); +BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD_BIT); +BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK_BIT); +BRPORT_ATTR_FLAG(learning, BR_LEARNING_BIT); +BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD_BIT); +BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP_BIT); +BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI_BIT); +BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD_BIT); +BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD_BIT); +BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS_BIT); +BRPORT_ATTR_FLAG(isolated, BR_ISOLATED_BIT); #ifdef CONFIG_BRIDGE_IGMP_SNOOPING static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) @@ -273,8 +278,8 @@ static int store_multicast_router(struct net_bridge_port *p, static BRPORT_ATTR(multicast_router, 0644, show_multicast_router, store_multicast_router); -BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); -BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST); +BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE_BIT); +BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST_BIT); #endif static const struct brport_attribute *brport_attrs[] = { -- 2.54.0.1064.gd145956f57-goog