diff mbox series

[v2] initramfs-framework: add opt-in root-only udev trigger

Message ID 20260818101737.4010605-1-wenwfu@qti.qualcomm.com
State New
Headers show
Series [v2] initramfs-framework: add opt-in root-only udev trigger | expand

Commit Message

Wenwen Fu Aug. 18, 2026, 10:17 a.m. UTC
The initramfs udev module replays add events for the complete device
tree and waits for every resulting event. This can significantly delay
mounting the root filesystem when unrelated devices take time to
initialize.

On a Qualcomm RB3 Gen 2 Core Kit (MACHINE=rb3gen2-core-kit) running
Linux 6.18, using initramfs-rootfs-image with root=PARTLABEL=rootfs,
the following average times were measured:

                              Full coldplug    Root-only
udev trigger + settle           981.6 ms        109.8 ms
/init to rootfs EXT4 mount     1340.2 ms        441.1 ms

The root-only trigger reduced these times by 88.8% and 67.1%,
respectively. The values are averages of three full-coldplug boots and
two root-only boots.

Add the opt-in initramfs.udev-root-only=1 kernel parameter. When root
uses PARTLABEL or PARTUUID, trigger only the matching block device. For
PARTLABEL roots, match the PARTNAME property exposed by udev.

Keep the existing full trigger as the default so current users and
other initramfs modules retain their existing behaviour. If the root
device cannot be matched safely or the targeted trigger fails, fall
back to the original full coldplug.

Signed-off-by: Wenwen Fu <wenwfu@qti.qualcomm.com>
---
Changes in v2:
- Explain the boot-time motivation and include performance measurements.
- Clarify that initramfs.udev-root-only=1 enables the optimization.
- Make targeted-trigger error handling explicit.
---
 .../initrdscripts/initramfs-framework/udev    | 32 ++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/udev b/meta/recipes-core/initrdscripts/initramfs-framework/udev
index 4898b89246..8f67e78a7c 100644
--- a/meta/recipes-core/initrdscripts/initramfs-framework/udev
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/udev
@@ -35,6 +35,31 @@  udev_enabled() {
 	return 0
 }
 
+udev_trigger_root_device() {
+	case "${bootparam_root:-}" in
+		PARTLABEL=?*)
+			root_match="PARTNAME=${bootparam_root#PARTLABEL=}"
+			;;
+		PARTUUID=?*)
+			root_match="PARTUUID=${bootparam_root#PARTUUID=}"
+			;;
+		*)
+			return 1
+			;;
+	esac
+
+	root_devices=$(udevadm trigger --dry-run --verbose \
+		--subsystem-match=block "--property-match=$root_match") || return 1
+
+	# udevadm succeeds even when no devices match, so check its dry-run output.
+	[ -n "$root_devices" ] || return 1
+
+	udevadm trigger --subsystem-match=block \
+		"--property-match=$root_match" --action=add || return 1
+
+	return 0
+}
+
 udev_run() {
 	add_module_pre_hook "udev_shutdown_hook_handler"
 
@@ -45,6 +70,11 @@  udev_run() {
 	sh -c "exec 4< /dev/console" || { exec 0> /dev/null; exec 1> /dev/null; exec 2> /dev/null; }
 
 	$_UDEV_DAEMON --daemon
-	udevadm trigger --action=add
+	if [ "${bootparam_initramfs_udev_root_only:-}" = "1" ] &&
+	   udev_trigger_root_device; then
+		debug "Triggered udev for root partition only"
+	else
+		udevadm trigger --action=add
+	fi
 	udevadm settle
 }