Commit bb813f4c933ae9f887a014483690d5f8b8ec05e1
1 parent
84b233adcc
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
block/elevator.c
... | ... | @@ -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
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. |
init/initramfs.c
... | ... | @@ -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 | } |
init/main.c
... | ... | @@ -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 | } |