summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJarrett Farnitano <jmf@amazon.com>2018-06-15 00:26:31 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-15 00:55:24 +0200
commita8311f647e419675f6ecba9f4284080fd38a0a37 (patch)
tree0b9ce3245f1b4d06dfc0b1cb695262f3111740db /kernel
parentmm: fix race between kmem_cache destroy, create and deactivate (diff)
downloadlinux-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')
-rw-r--r--kernel/kexec_core.c4
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;