Skip to content

Commit

Permalink
init, block: try to load default elevator module early during boot
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
htejun committed Jan 18, 2013
1 parent 84b233a commit bb813f4
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 1 deletion.
16 changes: 16 additions & 0 deletions block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions include/linux/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions init/do_mounts_initrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 7 additions & 1 deletion init/initramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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;
}
Expand Down
16 changes: 16 additions & 0 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

0 comments on commit bb813f4

Please sign in to comment.