Skip to content

Commit bb813f4

Browse files
committed
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 <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Arjan van de Ven <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Alex Riesen <[email protected]> Cc: Fengguang We <[email protected]>
1 parent 84b233a commit bb813f4

File tree

6 files changed

+48
-1
lines changed

6 files changed

+48
-1
lines changed

block/elevator.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,22 @@ static int __init elevator_setup(char *str)
136136

137137
__setup("elevator=", elevator_setup);
138138

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+
139155
static struct kobj_type elv_ktype;
140156

141157
static struct elevator_queue *elevator_alloc(struct request_queue *q,

include/linux/elevator.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ extern void elv_drain_elevator(struct request_queue *);
138138
/*
139139
* io scheduler registration
140140
*/
141+
extern void __init load_default_elevator_module(void);
141142
extern int elv_register(struct elevator_type *);
142143
extern void elv_unregister(struct elevator_type *);
143144

@@ -206,5 +207,9 @@ enum {
206207
INIT_LIST_HEAD(&(rq)->csd.list); \
207208
} while (0)
208209

210+
#else /* CONFIG_BLOCK */
211+
212+
static inline void load_default_elevator_module(void) { }
213+
209214
#endif /* CONFIG_BLOCK */
210215
#endif

include/linux/init.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ extern unsigned int reset_devices;
161161
/* used by init/main.c */
162162
void setup_arch(char **);
163163
void prepare_namespace(void);
164+
void __init load_default_modules(void);
164165

165166
extern void (*late_time_init)(void);
166167

init/do_mounts_initrd.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ static void __init handle_initrd(void)
5757
sys_mkdir("/old", 0700);
5858
sys_chdir("/old");
5959

60+
/* try loading default modules from initrd */
61+
load_default_modules();
62+
6063
/*
6164
* In case that a resume from disk is carried out by linuxrc or one of
6265
* its children, we need to tell the freezer not to wait for us.

init/initramfs.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ static int __init populate_rootfs(void)
592592
initrd_end - initrd_start);
593593
if (!err) {
594594
free_initrd();
595-
return 0;
595+
goto done;
596596
} else {
597597
clean_rootfs();
598598
unpack_to_rootfs(__initramfs_start, __initramfs_size);
@@ -607,6 +607,7 @@ static int __init populate_rootfs(void)
607607
sys_close(fd);
608608
free_initrd();
609609
}
610+
done:
610611
#else
611612
printk(KERN_INFO "Unpacking initramfs...\n");
612613
err = unpack_to_rootfs((char *)initrd_start,
@@ -615,6 +616,11 @@ static int __init populate_rootfs(void)
615616
printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
616617
free_initrd();
617618
#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();
618624
}
619625
return 0;
620626
}

init/main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
#include <linux/perf_event.h>
7171
#include <linux/file.h>
7272
#include <linux/ptrace.h>
73+
#include <linux/blkdev.h>
74+
#include <linux/elevator.h>
7375

7476
#include <asm/io.h>
7577
#include <asm/bugs.h>
@@ -794,6 +796,17 @@ static void __init do_pre_smp_initcalls(void)
794796
do_one_initcall(*fn);
795797
}
796798

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+
797810
static int run_init_process(const char *init_filename)
798811
{
799812
argv_init[0] = init_filename;
@@ -898,4 +911,7 @@ static void __init kernel_init_freeable(void)
898911
* we're essentially up and running. Get rid of the
899912
* initmem segments and start the user-mode stuff..
900913
*/
914+
915+
/* rootfs is available now, try loading default modules */
916+
load_default_modules();
901917
}

0 commit comments

Comments
 (0)