xthop.c:2085 and net/ipv4/nexthop.c:2094. - This function runs for non-group nexthops during deletion; see call site in `__remove_nexthop()`: net/ipv4/nexthop.c:2166. The RTNL lock is held across deletion (rtnl lock in `rtm_del_nexthop()`); net/ipv4/nexthop.c:3310. - The patch’s exact change: - Adds an early return when there is nothing to remove: - New check: `if (list_empty(&nh->grp_list)) return;` - This prevents the unconditional `synchronize_net()` when `nh` belongs to no groups. - The loop and the barrier still run when there are entries to remove, preserving the original safety guarantee. - Why the early return is safe: - If `&nh->grp_list` is empty, no group arrays are modified; there is nothing to “publish” and thus no readers to wait out. The barrier is purely to serialize readers after `rcu_assign_pointer()` of a new group array (e.g., in `remove_nh_grp_entry()` which calls `rcu_assign_pointer(nhp->nh_grp, newg)`; net/ipv4/nexthop.c:around 2020). With no modifications, the barrier is a no-op, only adding latency. - Concurrency context is correct: group membership modifications happen under RTNL, and `remove_nexthop_from_groups()` is called under RTNL; `list_empty()` on `nh->grp_list` is consistent. The list head is always initialized (`INIT_LIST_HEAD(&nh->grp_list)`; net/ipv4/nexthop.c:542). - Other RCU barriers in the file that protect real publications remain intact (e.g., in group replacement, `synchronize_net()` remains; net/ipv4/nexthop.c:2291). Stable policy considerations - Scope is tiny and self-contained (one function, one early return); no cross-subsystem impact. - Not a feature; it is a performance fix for a behavior introduced by an earlier change (90f33bffa382) that added unconditional grace periods even when nothing changed. - Risk of regression is very low: previously, the barrier was sometimes unnecessary. Now it remains when necessary and is skipped when provably unneeded. No change to notifier behavior or group update logic. Practical backport notes - Older stable trees may have `synchronize_rcu()` instead of `synchronize_net()` at the end of `remove_nexthop_from_groups()`. The early return remains valid and safe regardless; adapt the barrier name to the tree’s version if needed. - The infrastructure used by the check (`nh->grp_list`) and usage context (RTNL held) are long-standing and present in stable kernels that have nexthop groups. Conclusion - This change is a classic stable backport candidate: important user- visible improvement, minimal risk, no semantics change, and tightly scoped to the nexthop cleanup path. net/ipv4/nexthop.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 34137768e7f9a..15acfb74fd238 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -2087,6 +2087,12 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, { struct nh_grp_entry *nhge, *tmp; + /* If there is nothing to do, let's avoid the costly call to + * synchronize_net() + */ + if (list_empty(&nh->grp_list)) + return; + list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list) remove_nh_grp_entry(net, nhge, nlinfo); -- 2.51.0[PATCH AUTOSEL 6.17-5.4] net: When removing nexthops, don't call synchronize_net if it is not necessarySasha Levin undefinedpatches@lists.linux.dev, stable@vger.kernel.org undefined undefined undefined undefined undefined undefined undefined undefined undefined undefinedW#