diff options
| author | TAMUKI Shoichi <tamuki@linet.gr.jp> | 2010-08-10 18:03:28 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 08:59:22 -0700 | 
| commit | c7ff0d9c92435e836e13aaa8d0e56d4000424bcc (patch) | |
| tree | 96f56d15b5dd96c44fb183ce00152608df50dc5c /kernel/panic.c | |
| parent | bebf8cfaea1df1a104b993b995bb385e998a4dc8 (diff) | |
| download | olio-linux-3.10-c7ff0d9c92435e836e13aaa8d0e56d4000424bcc.tar.xz olio-linux-3.10-c7ff0d9c92435e836e13aaa8d0e56d4000424bcc.zip  | |
panic: keep blinking in spite of long spin timer mode
To keep panic_timeout accuracy when running under a hypervisor, the
current implementation only spins on long time (1 second) calls to mdelay.
 That brings a good effect, but the problem is the keyboard LEDs don't
blink at all on that situation.
This patch changes to call to panic_blink_enter() between every mdelay and
keeps blinking in spite of long spin timer mode.
The time to call to mdelay is now 100ms.  Even this change will keep
panic_timeout accuracy enough when running under a hypervisor.
Signed-off-by: TAMUKI Shoichi <tamuki@linet.gr.jp>
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Russell King <linux@arm.linux.org.uk>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Anton Blanchard <anton@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/panic.c')
| -rw-r--r-- | kernel/panic.c | 58 | 
1 files changed, 26 insertions, 32 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 3b16cd93fa7..3e9037ae10e 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -24,6 +24,9 @@  #include <linux/nmi.h>  #include <linux/dmi.h> +#define PANIC_TIMER_STEP 100 +#define PANIC_BLINK_SPD 18 +  int panic_on_oops;  static unsigned long tainted_mask;  static int pause_on_oops; @@ -36,36 +39,15 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);  EXPORT_SYMBOL(panic_notifier_list); -/* Returns how long it waited in ms */ -long (*panic_blink)(long time); -EXPORT_SYMBOL(panic_blink); - -static void panic_blink_one_second(void) +static long no_blink(int state)  { -	static long i = 0, end; - -	if (panic_blink) { -		end = i + MSEC_PER_SEC; - -		while (i < end) { -			i += panic_blink(i); -			mdelay(1); -			i++; -		} -	} else { -		/* -		 * When running under a hypervisor a small mdelay may get -		 * rounded up to the hypervisor timeslice. For example, with -		 * a 1ms in 10ms hypervisor timeslice we might inflate a -		 * mdelay(1) loop by 10x. -		 * -		 * If we have nothing to blink, spin on 1 second calls to -		 * mdelay to avoid this. -		 */ -		mdelay(MSEC_PER_SEC); -	} +	return 0;  } +/* Returns how long it waited in ms */ +long (*panic_blink)(int state); +EXPORT_SYMBOL(panic_blink); +  /**   *	panic - halt the system   *	@fmt: The text string to print @@ -78,7 +60,8 @@ NORET_TYPE void panic(const char * fmt, ...)  {  	static char buf[1024];  	va_list args; -	long i; +	long i, i_next = 0; +	int state = 0;  	/*  	 * It's possible to come here directly from a panic-assertion and @@ -117,6 +100,9 @@ NORET_TYPE void panic(const char * fmt, ...)  	bust_spinlocks(0); +	if (!panic_blink) +		panic_blink = no_blink; +  	if (panic_timeout > 0) {  		/*  		 * Delay timeout seconds before rebooting the machine. @@ -124,9 +110,13 @@ NORET_TYPE void panic(const char * fmt, ...)  		 */  		printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); -		for (i = 0; i < panic_timeout; i++) { +		for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) {  			touch_nmi_watchdog(); -			panic_blink_one_second(); +			if (i >= i_next) { +				i += panic_blink(state ^= 1); +				i_next = i + 3600 / PANIC_BLINK_SPD; +			} +			mdelay(PANIC_TIMER_STEP);  		}  		/*  		 * This will not be a clean reboot, with everything @@ -152,9 +142,13 @@ NORET_TYPE void panic(const char * fmt, ...)  	}  #endif  	local_irq_enable(); -	while (1) { +	for (i = 0; ; i += PANIC_TIMER_STEP) {  		touch_softlockup_watchdog(); -		panic_blink_one_second(); +		if (i >= i_next) { +			i += panic_blink(state ^= 1); +			i_next = i + 3600 / PANIC_BLINK_SPD; +		} +		mdelay(PANIC_TIMER_STEP);  	}  }  |