Эх сурвалжийг харах

workqueue: avoid hard lockups in show_workqueue_state()

show_workqueue_state() can print out a lot of messages while being in
atomic context, e.g. sysrq-t -> show_workqueue_state(). If the console
device is slow it may end up triggering NMI hard lockup watchdog.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org # v4.5+
Sergey Senozhatsky 7 жил өмнө
parent
commit
62635ea8c1
1 өөрчлөгдсөн 13 нэмэгдсэн , 0 устгасан
  1. 13 0
      kernel/workqueue.c

+ 13 - 0
kernel/workqueue.c

@@ -48,6 +48,7 @@
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 #include <linux/sched/isolation.h>
 #include <linux/sched/isolation.h>
+#include <linux/nmi.h>
 
 
 #include "workqueue_internal.h"
 #include "workqueue_internal.h"
 
 
@@ -4463,6 +4464,12 @@ void show_workqueue_state(void)
 			if (pwq->nr_active || !list_empty(&pwq->delayed_works))
 			if (pwq->nr_active || !list_empty(&pwq->delayed_works))
 				show_pwq(pwq);
 				show_pwq(pwq);
 			spin_unlock_irqrestore(&pwq->pool->lock, flags);
 			spin_unlock_irqrestore(&pwq->pool->lock, flags);
+			/*
+			 * We could be printing a lot from atomic context, e.g.
+			 * sysrq-t -> show_workqueue_state(). Avoid triggering
+			 * hard lockup.
+			 */
+			touch_nmi_watchdog();
 		}
 		}
 	}
 	}
 
 
@@ -4490,6 +4497,12 @@ void show_workqueue_state(void)
 		pr_cont("\n");
 		pr_cont("\n");
 	next_pool:
 	next_pool:
 		spin_unlock_irqrestore(&pool->lock, flags);
 		spin_unlock_irqrestore(&pool->lock, flags);
+		/*
+		 * We could be printing a lot from atomic context, e.g.
+		 * sysrq-t -> show_workqueue_state(). Avoid triggering
+		 * hard lockup.
+		 */
+		touch_nmi_watchdog();
 	}
 	}
 
 
 	rcu_read_unlock_sched();
 	rcu_read_unlock_sched();