diff options
author | Michal Hocko <mhocko@suse.cz> | 2013-09-24 18:27:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-24 20:00:25 -0400 |
commit | 359e6fab6600562073162348cd4c18c5958296d8 (patch) | |
tree | a7cd07315603004dc2b00311df8cfa259b863feb /kernel | |
parent | 4a10c2ac2f368583138b774ca41fac4207911983 (diff) |
watchdog: update watchdog attributes atomically
proc_dowatchdog doesn't synchronize multiple callers which might lead to
confusion when two parallel callers might confuse watchdog_enable_all_cpus
resp watchdog_disable_all_cpus (eg watchdog gets enabled even if
watchdog_thresh was set to 0 already).
This patch adds a local mutex which synchronizes callers to the sysctl
handler.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Acked-by: Don Zickus <dzickus@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/watchdog.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 51c4f34d258e..ced7d0609931 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -520,13 +520,15 @@ int proc_dowatchdog(struct ctl_table *table, int write, | |||
520 | void __user *buffer, size_t *lenp, loff_t *ppos) | 520 | void __user *buffer, size_t *lenp, loff_t *ppos) |
521 | { | 521 | { |
522 | int err, old_thresh, old_enabled; | 522 | int err, old_thresh, old_enabled; |
523 | static DEFINE_MUTEX(watchdog_proc_mutex); | ||
523 | 524 | ||
525 | mutex_lock(&watchdog_proc_mutex); | ||
524 | old_thresh = ACCESS_ONCE(watchdog_thresh); | 526 | old_thresh = ACCESS_ONCE(watchdog_thresh); |
525 | old_enabled = ACCESS_ONCE(watchdog_user_enabled); | 527 | old_enabled = ACCESS_ONCE(watchdog_user_enabled); |
526 | 528 | ||
527 | err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | 529 | err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
528 | if (err || !write) | 530 | if (err || !write) |
529 | return err; | 531 | goto out; |
530 | 532 | ||
531 | set_sample_period(); | 533 | set_sample_period(); |
532 | /* | 534 | /* |
@@ -544,7 +546,8 @@ int proc_dowatchdog(struct ctl_table *table, int write, | |||
544 | watchdog_thresh = old_thresh; | 546 | watchdog_thresh = old_thresh; |
545 | watchdog_user_enabled = old_enabled; | 547 | watchdog_user_enabled = old_enabled; |
546 | } | 548 | } |
547 | 549 | out: | |
550 | mutex_unlock(&watchdog_proc_mutex); | ||
548 | return err; | 551 | return err; |
549 | } | 552 | } |
550 | #endif /* CONFIG_SYSCTL */ | 553 | #endif /* CONFIG_SYSCTL */ |