From 1fbe2d9d37adbc881c3a558de0903c8c0e70651c Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Mon, 5 Oct 2026 17:39:35 +0300 Subject: [PATCH] net: bridge: vlan: inline pvid pointer updates After caching the pvid VLAN entry directly, the add and delete helpers only check and update the pointer. So inline them both and clear pvid directly in __vlan_flush before walking the VLAN entries. Signed-off-by: Nikolay Aleksandrov Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20261005143937.877466-5-razor@blackwall.org Signed-off-by: Jakub Kicinski --- net/bridge/br_vlan.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index dcf783e1a440..c4e7e03e0969 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -34,24 +34,6 @@ static struct net_bridge_vlan *br_vlan_lookup(struct rhashtable *tbl, u16 vid) return rhashtable_lookup_fast(tbl, &vid, br_vlan_rht_params); } -static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, - struct net_bridge_vlan *v) -{ - if (rcu_access_pointer(vg->pvid) == v) - return; - - RCU_INIT_POINTER(vg->pvid, v); -} - -static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, - struct net_bridge_vlan *v) -{ - if (rcu_access_pointer(vg->pvid) != v) - return; - - RCU_INIT_POINTER(vg->pvid, NULL); -} - /* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v. * If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID and * BRIDGE_VLAN_INFO_UNTAGGED bits of @flags would produce any change onto @v. @@ -78,10 +60,12 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, if (!commit) goto out; - if (flags & BRIDGE_VLAN_INFO_PVID) - __vlan_add_pvid(vg, v); - else - __vlan_delete_pvid(vg, v); + if (flags & BRIDGE_VLAN_INFO_PVID) { + if (pvid != v) + RCU_INIT_POINTER(vg->pvid, v); + } else if (pvid == v) { + RCU_INIT_POINTER(vg->pvid, NULL); + } if (flags & BRIDGE_VLAN_INFO_UNTAGGED) vlan_flags |= BRIDGE_VLAN_INFO_UNTAGGED; @@ -432,7 +416,8 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, static void __vlan_unpublish(struct net_bridge_vlan_group *vg, struct net_bridge_vlan *v) { - __vlan_delete_pvid(vg, v); + if (rcu_access_pointer(vg->pvid) == v) + RCU_INIT_POINTER(vg->pvid, NULL); if (!br_vlan_is_master(v)) { struct net_bridge_vlan *masterv = v->brvlan; @@ -503,7 +488,7 @@ static void __vlan_flush(const struct net_bridge *br, struct net_bridge_vlan *vlan, *tmp; u16 v_start = 0, v_end = 0; - __vlan_delete_pvid(vg, rtnl_dereference(vg->pvid)); + RCU_INIT_POINTER(vg->pvid, NULL); list_for_each_entry_safe(vlan, tmp, &vg->vlan_list, vlist) { /* take care of disjoint ranges */ if (!v_start) {