#define for_each_watchdog_cpu(cpu) \
        for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask)
 
+static int __read_mostly watchdog_suspended;
 static int __read_mostly watchdog_running;
 static u64 __read_mostly sample_period;
 
        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);
 
        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
 
        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);
 
        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. */
                                pr_err("cpumask update failed\n");
                }
        }
+out:
        mutex_unlock(&watchdog_proc_mutex);
        return err;
 }