Commit bb813f4c933ae9f887a014483690d5f8b8ec05e1

Authored by Tejun Heo
1 parent 84b233adcc

init, block: try to load default elevator module early during boot

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>

Showing 6 changed files with 48 additions and 1 deletions Side-by-side Diff

... ... @@ -136,6 +136,22 @@
136 136  
137 137 __setup("elevator=", elevator_setup);
138 138  
  139 +/* called during boot to load the elevator chosen by the elevator param */
  140 +void __init load_default_elevator_module(void)
  141 +{
  142 + struct elevator_type *e;
  143 +
  144 + if (!chosen_elevator[0])
  145 + return;
  146 +
  147 + spin_lock(&elv_list_lock);
  148 + e = elevator_find(chosen_elevator);
  149 + spin_unlock(&elv_list_lock);
  150 +
  151 + if (!e)
  152 + request_module("%s-iosched", chosen_elevator);
  153 +}
  154 +
139 155 static struct kobj_type elv_ktype;
140 156  
141 157 static struct elevator_queue *elevator_alloc(struct request_queue *q,
include/linux/elevator.h
... ... @@ -138,6 +138,7 @@
138 138 /*
139 139 * io scheduler registration
140 140 */
  141 +extern void __init load_default_elevator_module(void);
141 142 extern int elv_register(struct elevator_type *);
142 143 extern void elv_unregister(struct elevator_type *);
143 144  
... ... @@ -205,6 +206,10 @@
205 206 list_del_init(&(rq)->queuelist); \
206 207 INIT_LIST_HEAD(&(rq)->csd.list); \
207 208 } while (0)
  209 +
  210 +#else /* CONFIG_BLOCK */
  211 +
  212 +static inline void load_default_elevator_module(void) { }
208 213  
209 214 #endif /* CONFIG_BLOCK */
210 215 #endif
include/linux/init.h
... ... @@ -161,6 +161,7 @@
161 161 /* used by init/main.c */
162 162 void setup_arch(char **);
163 163 void prepare_namespace(void);
  164 +void __init load_default_modules(void);
164 165  
165 166 extern void (*late_time_init)(void);
166 167  
init/do_mounts_initrd.c
... ... @@ -57,6 +57,9 @@
57 57 sys_mkdir("/old", 0700);
58 58 sys_chdir("/old");
59 59  
  60 + /* try loading default modules from initrd */
  61 + load_default_modules();
  62 +
60 63 /*
61 64 * In case that a resume from disk is carried out by linuxrc or one of
62 65 * its children, we need to tell the freezer not to wait for us.
... ... @@ -592,7 +592,7 @@
592 592 initrd_end - initrd_start);
593 593 if (!err) {
594 594 free_initrd();
595   - return 0;
  595 + goto done;
596 596 } else {
597 597 clean_rootfs();
598 598 unpack_to_rootfs(__initramfs_start, __initramfs_size);
... ... @@ -607,6 +607,7 @@
607 607 sys_close(fd);
608 608 free_initrd();
609 609 }
  610 + done:
610 611 #else
611 612 printk(KERN_INFO "Unpacking initramfs...\n");
612 613 err = unpack_to_rootfs((char *)initrd_start,
... ... @@ -615,6 +616,11 @@
615 616 printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
616 617 free_initrd();
617 618 #endif
  619 + /*
  620 + * Try loading default modules from initramfs. This gives
  621 + * us a chance to load before device_initcalls.
  622 + */
  623 + load_default_modules();
618 624 }
619 625 return 0;
620 626 }
... ... @@ -70,6 +70,8 @@
70 70 #include <linux/perf_event.h>
71 71 #include <linux/file.h>
72 72 #include <linux/ptrace.h>
  73 +#include <linux/blkdev.h>
  74 +#include <linux/elevator.h>
73 75  
74 76 #include <asm/io.h>
75 77 #include <asm/bugs.h>
... ... @@ -794,6 +796,17 @@
794 796 do_one_initcall(*fn);
795 797 }
796 798  
  799 +/*
  800 + * This function requests modules which should be loaded by default and is
  801 + * called twice right after initrd is mounted and right before init is
  802 + * exec'd. If such modules are on either initrd or rootfs, they will be
  803 + * loaded before control is passed to userland.
  804 + */
  805 +void __init load_default_modules(void)
  806 +{
  807 + load_default_elevator_module();
  808 +}
  809 +
797 810 static int run_init_process(const char *init_filename)
798 811 {
799 812 argv_init[0] = init_filename;
... ... @@ -898,5 +911,8 @@
898 911 * we're essentially up and running. Get rid of the
899 912 * initmem segments and start the user-mode stuff..
900 913 */
  914 +
  915 + /* rootfs is available now, try loading default modules */
  916 + load_default_modules();
901 917 }