Merge tag 'drm-intel-fixes-2021-06-03' of git://anongit.freedesktop.org/drm/drm-intel...
[linux-2.6-microblaze.git] / kernel / workqueue.c
index 79f2319..50142fc 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/uaccess.h>
 #include <linux/sched/isolation.h>
 #include <linux/nmi.h>
+#include <linux/kvm_para.h>
 
 #include "workqueue_internal.h"
 
@@ -1630,7 +1631,7 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
        struct work_struct *work = &dwork->work;
 
        WARN_ON_ONCE(!wq);
-       WARN_ON_ONCE(timer->function != delayed_work_timer_fn);
+       WARN_ON_FUNCTION_MISMATCH(timer->function, delayed_work_timer_fn);
        WARN_ON_ONCE(timer_pending(timer));
        WARN_ON_ONCE(!list_empty(&work->entry));
 
@@ -5772,6 +5773,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
 {
        unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ;
        bool lockup_detected = false;
+       unsigned long now = jiffies;
        struct worker_pool *pool;
        int pi;
 
@@ -5786,6 +5788,12 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
                if (list_empty(&pool->worklist))
                        continue;
 
+               /*
+                * If a virtual machine is stopped by the host it can look to
+                * the watchdog like a stall.
+                */
+               kvm_check_and_clear_guest_paused();
+
                /* get the latest of pool and touched timestamps */
                if (pool->cpu >= 0)
                        touched = READ_ONCE(per_cpu(wq_watchdog_touched_cpu, pool->cpu));
@@ -5799,12 +5807,12 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
                        ts = touched;
 
                /* did we stall? */
-               if (time_after(jiffies, ts + thresh)) {
+               if (time_after(now, ts + thresh)) {
                        lockup_detected = true;
                        pr_emerg("BUG: workqueue lockup - pool");
                        pr_cont_pool_info(pool);
                        pr_cont(" stuck for %us!\n",
-                               jiffies_to_msecs(jiffies - pool_ts) / 1000);
+                               jiffies_to_msecs(now - pool_ts) / 1000);
                }
        }