Commit 9c7da87c2dc8 for kernel

commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9
Author: Jiayuan Chen <jiayuan.chen@linux.dev>
Date:   Wed May 27 13:31:31 2026 +0800

    ipv6: fix possible infinite loop in fib6_select_path()

    Found while auditing the same pattern Sashiko reported in
    rt6_fill_node() [1]. Apply the same fix as
    commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

    Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
    without waiting for RCU readers; first->fib6_siblings.next then
    still points into the old ring and this softirq-side walker never
    reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
    always WRITE_ONCE()s first->fib6_nsiblings to 0 before
    list_del_rcu(), so an inside-loop check is a reliable detach signal.

    [1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

    Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
    Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
    Reviewed-by: Ido Schimmel <idosch@nvidia.com>
    Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index dad416fdc585..636f0120d7e3 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -481,6 +481,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
 		const struct fib6_nh *nh = sibling->fib6_nh;
 		int nh_upper_bound;

+		if (!READ_ONCE(first->fib6_nsiblings))
+			break;
+
 		nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
 		if (hash > nh_upper_bound)
 			continue;