diff options
author | Jarrett Farnitano <jmf@amazon.com> | 2018-06-15 00:26:31 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-15 00:55:24 +0200 |
commit | a8311f647e419675f6ecba9f4284080fd38a0a37 (patch) | |
tree | 0b9ce3245f1b4d06dfc0b1cb695262f3111740db /kernel/kexec_core.c | |
parent | mm: fix race between kmem_cache destroy, create and deactivate (diff) | |
download | linux-a8311f647e419675f6ecba9f4284080fd38a0a37.tar.xz linux-a8311f647e419675f6ecba9f4284080fd38a0a37.zip |
kexec: yield to scheduler when loading kimage segments
Without yielding while loading kimage segments, a large initrd will
block all other work on the CPU performing the load until it is
completed. For example loading an initrd of 200MB on a low power single
core system will lock up the system for a few seconds.
To increase system responsiveness to other tasks at that time, call
cond_resched() in both the crash kernel and normal kernel segment
loading loops.
I did run into a practical problem. Hardware watchdogs on embedded
systems can have short timers on the order of seconds. If the system is
locked up for a few seconds with only a single core available, the
watchdog may not be pet in a timely fashion. If this happens, the
hardware watchdog will fire and reset the system.
This really only becomes a problem when you are working with a single
core, a decently sized initrd, and have a constrained hardware watchdog.
Link: http://lkml.kernel.org/r/1528738546-3328-1-git-send-email-jmf@amazon.com
Signed-off-by: Jarrett Farnitano <jmf@amazon.com>
Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kexec_core.c')
-rw-r--r-- | kernel/kexec_core.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 20fef1a38602..23a83a4da38a 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -829,6 +829,8 @@ static int kimage_load_normal_segment(struct kimage *image, else buf += mchunk; mbytes -= mchunk; + + cond_resched(); } out: return result; @@ -893,6 +895,8 @@ static int kimage_load_crash_segment(struct kimage *image, else buf += mchunk; mbytes -= mchunk; + + cond_resched(); } out: return result; |