Commit d5767c53 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

bootup: move 'usermodehelper_enable()' to the end of do_basic_setup()

Doing it just before starting to call into cpu_idle() made a sick kind
of sense only because the original bug we fixed (see commit
288d5abe: "Boot up with usermodehelper disabled") was about problems
with some scheduler data structures not being initialized, and they had
better be initialized at that point.

But it really didn't make any other conceptual sense, and doing it after
the initial "schedule()" call for the idle thread actually opened up a
race: what if the main initialization thread did everything without
needing to sleep, and got all the way into user land too? Without
actually having scheduled back to the idle thread?

Now, in normal circumstances that doesn't ever happen, but it looks like
Richard Cochran triggered exactly that on his ARM IXP4xx machines:

  "I have some ARM IXP4xx based machines that use the two on chip MAC
   ports (aka NPEs).  The NPE needs a firmware in order to function.
   Ever since the following commit [that 288d5abe

 one], it is no
   longer possible to bring up the interfaces during the init scripts."

with a call trace showing an ioctl coming from user space. Richard says:

  "The init is busybox, and the startup script does mount, syslogd, and
   then ifup, so that all can go by quickly."

The fix is to move the usermodehelper_enable() into the main 'init'
thread, and just put it after we've done all our initcalls.  By then,
everything really should be up, but we've obviously not actually started
the user-mode portion of init yet.
Reported-and-tested-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2ef7b45a
......@@ -381,9 +381,6 @@ static noinline void __init_refok rest_init(void)
preempt_enable_no_resched();
schedule();
/* At this point, we can enable user mode helper functionality */
usermodehelper_enable();
/* Call into cpu_idle with preempt disabled */
preempt_disable();
cpu_idle();
......@@ -734,6 +731,7 @@ static void __init do_basic_setup(void)
init_irq_proc();
do_ctors();
do_initcalls();
usermodehelper_enable();
}
static void __init do_pre_smp_initcalls(void)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment