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:
		
				
					committed by
					
						
						Ingo Molnar
					
				
			
			
				
	
			
			
			
						parent
						
							e4fa4c9701
						
					
				
				
					commit
					baf48f6577
				
			@@ -293,6 +293,9 @@ extern void sched_show_task(struct task_struct *p);
 | 
			
		||||
extern void softlockup_tick(void);
 | 
			
		||||
extern void touch_softlockup_watchdog(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 long sysctl_hung_task_check_count;
 | 
			
		||||
extern unsigned long sysctl_hung_task_timeout_secs;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
#include <linux/lockdep.h>
 | 
			
		||||
#include <linux/notifier.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
#include <linux/sysctl.h>
 | 
			
		||||
 | 
			
		||||
#include <asm/irq_regs.h>
 | 
			
		||||
 | 
			
		||||
@@ -88,6 +89,14 @@ void touch_all_softlockup_watchdogs(void)
 | 
			
		||||
}
 | 
			
		||||
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
 | 
			
		||||
 * whether the watchdog thread has hung or not:
 | 
			
		||||
 
 | 
			
		||||
@@ -800,7 +800,7 @@ static struct ctl_table kern_table[] = {
 | 
			
		||||
		.data		= &softlockup_thresh,
 | 
			
		||||
		.maxlen		= sizeof(int),
 | 
			
		||||
		.mode		= 0644,
 | 
			
		||||
		.proc_handler	= &proc_dointvec_minmax,
 | 
			
		||||
		.proc_handler	= &proc_dosoftlockup_thresh,
 | 
			
		||||
		.strategy	= &sysctl_intvec,
 | 
			
		||||
		.extra1		= &neg_one,
 | 
			
		||||
		.extra2		= &sixty,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user