From 20dff14006b189baf05011b44e785d100458cc95 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 1 Oct 2026 20:47:13 +0000 Subject: [PATCH] net: Order blackhole_netdev_init(), inet_init(), and inet6_init(). Commit 309b905deee5 ("ipv6: convert CONFIG_IPV6 to built-in only and clean up Kconfigs") started to call inet6_init() as device_initcall(). It explains the reason as a race condition on IPv6 addrconf, but this is not accurate. The change initially used fs_initcall() but switched to device_initcall() due to the null-ptr-deref stack trace in the link below. It happened because blackhole_netdev_init() uses device_initcall() and blackhole_netdev was NULL when addrconf_init() called ipv6_add_dev(blackhole_netdev). Due to the order in Kbuild, $ cat -n Kbuild | grep -E "(drivers|net)" 111 obj-y += drivers/ 114 obj-$(CONFIG_NET) += net/ using device_initcall() for IPv6 allows built-in drivers to be initialised earlier, which requires unnecessary NULL checks. For the same ordering reason, IPv4 uses late_initcall() to initialise blackhole_netdev. Given loopback_net_ops is registered in net_dev_init() at subsys_initcall(), blackhole_netdev_init() can be called after that. In addition, some places assume that IPv4 must be initialised before IPv6. For example, mptcp_proto_v6_init() copies mptcp_prot to mptcp_v6_prot, which would otherwise have NULL mptcp_v6_prot.h.hashinfo. Let's explicitly order blackhole_netdev_init() -> inet_init() -> inet6_init() before device_initcall() with 3 different initcall levels: subsys_initcall : 4 : net_dev_init() subsys_initcall_sync : 4s : blackhole_netdev_init() fs_initcall : 5 : inet_init() fs_initcall_sync : 5s : inet6_init() device_initcall : 6 : built-in drivers Note that both IPv4 and IPv6 can still use fs_initcall() thanks to the order in net/Makefile, but explicit ordering would be less error-prone. $ cat -n net/Makefile | grep ipv 17 obj-$(CONFIG_INET) += ipv4/ 22 obj-y += ipv6/ Link: https://lore.kernel.org/netdev/20260309074758.0ea95a18@kernel.org/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Ido Schimmel Tested-by: Chris J Arges Reviewed-by: Fernando Fernandez Mancera Link: https://patch.msgid.link/20261001204752.2572265-2-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/loopback.c | 2 +- net/ipv6/af_inet6.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 1fb6ce6843ad..55ecd5ebac0f 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -289,4 +289,4 @@ static int __init blackhole_netdev_init(void) return 0; } -device_initcall(blackhole_netdev_init); +subsys_initcall_sync(blackhole_netdev_init); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index f0efdc13baf4..a9b8b4b42a1a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -1217,4 +1217,4 @@ static int __init inet6_init(void) proto_unregister(&tcpv6_prot); goto out; } -device_initcall(inet6_init); +fs_initcall_sync(inet6_init);