mm: migrate: change to use bool type for 'page_was_mapped'
[linux-2.6-microblaze.git] / init / initramfs.c
index d677e8e..a842c05 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/init.h>
+#include <linux/async.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -14,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/namei.h>
 #include <linux/init_syscalls.h>
+#include <linux/umh.h>
 
 static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
                loff_t *pos)
@@ -541,6 +543,14 @@ static int __init keepinitrd_setup(char *__unused)
 __setup("keepinitrd", keepinitrd_setup);
 #endif
 
+static bool __initdata initramfs_async = true;
+static int __init initramfs_async_setup(char *str)
+{
+       strtobool(str, &initramfs_async);
+       return 1;
+}
+__setup("initramfs_async=", initramfs_async_setup);
+
 extern char __initramfs_start[];
 extern unsigned long __initramfs_size;
 #include <linux/initrd.h>
@@ -658,7 +668,7 @@ static void __init populate_initrd_image(char *err)
 }
 #endif /* CONFIG_BLK_DEV_RAM */
 
-static int __init populate_rootfs(void)
+static void __init do_populate_rootfs(void *unused, async_cookie_t cookie)
 {
        /* Load the built in initramfs */
        char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
@@ -693,6 +703,34 @@ done:
        initrd_end = 0;
 
        flush_delayed_fput();
+}
+
+static ASYNC_DOMAIN_EXCLUSIVE(initramfs_domain);
+static async_cookie_t initramfs_cookie;
+
+void wait_for_initramfs(void)
+{
+       if (!initramfs_cookie) {
+               /*
+                * Something before rootfs_initcall wants to access
+                * the filesystem/initramfs. Probably a bug. Make a
+                * note, avoid deadlocking the machine, and let the
+                * caller's access fail as it used to.
+                */
+               pr_warn_once("wait_for_initramfs() called before rootfs_initcalls\n");
+               return;
+       }
+       async_synchronize_cookie_domain(initramfs_cookie + 1, &initramfs_domain);
+}
+EXPORT_SYMBOL_GPL(wait_for_initramfs);
+
+static int __init populate_rootfs(void)
+{
+       initramfs_cookie = async_schedule_domain(do_populate_rootfs, NULL,
+                                                &initramfs_domain);
+       usermodehelper_enable();
+       if (!initramfs_async)
+               wait_for_initramfs();
        return 0;
 }
 rootfs_initcall(populate_rootfs);