linux/drivers/base
Rasmus Villemoes e7cb072eb9 init/initramfs.c: do unpacking asynchronously
Patch series "background initramfs unpacking, and CONFIG_MODPROBE_PATH", v3.

These two patches are independent, but better-together.

The second is a rather trivial patch that simply allows the developer to
change "/sbin/modprobe" to something else - e.g.  the empty string, so
that all request_module() during early boot return -ENOENT early, without
even spawning a usermode helper, needlessly synchronizing with the
initramfs unpacking.

The first patch delegates decompressing the initramfs to a worker thread,
allowing do_initcalls() in main.c to proceed to the device_ and late_
initcalls without waiting for that decompression (and populating of
rootfs) to finish.  Obviously, some of those later calls may rely on the
initramfs being available, so I've added synchronization points in the
firmware loader and usermodehelper paths - there might be other places
that would need this, but so far no one has been able to think of any
places I have missed.

There's not much to win if most of the functionality needed during boot is
only available as modules.  But systems with a custom-made .config and
initramfs can boot faster, partly due to utilizing more than one cpu
earlier, partly by avoiding known-futile modprobe calls (which would still
trigger synchronization with the initramfs unpacking, thus eliminating
most of the first benefit).

This patch (of 2):

Most of the boot process doesn't actually need anything from the
initramfs, until of course PID1 is to be executed.  So instead of doing
the decompressing and populating of the initramfs synchronously in
populate_rootfs() itself, push that off to a worker thread.

This is primarily motivated by an embedded ppc target, where unpacking
even the rather modest sized initramfs takes 0.6 seconds, which is long
enough that the external watchdog becomes unhappy that it doesn't get
attention soon enough.  By doing the initramfs decompression in a worker
thread, we get to do the device_initcalls and hence start petting the
watchdog much sooner.

Normal desktops might benefit as well.  On my mostly stock Ubuntu kernel,
my initramfs is a 26M xz-compressed blob, decompressing to around 126M.
That takes almost two seconds:

[    0.201454] Trying to unpack rootfs image as initramfs...
[    1.976633] Freeing initrd memory: 29416K

Before this patch, these lines occur consecutively in dmesg.  With this
patch, the timestamps on these two lines is roughly the same as above, but
with 172 lines inbetween - so more than one cpu has been kept busy doing
work that would otherwise only happen after the populate_rootfs()
finished.

Should one of the initcalls done after rootfs_initcall time (i.e., device_
and late_ initcalls) need something from the initramfs (say, a kernel
module or a firmware blob), it will simply wait for the initramfs
unpacking to be done before proceeding, which should in theory make this
completely safe.

But if some driver pokes around in the filesystem directly and not via one
of the official kernel interfaces (i.e.  request_firmware*(),
call_usermodehelper*) that theory may not hold - also, I certainly might
have missed a spot when sprinkling wait_for_initramfs().  So there is an
escape hatch in the form of an initramfs_async= command line parameter.

Link: https://lkml.kernel.org/r/20210313212528.2956377-1-linux@rasmusvillemoes.dk
Link: https://lkml.kernel.org/r/20210313212528.2956377-2-linux@rasmusvillemoes.dk
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-05-07 00:26:33 -07:00
..
firmware_loader init/initramfs.c: do unpacking asynchronously 2021-05-07 00:26:33 -07:00
power Merge branches 'pm-docs' and 'pm-tools' 2021-04-26 17:00:14 +02:00
regmap regmap-irq: Fix dereference of a potentially null d->virt_buf 2021-04-07 16:58:33 +01:00
test kunit: software node: adhear to KUNIT formatting standard 2021-04-15 08:56:27 +02:00
Kconfig RISC-V Patches for the 5.12 Merge Window 2021-02-26 10:28:35 -08:00
Makefile numa: Move numa implementation to common code 2021-01-14 15:08:55 -08:00
arch_numa.c arch_numa: fix common code printing of phys_addr_t 2021-02-18 23:18:04 -08:00
arch_topology.c arch_topology: Export arch_freq_scale and helpers 2021-03-12 10:35:57 +05:30
attribute_container.c driver core: attribute_container: remove kernel-doc warnings 2021-04-02 16:40:07 +02:00
auxiliary.c driver core: auxiliary bus: Remove unneeded module bits 2021-03-23 10:47:55 +01:00
base.h driver core: Improve fw_devlink & deferred_probe_timeout interaction 2021-04-05 09:17:56 +02:00
bus.c drivers: base: change 'driver_create_groups' to 'driver_add_groups' in printk 2021-01-27 14:35:09 +01:00
cacheinfo.c drivers core: Use sysfs_emit for shared_cpu_map_show and shared_cpu_list_show 2020-10-02 13:24:40 +02:00
class.c drivers: base: fix some kernel-doc markups 2020-11-09 18:56:49 +01:00
component.c driver core: component: remove dentry pointer in "struct master" 2021-03-23 10:49:02 +01:00
container.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
core.c driver core: Improve fw_devlink & deferred_probe_timeout interaction 2021-04-05 09:17:56 +02:00
cpu.c drivers/base/cpu: remove redundant assignment of variable retval 2021-03-23 14:56:50 +01:00
dd.c Linux 5.12-rc7 2021-04-14 19:53:39 +02:00
devcoredump.c devcoredump: fix kernel-doc warning 2021-04-02 16:40:08 +02:00
devres.c driver core: Replace printf() specifier and drop unneeded casting 2021-04-02 17:02:45 +02:00
devtmpfs.c devtmpfs: actually reclaim some init memory 2021-03-23 14:57:35 +01:00
driver.c drivers: base: Convert to printk alias functions 2020-07-10 14:16:44 +02:00
firmware.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
hypervisor.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
init.c driver core: auxiliary bus: Fix calling stage for auxiliary bus init 2021-02-11 08:43:03 +01:00
isa.c isa: Make the remove callback for isa drivers return void 2021-01-26 07:42:27 +01:00
map.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
memory.c mm,memory_hotplug: allocate memmap from the added memory range 2021-05-05 11:27:26 -07:00
module.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
node.c node: fix device cleanups in error handling code 2021-04-10 11:10:21 +02:00
pinctrl.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
platform-msi.c platform-msi: fix kernel-doc warnings 2021-04-02 16:40:08 +02:00
platform.c Revert "driver core: platform: Make platform_get_irq_optional() optional" 2021-04-07 11:47:56 +02:00
property.c media: device property: Call fwnode_graph_get_endpoint_by_id() for fwnode->secondary 2021-01-26 19:24:18 +01:00
soc.c soc: fix comment for freeing soc_dev_attr 2020-12-09 19:46:31 +01:00
swnode.c software node: Allow node addition to already existing device 2021-04-15 10:36:07 +02:00
syscore.c syscore: Use pm_pr_dbg() for syscore_{suspend,resume}() 2020-09-08 13:32:06 +02:00
topology.c drivers core: Miscellaneous changes for sysfs_emit 2020-10-02 13:12:07 +02:00
transport_class.c scsi: drivers: base: Propagate errors through the transport component 2020-01-15 22:55:37 -05:00