diff options
Diffstat (limited to 'init/initramfs.c')
-rw-r--r-- | init/initramfs.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/init/initramfs.c b/init/initramfs.c index 84c6bf111300..a9ea4066e2ef 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -18,6 +18,8 @@ #include <linux/dirent.h> #include <linux/syscalls.h> #include <linux/utime.h> +#include <linux/async.h> +#include <linux/export.h> static __initdata char *message; static void __init error(char *x) @@ -579,7 +581,15 @@ static void __init clean_rootfs(void) } #endif -static int __init populate_rootfs(void) +LIST_HEAD(populate_rootfs_domain); + +void populate_rootfs_wait(void) +{ + async_synchronize_full_domain(&populate_rootfs_domain); +} +EXPORT_SYMBOL(populate_rootfs_wait); + +static void __init async_populate_rootfs(void *data, async_cookie_t cookie) { char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); if (err) @@ -592,7 +602,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); @@ -616,6 +626,27 @@ static int __init populate_rootfs(void) free_initrd(); #endif } + return; +} + +static int __initdata rootfs_populated; + +static int __init populate_rootfs_early(void) +{ + if (num_online_cpus() > 1) { + rootfs_populated = 1; + async_schedule_domain(async_populate_rootfs, NULL, + &populate_rootfs_domain); + } + return 0; +} +static int __init populate_rootfs(void) +{ + if (!rootfs_populated) + async_schedule_domain(async_populate_rootfs, NULL, + &populate_rootfs_domain); return 0; } + +earlyrootfs_initcall(populate_rootfs_early); rootfs_initcall(populate_rootfs); |