From: Ulrich Obergfell <uobergfe@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, dzickus@redhat.com,
atomlin@redhat.com, uobergfe@redhat.com, jolsa@kernel.org,
mhocko@suse.cz, eranian@google.com, cmetcalf@ezchip.com,
fweisbec@gmail.com
Subject: [PATCH 2/4] watchdog: introduce watchdog_suspend() and watchdog_resume()
Date: Sat, 1 Aug 2015 14:49:23 +0200 [thread overview]
Message-ID: <1438433365-2979-3-git-send-email-uobergfe@redhat.com> (raw)
In-Reply-To: <1438433365-2979-1-git-send-email-uobergfe@redhat.com>
This interface can be utilized to deactivate the hard and soft lockup
detector temporarily. Callers are expected to minimize the duration of
deactivation. Multiple deactivations are allowed to occur in parallel
but should be rare in practice.
Signed-off-by: Ulrich Obergfell <uobergfe@redhat.com>
---
include/linux/nmi.h | 2 ++
kernel/watchdog.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index f94da0e..60050c2 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -80,6 +80,8 @@ extern int proc_watchdog_thresh(struct ctl_table *, int ,
void __user *, size_t *, loff_t *);
extern int proc_watchdog_cpumask(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
+extern int watchdog_suspend(void);
+extern void watchdog_resume(void);
#endif
#ifdef CONFIG_HAVE_ACPI_APEI_NMI
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 5571f20..98d44b1 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -67,6 +67,7 @@ unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
#define for_each_watchdog_cpu(cpu) \
for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask)
+static int __read_mostly watchdog_suspended = 0;
static int __read_mostly watchdog_running;
static u64 __read_mostly sample_period;
@@ -702,6 +703,50 @@ static void watchdog_unpark_threads(void)
put_online_cpus();
}
+/*
+ * Suspend the hard and soft lockup detector by parking the watchdog threads.
+ */
+int watchdog_suspend(void)
+{
+ int ret = 0;
+
+ mutex_lock(&watchdog_proc_mutex);
+ /*
+ * Multiple suspend requests can be active in parallel (counted by
+ * the 'watchdog_suspended' variable). If the watchdog threads are
+ * running, the first caller takes care that they will be parked.
+ * The state of 'watchdog_running' cannot change while a suspend
+ * request is active (see related changes in 'proc' handlers).
+ */
+ if (watchdog_running && !watchdog_suspended)
+ ret = watchdog_park_threads();
+
+ if (ret == 0)
+ watchdog_suspended++;
+
+ mutex_unlock(&watchdog_proc_mutex);
+
+ return ret;
+}
+
+/*
+ * Resume the hard and soft lockup detector by unparking the watchdog threads.
+ */
+void watchdog_resume(void)
+{
+ mutex_lock(&watchdog_proc_mutex);
+
+ watchdog_suspended--;
+ /*
+ * The watchdog threads are unparked if they were previously running
+ * and if there is no more active suspend request.
+ */
+ if (watchdog_running && !watchdog_suspended)
+ watchdog_unpark_threads();
+
+ mutex_unlock(&watchdog_proc_mutex);
+}
+
static void restart_watchdog_hrtimer(void *info)
{
struct hrtimer *hrtimer = raw_cpu_ptr(&watchdog_hrtimer);
@@ -823,6 +868,12 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write,
mutex_lock(&watchdog_proc_mutex);
+ if (watchdog_suspended) {
+ /* no parameter changes allowed while watchdog is suspended */
+ err = -EAGAIN;
+ goto out;
+ }
+
/*
* If the parameter is being read return the state of the corresponding
* bit(s) in 'watchdog_enabled', else update 'watchdog_enabled' and the
@@ -908,6 +959,12 @@ int proc_watchdog_thresh(struct ctl_table *table, int write,
mutex_lock(&watchdog_proc_mutex);
+ if (watchdog_suspended) {
+ /* no parameter changes allowed while watchdog is suspended */
+ err = -EAGAIN;
+ goto out;
+ }
+
old = ACCESS_ONCE(watchdog_thresh);
err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
@@ -939,6 +996,13 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,
int err;
mutex_lock(&watchdog_proc_mutex);
+
+ if (watchdog_suspended) {
+ /* no parameter changes allowed while watchdog is suspended */
+ err = -EAGAIN;
+ goto out;
+ }
+
err = proc_do_large_bitmap(table, write, buffer, lenp, ppos);
if (!err && write) {
/* Remove impossible cpus to keep sysctl output cleaner. */
@@ -956,6 +1020,7 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,
pr_err("cpumask update failed\n");
}
}
+out:
mutex_unlock(&watchdog_proc_mutex);
return err;
}
--
1.7.11.7
next prev parent reply other threads:[~2015-08-01 12:46 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-01 12:49 [PATCH 0/4] watchdog: avoid races in watchdog_nmi_{en|disable} functions Ulrich Obergfell
2015-08-01 12:49 ` [PATCH 1/4] watchdog: introduce watchdog_park_threads() and watchdog_unpark_threads() Ulrich Obergfell
2015-08-04 13:26 ` Michal Hocko
2015-08-04 15:20 ` Ulrich Obergfell
2015-08-01 12:49 ` Ulrich Obergfell [this message]
2015-08-01 14:04 ` [PATCH 2/4] watchdog: introduce watchdog_suspend() and watchdog_resume() Guenter Roeck
2015-08-01 14:39 ` Ulrich Obergfell
2015-08-01 14:47 ` Guenter Roeck
2015-08-04 22:58 ` Andrew Morton
2015-08-05 8:10 ` Ulrich Obergfell
2015-08-01 12:49 ` [PATCH 3/4] watchdog: use park/unpark functions in update_watchdog_all_cpus() Ulrich Obergfell
2015-08-01 12:49 ` [PATCH 4/4] watchdog: use suspend/resume interface in fixup_ht_bug() Ulrich Obergfell
2015-08-04 13:31 ` Michal Hocko
2015-08-04 14:27 ` Don Zickus
2015-08-04 14:44 ` Michal Hocko
2015-08-04 14:59 ` Ulrich Obergfell
2015-08-05 22:17 ` Andrew Morton
2015-08-02 10:54 ` [PATCH 0/4] watchdog: avoid races in watchdog_nmi_{en|disable} functions Aaron Tomlin
2015-08-02 22:14 ` Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1438433365-2979-3-git-send-email-uobergfe@redhat.com \
--to=uobergfe@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=atomlin@redhat.com \
--cc=cmetcalf@ezchip.com \
--cc=dzickus@redhat.com \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhocko@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).