aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 12:25:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 12:25:52 -0400
commit19504828b4bee5e471bcd35e214bc6fd0d380692 (patch)
tree30d4ffb6783daf9fadd47548c035646d3f0f073e /kernel
parent57d19e80f459dd845fb3cfeba8e6df8471bac142 (diff)
parent3cb6d1540880e767d911b79eb49578de2190f428 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf tools: Fix sample size bit operations perf tools: Fix ommitted mmap data update on remap watchdog: Change the default timeout and configure nmi watchdog period based on watchdog_thresh watchdog: Disable watchdog when thresh is zero watchdog: Only disable/enable watchdog if neccessary watchdog: Fix rounding bug in get_sample_period() perf tools: Propagate event parse error handling perf tools: Robustify dynamic sample content fetch perf tools: Pre-check sample size before parsing perf tools: Move evlist sample helpers to evlist area perf tools: Remove junk code in mmap size handling perf tools: Check we are able to read the event size on mmap
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sysctl.c12
-rw-r--r--kernel/watchdog.c52
2 files changed, 38 insertions, 26 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c0bb32414b17..3dd0c46fa3bb 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -730,14 +730,16 @@ static struct ctl_table kern_table[] = {
730 .data = &watchdog_enabled, 730 .data = &watchdog_enabled,
731 .maxlen = sizeof (int), 731 .maxlen = sizeof (int),
732 .mode = 0644, 732 .mode = 0644,
733 .proc_handler = proc_dowatchdog_enabled, 733 .proc_handler = proc_dowatchdog,
734 .extra1 = &zero,
735 .extra2 = &one,
734 }, 736 },
735 { 737 {
736 .procname = "watchdog_thresh", 738 .procname = "watchdog_thresh",
737 .data = &softlockup_thresh, 739 .data = &watchdog_thresh,
738 .maxlen = sizeof(int), 740 .maxlen = sizeof(int),
739 .mode = 0644, 741 .mode = 0644,
740 .proc_handler = proc_dowatchdog_thresh, 742 .proc_handler = proc_dowatchdog,
741 .extra1 = &neg_one, 743 .extra1 = &neg_one,
742 .extra2 = &sixty, 744 .extra2 = &sixty,
743 }, 745 },
@@ -755,7 +757,9 @@ static struct ctl_table kern_table[] = {
755 .data = &watchdog_enabled, 757 .data = &watchdog_enabled,
756 .maxlen = sizeof (int), 758 .maxlen = sizeof (int),
757 .mode = 0644, 759 .mode = 0644,
758 .proc_handler = proc_dowatchdog_enabled, 760 .proc_handler = proc_dowatchdog,
761 .extra1 = &zero,
762 .extra2 = &one,
759 }, 763 },
760#endif 764#endif
761#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) 765#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 14733d4d156b..6e63097fa73a 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -28,7 +28,7 @@
28#include <linux/perf_event.h> 28#include <linux/perf_event.h>
29 29
30int watchdog_enabled = 1; 30int watchdog_enabled = 1;
31int __read_mostly softlockup_thresh = 60; 31int __read_mostly watchdog_thresh = 10;
32 32
33static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); 33static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
34static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); 34static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);
@@ -91,6 +91,17 @@ static int __init nosoftlockup_setup(char *str)
91__setup("nosoftlockup", nosoftlockup_setup); 91__setup("nosoftlockup", nosoftlockup_setup);
92/* */ 92/* */
93 93
94/*
95 * Hard-lockup warnings should be triggered after just a few seconds. Soft-
96 * lockups can have false positives under extreme conditions. So we generally
97 * want a higher threshold for soft lockups than for hard lockups. So we couple
98 * the thresholds with a factor: we make the soft threshold twice the amount of
99 * time the hard threshold is.
100 */
101static int get_softlockup_thresh()
102{
103 return watchdog_thresh * 2;
104}
94 105
95/* 106/*
96 * Returns seconds, approximately. We don't need nanosecond 107 * Returns seconds, approximately. We don't need nanosecond
@@ -105,12 +116,12 @@ static unsigned long get_timestamp(int this_cpu)
105static unsigned long get_sample_period(void) 116static unsigned long get_sample_period(void)
106{ 117{
107 /* 118 /*
108 * convert softlockup_thresh from seconds to ns 119 * convert watchdog_thresh from seconds to ns
109 * the divide by 5 is to give hrtimer 5 chances to 120 * the divide by 5 is to give hrtimer 5 chances to
110 * increment before the hardlockup detector generates 121 * increment before the hardlockup detector generates
111 * a warning 122 * a warning
112 */ 123 */
113 return softlockup_thresh / 5 * NSEC_PER_SEC; 124 return get_softlockup_thresh() * (NSEC_PER_SEC / 5);
114} 125}
115 126
116/* Commands for resetting the watchdog */ 127/* Commands for resetting the watchdog */
@@ -182,7 +193,7 @@ static int is_softlockup(unsigned long touch_ts)
182 unsigned long now = get_timestamp(smp_processor_id()); 193 unsigned long now = get_timestamp(smp_processor_id());
183 194
184 /* Warn about unreasonable delays: */ 195 /* Warn about unreasonable delays: */
185 if (time_after(now, touch_ts + softlockup_thresh)) 196 if (time_after(now, touch_ts + get_softlockup_thresh()))
186 return now - touch_ts; 197 return now - touch_ts;
187 198
188 return 0; 199 return 0;
@@ -359,7 +370,7 @@ static int watchdog_nmi_enable(int cpu)
359 370
360 /* Try to register using hardware perf events */ 371 /* Try to register using hardware perf events */
361 wd_attr = &wd_hw_attr; 372 wd_attr = &wd_hw_attr;
362 wd_attr->sample_period = hw_nmi_get_sample_period(); 373 wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
363 event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback); 374 event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback);
364 if (!IS_ERR(event)) { 375 if (!IS_ERR(event)) {
365 printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); 376 printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n");
@@ -501,28 +512,25 @@ static void watchdog_disable_all_cpus(void)
501/* sysctl functions */ 512/* sysctl functions */
502#ifdef CONFIG_SYSCTL 513#ifdef CONFIG_SYSCTL
503/* 514/*
504 * proc handler for /proc/sys/kernel/nmi_watchdog 515 * proc handler for /proc/sys/kernel/nmi_watchdog,watchdog_thresh
505 */ 516 */
506 517
507int proc_dowatchdog_enabled(struct ctl_table *table, int write, 518int proc_dowatchdog(struct ctl_table *table, int write,
508 void __user *buffer, size_t *length, loff_t *ppos) 519 void __user *buffer, size_t *lenp, loff_t *ppos)
509{ 520{
510 proc_dointvec(table, write, buffer, length, ppos); 521 int ret;
511 522
512 if (write) { 523 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
513 if (watchdog_enabled) 524 if (ret || !write)
514 watchdog_enable_all_cpus(); 525 goto out;
515 else
516 watchdog_disable_all_cpus();
517 }
518 return 0;
519}
520 526
521int proc_dowatchdog_thresh(struct ctl_table *table, int write, 527 if (watchdog_enabled && watchdog_thresh)
522 void __user *buffer, 528 watchdog_enable_all_cpus();
523 size_t *lenp, loff_t *ppos) 529 else
524{ 530 watchdog_disable_all_cpus();
525 return proc_dointvec_minmax(table, write, buffer, lenp, ppos); 531
532out:
533 return ret;
526} 534}
527#endif /* CONFIG_SYSCTL */ 535#endif /* CONFIG_SYSCTL */
528 536