From: Jason U. <jas...@sg...> - 2005-04-14 23:06:49
|
If a task other than the one doing the dump calls schedule(), it's forced to spin until the dump is complete and then return, which is wrong if it's a zombie which was calling schedule() to switch itself out for the last time. In that case we'll return back into do_exit() and hit the BUG() near the bottom. The fix is to spin until the dump is complete and then continue normal processing of schedule() rather than just returning. This is only a problem for nondisruptive dumps. In the disruptive case, the dumping cpu will reset the machine without ever clearing dump_oncpu, so the non-dumping tasks will never leave schedule(). Index: linux/kernel/sched.c =================================================================== --- linux.orig/kernel/sched.c 2005-04-14 15:02:34.145213372 -0700 +++ linux/kernel/sched.c 2005-04-14 15:04:11.505402921 -0700 @@ -2437,14 +2437,18 @@ unsigned long run_time; int cpu, idx; - /* - * If crash dump is in progress, this other cpu's - * need to wait until it completes. - * NB: this code is optimized away for kernels without - * dumping enabled. + /* + * If a crash dump is in progress, schedule() + * is a no-op for the dumping cpu, and all + * other cpus are forced to wait until the dump + * completes. */ if (unlikely(dump_oncpu)) - goto dump_scheduling_disabled; + if (dump_oncpu == smp_processor_id()+1) + return; + else + while (dump_oncpu) + cpu_relax(); /* * Test if we are atomic. Since do_exit() needs to call into @@ -2611,14 +2615,6 @@ goto need_resched; return; - - dump_scheduling_disabled: - /* allow scheduling only if this is the dumping cpu */ - if (dump_oncpu != smp_processor_id()+1) { - while (dump_oncpu) - cpu_relax(); - } - return; } EXPORT_SYMBOL(schedule); |