kexec: yield to scheduler when loading kimage segments
authorJarrett Farnitano <jmf@amazon.com>
Thu, 14 Jun 2018 22:26:31 +0000 (15:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Jun 2018 22:55:24 +0000 (07:55 +0900)
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>
kernel/kexec_core.c

index 20fef1a38602d9d0ed6fdb5d359d5604fbafc3dd..23a83a4da38a1dffc5203c828a384531b6cce9b2 100644 (file)
@@ -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;