mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	softlock: fix false panic which can occur if softlockup_thresh is reduced
At run-time, if softlockup_thresh is changed to a much lower value, touch_timestamp is likely to be much older than the new softlock_thresh. This will cause a false softlockup to be detected. If softlockup_panic is enabled, the system will panic. The fix is to touch all watchdogs before changing softlockup_thresh. Signed-off-by: Mandeep Singh Baines <msb@google.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
		
							parent
							
								
									e4fa4c9701
								
							
						
					
					
						commit
						baf48f6577
					
				
					 3 changed files with 13 additions and 1 deletions
				
			
		|  | @ -293,6 +293,9 @@ extern void sched_show_task(struct task_struct *p); | ||||||
| extern void softlockup_tick(void); | extern void softlockup_tick(void); | ||||||
| extern void touch_softlockup_watchdog(void); | extern void touch_softlockup_watchdog(void); | ||||||
| extern void touch_all_softlockup_watchdogs(void); | extern void touch_all_softlockup_watchdogs(void); | ||||||
|  | extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write, | ||||||
|  | 				    struct file *filp, void __user *buffer, | ||||||
|  | 				    size_t *lenp, loff_t *ppos); | ||||||
| extern unsigned int  softlockup_panic; | extern unsigned int  softlockup_panic; | ||||||
| extern unsigned long sysctl_hung_task_check_count; | extern unsigned long sysctl_hung_task_check_count; | ||||||
| extern unsigned long sysctl_hung_task_timeout_secs; | extern unsigned long sysctl_hung_task_timeout_secs; | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| #include <linux/lockdep.h> | #include <linux/lockdep.h> | ||||||
| #include <linux/notifier.h> | #include <linux/notifier.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
|  | #include <linux/sysctl.h> | ||||||
| 
 | 
 | ||||||
| #include <asm/irq_regs.h> | #include <asm/irq_regs.h> | ||||||
| 
 | 
 | ||||||
|  | @ -88,6 +89,14 @@ void touch_all_softlockup_watchdogs(void) | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(touch_all_softlockup_watchdogs); | EXPORT_SYMBOL(touch_all_softlockup_watchdogs); | ||||||
| 
 | 
 | ||||||
|  | int proc_dosoftlockup_thresh(struct ctl_table *table, int write, | ||||||
|  | 			     struct file *filp, void __user *buffer, | ||||||
|  | 			     size_t *lenp, loff_t *ppos) | ||||||
|  | { | ||||||
|  | 	touch_all_softlockup_watchdogs(); | ||||||
|  | 	return proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * This callback runs from the timer interrupt, and checks |  * This callback runs from the timer interrupt, and checks | ||||||
|  * whether the watchdog thread has hung or not: |  * whether the watchdog thread has hung or not: | ||||||
|  |  | ||||||
|  | @ -800,7 +800,7 @@ static struct ctl_table kern_table[] = { | ||||||
| 		.data		= &softlockup_thresh, | 		.data		= &softlockup_thresh, | ||||||
| 		.maxlen		= sizeof(int), | 		.maxlen		= sizeof(int), | ||||||
| 		.mode		= 0644, | 		.mode		= 0644, | ||||||
| 		.proc_handler	= &proc_dointvec_minmax, | 		.proc_handler	= &proc_dosoftlockup_thresh, | ||||||
| 		.strategy	= &sysctl_intvec, | 		.strategy	= &sysctl_intvec, | ||||||
| 		.extra1		= &neg_one, | 		.extra1		= &neg_one, | ||||||
| 		.extra2		= &sixty, | 		.extra2		= &sixty, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Mandeep Singh Baines
						Mandeep Singh Baines