Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Fix blocking allocations called very early during bootup

During early boot, when the scheduler hasn't really been fully set up,
we really can't do blocking allocations because with certain (dubious)
configurations the "might_resched()" calls can actually result in
scheduling events.

We could just make such users always use GFP_ATOMIC, but quite often the
code that does the allocation isn't really aware of the fact that the
scheduler isn't up yet, and forcing that kind of random knowledge on the
initialization code is just annoying and not good for anybody.

And we actually have a the 'gfp_allowed_mask' exactly for this reason:
it's just that the kernel init sequence happens to set it to allow
blocking allocations much too early.

So move the 'gfp_allowed_mask' initialization from 'start_kernel()'
(which is some of the earliest init code, and runs with preemption
disabled for good reasons) into 'kernel_init()'. kernel_init() is run
in the newly created thread that will become the 'init' process, as
opposed to the early startup code that runs within the context of what
will be the first idle thread.

So by the time we reach 'kernel_init()', we know that the scheduler must
be at least limping along, because we've already scheduled from the idle
thread into the init thread.

Reported-by: Steven Rostedt <rostedt@goodmis.org>
Cc: David Rientjes <rientjes@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+4 -3
+4 -3
init/main.c
··· 560 560 early_boot_irqs_disabled = false; 561 561 local_irq_enable(); 562 562 563 - /* Interrupts are enabled now so all GFP allocations are safe. */ 564 - gfp_allowed_mask = __GFP_BITS_MASK; 565 - 566 563 kmem_cache_init_late(); 567 564 568 565 /* ··· 839 842 * Wait until kthreadd is all set-up. 840 843 */ 841 844 wait_for_completion(&kthreadd_done); 845 + 846 + /* Now the scheduler is fully set up and can do blocking allocations */ 847 + gfp_allowed_mask = __GFP_BITS_MASK; 848 + 842 849 /* 843 850 * init can allocate pages on any node 844 851 */