* [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations
@ 2026-09-01 12:07 Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 1/9] net: bridge: vlan: drop legacy memory barriers Nikolay Aleksandrov
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Hi,
In preparation for a complete vlan fast-path re-work, this set cleans up
a few minor things - removing legacy code barriers that don't help,
annotating lockless accesses and using proper helpers.
No functional changes are intended. Sashiko will find many pre-existing
problems, none of them are related to this set. I will try to fix
everything pre-existing separately in -net, there will probably be a few
critical items. So if there are missed places to annotate, or if there're
actual functional changes, these obviously should be addressed in this set.
Thanks,
Nik
Nikolay Aleksandrov (9):
net: bridge: vlan: drop legacy memory barriers
net: bridge: vlan: annotate lockless pvid use
net: bridge: mst: use br_get_pvid helper
net: bridge: vlan: annotate lockless vlan flags use
net: bridge: vlan: annotate lockless use of private flags
net: bridge: vlan: annotate lockless use of num_vlans
net: bridge: vlan: annotate lockless use of msti
net: bridge: vlan: add missing tinfo.tunnel_id annotations
net: bridge: vlan: use br_vlan_get_state to get vlan state
net/bridge/br_arp_nd_proxy.c | 6 ++++--
net/bridge/br_mst.c | 12 ++++++-----
net/bridge/br_multicast.c | 18 ++++++++++------
net/bridge/br_netlink.c | 10 ++++-----
net/bridge/br_netlink_tunnel.c | 12 +++++------
net/bridge/br_private.h | 16 ++++++++------
net/bridge/br_vlan.c | 39 +++++++++++++++++-----------------
net/bridge/br_vlan_options.c | 6 ++++--
net/bridge/br_vlan_tunnel.c | 2 +-
9 files changed, 67 insertions(+), 54 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 1/9] net: bridge: vlan: drop legacy memory barriers
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 2/9] net: bridge: vlan: annotate lockless pvid use Nikolay Aleksandrov
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
These memory barriers are legacy code from the old vlan implementation
that is not needed anymore. They're also affecting the fast-path.
The pvid is changed under lock and is read with rcu only in the fast-path
there is no need for a barrier, nothing to commit prior to changing it nor
invalidate prior to reading.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_private.h | 1 -
net/bridge/br_vlan.c | 2 --
2 files changed, 3 deletions(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d337b1cfb980..5b2c22ad669e 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1687,7 +1687,6 @@ static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
if (!vg)
return 0;
- smp_rmb();
return vg->pvid;
}
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 1e0e436629ec..2ae6ffb23399 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -40,7 +40,6 @@ static void __vlan_add_pvid(struct net_bridge_vlan_group *vg,
if (vg->pvid == v->vid)
return;
- smp_wmb();
br_vlan_set_pvid_state(vg, v->state);
vg->pvid = v->vid;
}
@@ -50,7 +49,6 @@ static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid)
if (vg->pvid != vid)
return;
- smp_wmb();
vg->pvid = 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 2/9] net: bridge: vlan: annotate lockless pvid use
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 1/9] net: bridge: vlan: drop legacy memory barriers Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 3/9] net: bridge: mst: use br_get_pvid helper Nikolay Aleksandrov
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Use READ/WRITE_ONCE to annotate lockless pvid use, br_get_pvid() is the
helper that should be used outside of the bridge vlan code. The rest of
the vlan places that access pvid directly all have rtnl.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_private.h | 2 +-
net/bridge/br_vlan.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 5b2c22ad669e..0efd2e79e255 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1687,7 +1687,7 @@ static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
if (!vg)
return 0;
- return vg->pvid;
+ return READ_ONCE(vg->pvid);
}
static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 2ae6ffb23399..a53054fcc093 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -41,7 +41,7 @@ static void __vlan_add_pvid(struct net_bridge_vlan_group *vg,
return;
br_vlan_set_pvid_state(vg, v->state);
- vg->pvid = v->vid;
+ WRITE_ONCE(vg->pvid, v->vid);
}
static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid)
@@ -49,7 +49,7 @@ static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid)
if (vg->pvid != vid)
return;
- vg->pvid = 0;
+ WRITE_ONCE(vg->pvid, 0);
}
/* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v.
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 3/9] net: bridge: mst: use br_get_pvid helper
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 1/9] net: bridge: vlan: drop legacy memory barriers Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 2/9] net: bridge: vlan: annotate lockless pvid use Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 4/9] net: bridge: vlan: annotate lockless vlan flags use Nikolay Aleksandrov
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
The only place that accessed pvid directly outside of the bridge vlan code
was mst, change it to use the br_get_pvid helper.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_mst.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
index 43a300ae6bfa..95e49ec8065e 100644
--- a/net/bridge/br_mst.c
+++ b/net/bridge/br_mst.c
@@ -86,7 +86,7 @@ static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg,
if (br_vlan_get_state(v) == state)
return;
- if (v->vid == vg->pvid)
+ if (v->vid == br_get_pvid(vg))
br_vlan_set_pvid_state(vg, state);
br_vlan_set_state(v, state);
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 4/9] net: bridge: vlan: annotate lockless vlan flags use
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (2 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 3/9] net: bridge: mst: use br_get_pvid helper Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 5/9] net: bridge: vlan: annotate lockless use of private flags Nikolay Aleksandrov
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Annotate vlan flags data races, they can be read lockless.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_multicast.c | 2 +-
net/bridge/br_netlink.c | 6 +++---
net/bridge/br_private.h | 4 ++--
net/bridge/br_vlan.c | 19 +++++++++++--------
4 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 3ef5d8bbf552..bbcaedf15ca1 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -912,7 +912,7 @@ static void __br_multicast_query_handle_vlan(struct net_bridge_mcast *brmctx,
else if (br_multicast_ctx_is_vlan(brmctx))
vlan = brmctx->vlan;
- if (vlan && !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) {
+ if (vlan && !(READ_ONCE(vlan->flags) & BRIDGE_VLAN_INFO_UNTAGGED)) {
u16 vlan_proto;
if (br_vlan_get_proto(brmctx->br->dev, &vlan_proto) != 0)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index b2cd4e39326d..62ce96d9ba32 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -41,7 +41,7 @@ static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg,
if (v->vid == pvid)
flags |= BRIDGE_VLAN_INFO_PVID;
- if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+ if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED)
flags |= BRIDGE_VLAN_INFO_UNTAGGED;
if (vid_range_start == 0) {
@@ -385,7 +385,7 @@ static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb,
if (v->vid == pvid)
flags |= BRIDGE_VLAN_INFO_PVID;
- if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+ if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED)
flags |= BRIDGE_VLAN_INFO_UNTAGGED;
if (vid_range_start == 0) {
@@ -437,7 +437,7 @@ static int br_fill_ifvlaninfo(struct sk_buff *skb,
if (v->vid == pvid)
vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
- if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+ if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED)
vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 0efd2e79e255..96554d293d22 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -665,13 +665,13 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
/* check if a VLAN entry is global */
static inline bool br_vlan_is_master(const struct net_bridge_vlan *v)
{
- return v->flags & BRIDGE_VLAN_INFO_MASTER;
+ return READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_MASTER;
}
/* check if a VLAN entry is used by the bridge */
static inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v)
{
- return v->flags & BRIDGE_VLAN_INFO_BRENTRY;
+ return READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_BRENTRY;
}
/* check if we should use the vlan entry, returns false if it's only context */
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index a53054fcc093..c8b2e3bfd42d 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -60,6 +60,7 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
bool commit)
{
struct net_bridge_vlan_group *vg;
+ u16 vlan_flags;
bool change;
if (br_vlan_is_master(v))
@@ -68,8 +69,9 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
vg = nbp_vlan_group(v->port);
/* check if anything would be changed on commit */
+ vlan_flags = v->flags;
change = !!(flags & BRIDGE_VLAN_INFO_PVID) == !!(vg->pvid != v->vid) ||
- ((flags ^ v->flags) & BRIDGE_VLAN_INFO_UNTAGGED);
+ ((flags ^ vlan_flags) & BRIDGE_VLAN_INFO_UNTAGGED);
if (!commit)
goto out;
@@ -80,9 +82,10 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
__vlan_delete_pvid(vg, v->vid);
if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
- v->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
+ vlan_flags |= BRIDGE_VLAN_INFO_UNTAGGED;
else
- v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED;
+ vlan_flags &= ~BRIDGE_VLAN_INFO_UNTAGGED;
+ WRITE_ONCE(v->flags, vlan_flags);
out:
return change;
@@ -413,7 +416,7 @@ static int __vlan_del(struct net_bridge_vlan *v)
}
if (br_vlan_should_use(v)) {
- v->flags &= ~BRIDGE_VLAN_INFO_BRENTRY;
+ WRITE_ONCE(v->flags, v->flags & ~BRIDGE_VLAN_INFO_BRENTRY);
vg->num_vlans--;
}
@@ -522,7 +525,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
* hardware on each egress port as appropriate. So only strip the VLAN
* header if forwarding offload is not being used.
*/
- if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED &&
+ if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED &&
!br_switchdev_frame_uses_tx_fwd_offload(skb))
__vlan_hwaccel_clear_tag(skb);
@@ -753,7 +756,7 @@ static int br_vlan_add_existing(struct net_bridge *br,
}
refcount_inc(&vlan->refcnt);
- vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY;
+ WRITE_ONCE(vlan->flags, vlan->flags | BRIDGE_VLAN_INFO_BRENTRY);
vg->num_vlans++;
*changed = true;
br_multicast_toggle_one_vlan(vlan, true);
@@ -1489,7 +1492,7 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
if (!v || !br_vlan_should_use(v))
return -EINVAL;
- if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED))
+ if (!(READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED))
return 0;
if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
@@ -1550,7 +1553,7 @@ int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid,
return -ENOENT;
p_vinfo->vid = vid;
- p_vinfo->flags = v->flags;
+ p_vinfo->flags = READ_ONCE(v->flags);
if (vid == br_get_pvid(vg))
p_vinfo->flags |= BRIDGE_VLAN_INFO_PVID;
return 0;
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 5/9] net: bridge: vlan: annotate lockless use of private flags
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (3 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 4/9] net: bridge: vlan: annotate lockless vlan flags use Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 6/9] net: bridge: vlan: annotate lockless use of num_vlans Nikolay Aleksandrov
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Annotate vlan private flags data races, they can be read lockless.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_arp_nd_proxy.c | 6 ++++--
net/bridge/br_multicast.c | 16 ++++++++++------
net/bridge/br_private.h | 9 ++++++---
net/bridge/br_vlan.c | 2 +-
net/bridge/br_vlan_options.c | 6 ++++--
5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
index 87a40e2f1c50..b82fa6589ab9 100644
--- a/net/bridge/br_arp_nd_proxy.c
+++ b/net/bridge/br_arp_nd_proxy.c
@@ -521,7 +521,8 @@ bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid)
v = br_vlan_find(vg, vid);
if (!v)
return false;
- return !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED);
+ return !!(READ_ONCE(v->priv_flags) &
+ BR_VLFLAG_NEIGH_SUPPRESS_ENABLED);
}
return test_bit(BR_NEIGH_SUPPRESS_BIT, &p->flags);
}
@@ -535,7 +536,8 @@ bool br_is_neigh_forward_grat_enabled(const struct net_bridge_port *p, u16 vid)
v = br_vlan_find(vg, vid);
if (!v)
return false;
- return !!(v->priv_flags & BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED);
+ return !!(READ_ONCE(v->priv_flags) &
+ BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED);
}
return test_bit(BR_NEIGH_FORWARD_GRAT_BIT, &p->flags);
}
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index bbcaedf15ca1..cd984173320f 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -2172,7 +2172,7 @@ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
spin_lock_bh(&br->multicast_lock);
if (br_multicast_port_ctx_is_vlan(pmctx) &&
- !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
+ !(READ_ONCE(pmctx->vlan->priv_flags) & BR_VLFLAG_MCAST_ENABLED)) {
spin_unlock_bh(&br->multicast_lock);
return;
}
@@ -2209,7 +2209,7 @@ static void br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
spin_lock_bh(&br->multicast_lock);
if (br_multicast_port_ctx_is_vlan(pmctx) &&
- !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
+ !(READ_ONCE(pmctx->vlan->priv_flags) & BR_VLFLAG_MCAST_ENABLED)) {
spin_unlock_bh(&br->multicast_lock);
return;
}
@@ -4083,7 +4083,8 @@ int br_multicast_rcv(struct net_bridge_mcast **brmctx,
*pmctx = &vlan->port_mcast_ctx;
}
- if (!(masterv->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED))
+ if (!(READ_ONCE(masterv->priv_flags) &
+ BR_VLFLAG_GLOBAL_MCAST_ENABLED))
return 0;
}
@@ -4383,7 +4384,8 @@ void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on)
return;
spin_lock_bh(&br->multicast_lock);
- vlan->priv_flags ^= BR_VLFLAG_MCAST_ENABLED;
+ WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^
+ BR_VLFLAG_MCAST_ENABLED);
spin_unlock_bh(&br->multicast_lock);
if (on)
@@ -4399,7 +4401,8 @@ void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on)
br = vlan->port->br;
spin_lock_bh(&br->multicast_lock);
- vlan->priv_flags ^= BR_VLFLAG_MCAST_ENABLED;
+ WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^
+ BR_VLFLAG_MCAST_ENABLED);
if (on)
__br_multicast_enable_port_ctx(&vlan->port_mcast_ctx);
else
@@ -4477,7 +4480,8 @@ bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on)
if (on == !!(vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED))
return false;
- vlan->priv_flags ^= BR_VLFLAG_GLOBAL_MCAST_ENABLED;
+ WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^
+ BR_VLFLAG_GLOBAL_MCAST_ENABLED);
br_multicast_toggle_vlan(vlan, on);
return true;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 96554d293d22..c7b64b5da012 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1273,21 +1273,24 @@ br_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx)
{
return br_multicast_ctx_is_vlan(brmctx) &&
(!br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) ||
- !(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED));
+ !(READ_ONCE(brmctx->vlan->priv_flags) &
+ BR_VLFLAG_GLOBAL_MCAST_ENABLED));
}
static inline bool
br_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx)
{
return br_multicast_ctx_is_vlan(brmctx) &&
- !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
+ !(READ_ONCE(brmctx->vlan->priv_flags) &
+ BR_VLFLAG_MCAST_ENABLED);
}
static inline bool
br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx)
{
return br_multicast_port_ctx_is_vlan(pmctx) &&
- !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
+ !(READ_ONCE(pmctx->vlan->priv_flags) &
+ BR_VLFLAG_MCAST_ENABLED);
}
static inline bool
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index c8b2e3bfd42d..102792f20a5e 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1497,7 +1497,7 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
- else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
+ else if (READ_ONCE(v->priv_flags) & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
else
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
diff --git a/net/bridge/br_vlan_options.c b/net/bridge/br_vlan_options.c
index cb0f556ff40d..bd049d268fe7 100644
--- a/net/bridge/br_vlan_options.c
+++ b/net/bridge/br_vlan_options.c
@@ -276,7 +276,8 @@ static int br_vlan_process_one_opts(const struct net_bridge *br,
}
if (val != enabled) {
- v->priv_flags ^= BR_VLFLAG_NEIGH_SUPPRESS_ENABLED;
+ WRITE_ONCE(v->priv_flags, v->priv_flags ^
+ BR_VLFLAG_NEIGH_SUPPRESS_ENABLED);
*changed = true;
}
}
@@ -292,7 +293,8 @@ static int br_vlan_process_one_opts(const struct net_bridge *br,
}
if (val != enabled) {
- v->priv_flags ^= BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED;
+ WRITE_ONCE(v->priv_flags, v->priv_flags ^
+ BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED);
*changed = true;
}
}
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 6/9] net: bridge: vlan: annotate lockless use of num_vlans
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (4 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 5/9] net: bridge: vlan: annotate lockless use of private flags Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 7/9] net: bridge: vlan: annotate lockless use of msti Nikolay Aleksandrov
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Annotate data races around vlan group's num_vlans, it can be read lockless.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_netlink.c | 4 ++--
net/bridge/br_vlan.c | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 62ce96d9ba32..ae76df0de05a 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -81,7 +81,7 @@ static int br_get_num_vlan_infos(struct net_bridge_vlan_group *vg,
return 0;
if (filter_mask & RTEXT_FILTER_BRVLAN)
- return vg->num_vlans;
+ return READ_ONCE(vg->num_vlans);
rcu_read_lock();
num_vlans = __get_num_vlan_infos(vg, filter_mask);
@@ -531,7 +531,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
else
vg = br_vlan_group_rcu(br);
- if (!vg || !vg->num_vlans) {
+ if (!vg || !READ_ONCE(vg->num_vlans)) {
rcu_read_unlock();
goto done;
}
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 102792f20a5e..95187a607ec2 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -344,7 +344,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
goto out_filt;
}
}
- vg->num_vlans++;
+ WRITE_ONCE(vg->num_vlans, vg->num_vlans + 1);
}
/* set the state before publishing */
@@ -367,7 +367,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
out_fdb_insert:
if (br_vlan_should_use(v)) {
br_fdb_find_delete_local(br, p, dev->dev_addr, v->vid);
- vg->num_vlans--;
+ WRITE_ONCE(vg->num_vlans, vg->num_vlans - 1);
}
out_filt:
@@ -417,7 +417,7 @@ static int __vlan_del(struct net_bridge_vlan *v)
if (br_vlan_should_use(v)) {
WRITE_ONCE(v->flags, v->flags & ~BRIDGE_VLAN_INFO_BRENTRY);
- vg->num_vlans--;
+ WRITE_ONCE(vg->num_vlans, vg->num_vlans - 1);
}
if (masterv != v) {
@@ -695,7 +695,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
return true;
vg = nbp_vlan_group_rcu(p);
- if (!vg || !vg->num_vlans)
+ if (!vg || !READ_ONCE(vg->num_vlans))
return false;
if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto)
@@ -757,7 +757,7 @@ static int br_vlan_add_existing(struct net_bridge *br,
refcount_inc(&vlan->refcnt);
WRITE_ONCE(vlan->flags, vlan->flags | BRIDGE_VLAN_INFO_BRENTRY);
- vg->num_vlans++;
+ WRITE_ONCE(vg->num_vlans, vg->num_vlans + 1);
*changed = true;
br_multicast_toggle_one_vlan(vlan, true);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 7/9] net: bridge: vlan: annotate lockless use of msti
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (5 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 6/9] net: bridge: vlan: annotate lockless use of num_vlans Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 8/9] net: bridge: vlan: add missing tinfo.tunnel_id annotations Nikolay Aleksandrov
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
Annotate data races around vlan msti field, it can be read lockless.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_mst.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
index 95e49ec8065e..76a5bf287578 100644
--- a/net/bridge/br_mst.c
+++ b/net/bridge/br_mst.c
@@ -123,7 +123,7 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
err = 0;
list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
- if (v->brvlan->msti != msti)
+ if (READ_ONCE(v->brvlan->msti) != msti)
continue;
br_mst_vlan_set_state(vg, v, state);
@@ -176,7 +176,7 @@ int br_mst_vlan_set_msti(struct net_bridge_vlan *mv, u16 msti)
if (err && err != -EOPNOTSUPP)
return err;
- mv->msti = msti;
+ WRITE_ONCE(mv->msti, msti);
list_for_each_entry(p, &mv->br->port_list, list) {
vg = nbp_vlan_group(p);
@@ -249,7 +249,9 @@ size_t br_mst_info_size(const struct net_bridge_vlan_group *vg)
sz = nla_total_size(0);
list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
- if (test_bit(v->brvlan->msti, seen))
+ u16 msti = READ_ONCE(v->brvlan->msti);
+
+ if (test_bit(msti, seen))
continue;
/* IFLA_BRIDGE_MST_ENTRY */
@@ -259,7 +261,7 @@ size_t br_mst_info_size(const struct net_bridge_vlan_group *vg)
/* IFLA_BRIDGE_MST_ENTRY_STATE */
nla_total_size(sizeof(u8));
- __set_bit(v->brvlan->msti, seen);
+ __set_bit(msti, seen);
}
return sz;
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 8/9] net: bridge: vlan: add missing tinfo.tunnel_id annotations
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (6 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 7/9] net: bridge: vlan: annotate lockless use of msti Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 9/9] net: bridge: vlan: use br_vlan_get_state to get vlan state Nikolay Aleksandrov
2026-09-02 17:22 ` [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
When I annotated data races around tinfo.tunnel_id before, I missed a few
places (e.g. bridge notifications, rhashtable compare), so add them now.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_netlink_tunnel.c | 12 ++++++------
net/bridge/br_vlan_tunnel.c | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/bridge/br_netlink_tunnel.c b/net/bridge/br_netlink_tunnel.c
index e7eceab5b515..58ec7bf1d8f5 100644
--- a/net/bridge/br_netlink_tunnel.c
+++ b/net/bridge/br_netlink_tunnel.c
@@ -29,8 +29,8 @@ static size_t __get_vlan_tinfo_size(void)
bool vlan_tunid_inrange(const struct net_bridge_vlan *v_curr,
const struct net_bridge_vlan *v_last)
{
- __be32 tunid_curr = tunnel_id_to_key32(v_curr->tinfo.tunnel_id);
- __be32 tunid_last = tunnel_id_to_key32(v_last->tinfo.tunnel_id);
+ __be32 tunid_curr = tunnel_id_to_key32(READ_ONCE(v_curr->tinfo.tunnel_id));
+ __be32 tunid_last = tunnel_id_to_key32(READ_ONCE(v_last->tinfo.tunnel_id));
return (be32_to_cpu(tunid_curr) - be32_to_cpu(tunid_last)) == 1;
}
@@ -43,7 +43,7 @@ static int __get_num_vlan_tunnel_infos(struct net_bridge_vlan_group *vg)
/* Count number of vlan infos */
list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
/* only a context, bridge vlan not activated */
- if (!br_vlan_should_use(v) || !v->tinfo.tunnel_id)
+ if (!br_vlan_should_use(v) || !READ_ONCE(v->tinfo.tunnel_id))
continue;
if (!vtbegin) {
@@ -124,19 +124,19 @@ static int br_fill_vlan_tinfo_range(struct sk_buff *skb,
if (vtend && (vtend->vid - vtbegin->vid) > 0) {
/* add range to skb */
err = br_fill_vlan_tinfo(skb, vtbegin->vid,
- vtbegin->tinfo.tunnel_id,
+ READ_ONCE(vtbegin->tinfo.tunnel_id),
BRIDGE_VLAN_INFO_RANGE_BEGIN);
if (err)
return err;
err = br_fill_vlan_tinfo(skb, vtend->vid,
- vtend->tinfo.tunnel_id,
+ READ_ONCE(vtend->tinfo.tunnel_id),
BRIDGE_VLAN_INFO_RANGE_END);
if (err)
return err;
} else {
err = br_fill_vlan_tinfo(skb, vtbegin->vid,
- vtbegin->tinfo.tunnel_id,
+ READ_ONCE(vtbegin->tinfo.tunnel_id),
0);
if (err)
return err;
diff --git a/net/bridge/br_vlan_tunnel.c b/net/bridge/br_vlan_tunnel.c
index 257cae9f1569..04751f15d708 100644
--- a/net/bridge/br_vlan_tunnel.c
+++ b/net/bridge/br_vlan_tunnel.c
@@ -22,7 +22,7 @@ static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg,
const struct net_bridge_vlan *vle = ptr;
__be64 tunid = *(__be64 *)arg->key;
- return vle->tinfo.tunnel_id != tunid;
+ return READ_ONCE(vle->tinfo.tunnel_id) != tunid;
}
static const struct rhashtable_params br_vlan_tunnel_rht_params = {
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next 9/9] net: bridge: vlan: use br_vlan_get_state to get vlan state
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (7 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 8/9] net: bridge: vlan: add missing tinfo.tunnel_id annotations Nikolay Aleksandrov
@ 2026-09-01 12:07 ` Nikolay Aleksandrov
2026-09-02 17:22 ` [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-01 12:07 UTC (permalink / raw)
To: netdev
Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge,
Nikolay Aleksandrov
The MST code can change the vlan state with only rcu, so use the helper
to get the state properly.
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
net/bridge/br_vlan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 95187a607ec2..72b75757ac85 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -40,7 +40,7 @@ static void __vlan_add_pvid(struct net_bridge_vlan_group *vg,
if (vg->pvid == v->vid)
return;
- br_vlan_set_pvid_state(vg, v->state);
+ br_vlan_set_pvid_state(vg, br_vlan_get_state(v));
WRITE_ONCE(vg->pvid, v->vid);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
` (8 preceding siblings ...)
2026-09-01 12:07 ` [PATCH net-next 9/9] net: bridge: vlan: use br_vlan_get_state to get vlan state Nikolay Aleksandrov
@ 2026-09-02 17:22 ` Nikolay Aleksandrov
9 siblings, 0 replies; 11+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-02 17:22 UTC (permalink / raw)
To: netdev; +Cc: idosch, davem, edumazet, kuba, pabeni, horms, bridge
On 01/09/2026 15:07, Nikolay Aleksandrov wrote:
> Hi,
> In preparation for a complete vlan fast-path re-work, this set cleans up
> a few minor things - removing legacy code barriers that don't help,
> annotating lockless accesses and using proper helpers.
> No functional changes are intended. Sashiko will find many pre-existing
> problems, none of them are related to this set. I will try to fix
> everything pre-existing separately in -net, there will probably be a few
> critical items. So if there are missed places to annotate, or if there're
> actual functional changes, these obviously should be addressed in this set.
>
> Thanks,
> Nik
>
> Nikolay Aleksandrov (9):
> net: bridge: vlan: drop legacy memory barriers
> net: bridge: vlan: annotate lockless pvid use
> net: bridge: mst: use br_get_pvid helper
> net: bridge: vlan: annotate lockless vlan flags use
> net: bridge: vlan: annotate lockless use of private flags
> net: bridge: vlan: annotate lockless use of num_vlans
> net: bridge: vlan: annotate lockless use of msti
> net: bridge: vlan: add missing tinfo.tunnel_id annotations
> net: bridge: vlan: use br_vlan_get_state to get vlan state
>
> net/bridge/br_arp_nd_proxy.c | 6 ++++--
> net/bridge/br_mst.c | 12 ++++++-----
> net/bridge/br_multicast.c | 18 ++++++++++------
> net/bridge/br_netlink.c | 10 ++++-----
> net/bridge/br_netlink_tunnel.c | 12 +++++------
> net/bridge/br_private.h | 16 ++++++++------
> net/bridge/br_vlan.c | 39 +++++++++++++++++-----------------
> net/bridge/br_vlan_options.c | 6 ++++--
> net/bridge/br_vlan_tunnel.c | 2 +-
> 9 files changed, 67 insertions(+), 54 deletions(-)
>
Me and Ido had a chat and he commented that patch 09 is far from done, I missed state
accesses outside of br_vlan.c, silly mistake. Anyway, I'll fix it up and post v2.
Cheers,
Nik
---
pw-bot: cr
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-02 17:22 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 12:07 [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 1/9] net: bridge: vlan: drop legacy memory barriers Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 2/9] net: bridge: vlan: annotate lockless pvid use Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 3/9] net: bridge: mst: use br_get_pvid helper Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 4/9] net: bridge: vlan: annotate lockless vlan flags use Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 5/9] net: bridge: vlan: annotate lockless use of private flags Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 6/9] net: bridge: vlan: annotate lockless use of num_vlans Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 7/9] net: bridge: vlan: annotate lockless use of msti Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 8/9] net: bridge: vlan: add missing tinfo.tunnel_id annotations Nikolay Aleksandrov
2026-09-01 12:07 ` [PATCH net-next 9/9] net: bridge: vlan: use br_vlan_get_state to get vlan state Nikolay Aleksandrov
2026-09-02 17:22 ` [PATCH net-next 0/9] net: bridge: vlan: minor cleanups and annotations Nikolay Aleksandrov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox