]> git.karo-electronics.de Git - linux-beck.git/commitdiff
init, block: try to load default elevator module early during boot
authorTejun Heo <tj@kernel.org>
Fri, 18 Jan 2013 22:05:56 +0000 (14:05 -0800)
committerTejun Heo <tj@kernel.org>
Fri, 18 Jan 2013 22:05:56 +0000 (14:05 -0800)
This patch adds default module loading and uses it to load the default
block elevator.  During boot, it's called right after initramfs or
initrd is made available and right before control is passed to
userland.  This ensures that as long as the modules are available in
the usual places in initramfs, initrd or the root filesystem, the
default modules are loaded as soon as possible.

This will replace the on-demand elevator module loading from elevator
init path.

v2: Fixed build breakage when !CONFIG_BLOCK.  Reported by kbuild test
    robot.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Alex Riesen <raa.lkml@gmail.com>
Cc: Fengguang We <fengguang.wu@intel.com>
block/elevator.c
include/linux/elevator.h
include/linux/init.h
init/do_mounts_initrd.c
init/initramfs.c
init/main.c

index 9edba1b8323ed713f17f475511a370d2cdd8df47..c2d61d56e0b7dc751bd629477bb4c092525841f7 100644 (file)
@@ -136,6 +136,22 @@ static int __init elevator_setup(char *str)
 
 __setup("elevator=", elevator_setup);
 
+/* called during boot to load the elevator chosen by the elevator param */
+void __init load_default_elevator_module(void)
+{
+       struct elevator_type *e;
+
+       if (!chosen_elevator[0])
+               return;
+
+       spin_lock(&elv_list_lock);
+       e = elevator_find(chosen_elevator);
+       spin_unlock(&elv_list_lock);
+
+       if (!e)
+               request_module("%s-iosched", chosen_elevator);
+}
+
 static struct kobj_type elv_ktype;
 
 static struct elevator_queue *elevator_alloc(struct request_queue *q,
index c03af7687bb4fdd916d5bf3c835e801376132392..18662063175044e4641610799d48422e3cd583f0 100644 (file)
@@ -138,6 +138,7 @@ extern void elv_drain_elevator(struct request_queue *);
 /*
  * io scheduler registration
  */
+extern void __init load_default_elevator_module(void);
 extern int elv_register(struct elevator_type *);
 extern void elv_unregister(struct elevator_type *);
 
@@ -206,5 +207,9 @@ enum {
        INIT_LIST_HEAD(&(rq)->csd.list);        \
        } while (0)
 
+#else /* CONFIG_BLOCK */
+
+static inline void load_default_elevator_module(void) { }
+
 #endif /* CONFIG_BLOCK */
 #endif
index a799273714accff40c0bf54850389b095746ff83..9230c9408d8b6387aa784e49efc4b76d7551894e 100644 (file)
@@ -161,6 +161,7 @@ extern unsigned int reset_devices;
 /* used by init/main.c */
 void setup_arch(char **);
 void prepare_namespace(void);
+void __init load_default_modules(void);
 
 extern void (*late_time_init)(void);
 
index 5e4ded51788eb81f277c0b5674f5602730220df4..dfe606a7dd61abbdc289cb87bf5e8631b31a2e3f 100644 (file)
@@ -57,6 +57,9 @@ static void __init handle_initrd(void)
        sys_mkdir("/old", 0700);
        sys_chdir("/old");
 
+       /* try loading default modules from initrd */
+       load_default_modules();
+
        /*
         * In case that a resume from disk is carried out by linuxrc or one of
         * its children, we need to tell the freezer not to wait for us.
index 84c6bf111300878a095a9fb3f8f91678dbe10b65..a67ef9dbda9dae0ea7a1619a393c55157a6d8592 100644 (file)
@@ -592,7 +592,7 @@ static int __init populate_rootfs(void)
                        initrd_end - initrd_start);
                if (!err) {
                        free_initrd();
-                       return 0;
+                       goto done;
                } else {
                        clean_rootfs();
                        unpack_to_rootfs(__initramfs_start, __initramfs_size);
@@ -607,6 +607,7 @@ static int __init populate_rootfs(void)
                        sys_close(fd);
                        free_initrd();
                }
+       done:
 #else
                printk(KERN_INFO "Unpacking initramfs...\n");
                err = unpack_to_rootfs((char *)initrd_start,
@@ -615,6 +616,11 @@ static int __init populate_rootfs(void)
                        printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
                free_initrd();
 #endif
+               /*
+                * Try loading default modules from initramfs.  This gives
+                * us a chance to load before device_initcalls.
+                */
+               load_default_modules();
        }
        return 0;
 }
index baf1f0f5c4611eb08b3f0eae7995c5d789f8e741..18efadb11cf6c962ee639965ef66ea07e782a881 100644 (file)
@@ -70,6 +70,8 @@
 #include <linux/perf_event.h>
 #include <linux/file.h>
 #include <linux/ptrace.h>
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -794,6 +796,17 @@ static void __init do_pre_smp_initcalls(void)
                do_one_initcall(*fn);
 }
 
+/*
+ * This function requests modules which should be loaded by default and is
+ * called twice right after initrd is mounted and right before init is
+ * exec'd.  If such modules are on either initrd or rootfs, they will be
+ * loaded before control is passed to userland.
+ */
+void __init load_default_modules(void)
+{
+       load_default_elevator_module();
+}
+
 static int run_init_process(const char *init_filename)
 {
        argv_init[0] = init_filename;
@@ -898,4 +911,7 @@ static void __init kernel_init_freeable(void)
         * we're essentially up and running. Get rid of the
         * initmem segments and start the user-mode stuff..
         */
+
+       /* rootfs is available now, try loading default modules */
+       load_default_modules();
 }