aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorSurbhi Palande <surbhi.palande@canonical.com>2009-12-08 11:44:34 +0200
committerJohn Rigby <john.rigby@linaro.org>2012-06-20 20:13:56 -0600
commit26c61c2ffb3bd32be2c2fa238604190bfdc1d07d (patch)
treeebef05263a90e604837170155da319c540dd8556 /init
parent783eff31da54c50c8dc2619e213f14d47ed3eb5f (diff)
UBUNTU: SAUCE: Make populate_rootfs asynchronous
The expansion of the initramfs is completely independant of other boot activities. The original data is already present at boot and the filesystem is not required until we are ready to start init. It is therefore reasonable to populate the rootfs asynchronously. Move this processing to an async call. This reduces kernel initialisation time (the time from bootloader to starting userspace) by several 10ths of a second on a selection of test hardware particularly SMP systems, although UP system also benefit. Signed-off-by: Surbhi Palande <surbhi.palande@canonical.com> Signed-off-by: Andy Whitcroft <apw@canonical.com>
Diffstat (limited to 'init')
-rw-r--r--init/initramfs.c15
-rw-r--r--init/main.c6
2 files changed, 18 insertions, 3 deletions
diff --git a/init/initramfs.c b/init/initramfs.c
index 8216c303b08..39dbed3ad9c 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -8,6 +8,7 @@
#include <linux/dirent.h>
#include <linux/syscalls.h>
#include <linux/utime.h>
+#include <linux/async.h>
static __initdata char *message;
static void __init error(char *x)
@@ -569,7 +570,9 @@ static void __init clean_rootfs(void)
}
#endif
-static int __init populate_rootfs(void)
+LIST_HEAD(populate_rootfs_domain);
+
+static void __init async_populate_rootfs(void)
{
char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
if (err)
@@ -582,7 +585,7 @@ static int __init populate_rootfs(void)
initrd_end - initrd_start);
if (!err) {
free_initrd();
- return 0;
+ return;
} else {
clean_rootfs();
unpack_to_rootfs(__initramfs_start, __initramfs_size);
@@ -606,6 +609,12 @@ static int __init populate_rootfs(void)
free_initrd();
#endif
}
- return 0;
+ return;
}
+
+static int __init populate_rootfs(void)
+{
+ async_schedule_domain(async_populate_rootfs, NULL, &populate_rootfs_domain);
+}
+
rootfs_initcall(populate_rootfs);
diff --git a/init/main.c b/init/main.c
index c62d6119a37..de1c75fd5a9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -870,6 +870,12 @@ static int __init kernel_init(void * unused)
(void) sys_dup(0);
(void) sys_dup(0);
/*
+ * We need to ensure that the filesystem is ready by this point, wait for
+ * async_populate_rootfs to complete.
+ */
+ async_synchronize_full_domain(&populate_rootfs_domain);
+
+ /*
* check if there is an early userspace init. If yes, let it do all
* the work
*/