Blob Blame History Raw
From: Petr Mladek <pmladek@suse.com>
Date: Tue, 20 Jun 2017 12:54:37 +0200
Subject: [PATCH] printk/xen: Force printk sync mode when migrating Xen guest
Patch-mainline: Not yet, still being discussed upstream
References: bsc#1043347, bsc#1174146

printk() tries to wake up the printk kthread when used in the async mode.
wake_up_process() might cause warning when it is called during system
freeze and timekeeping is already disabled. This causes recursive
printk() and a deadlock.

This problem is already solved in many situations by forcing
the synchronous mode in console_suspend() and relaxing the handling
in console_resume().

do_suspend() used by Xen handles consoles Xen-specific way and
resumes the console very early. This patch forces the printk sync mode
in Xen suspend as well. It is done around the dpm_suspend/dpm_resume
operations as inspired by kernel_kexec().

Signed-off-by: Petr Mladek <pmladek@suse.com>
---
 drivers/xen/manage.c   |  6 +++++-
 include/linux/printk.h |  3 +++
 kernel/printk/printk.c | 14 ++++++++++++--
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index e12bd3635f83..b99b8c85819b 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -115,10 +115,12 @@ static void do_suspend(void)
 		goto out_thaw;
 	}
 
+	printk_force_sync_mode();
+
 	err = dpm_suspend_start(PMSG_FREEZE);
 	if (err) {
 		pr_err("%s: dpm_suspend_start %d\n", __func__, err);
-		goto out_thaw;
+		goto out_resume_printk;
 	}
 
 	printk(KERN_DEBUG "suspending xenstore...\n");
@@ -160,6 +162,8 @@ out_resume:
 
 	dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
 
+out_resume_printk:
+	printk_relax_sync_mode();
 out_thaw:
 	thaw_processes();
 out:
diff --git a/include/linux/printk.h b/include/linux/printk.h
index e113c65951e0..3af7ddd51f7b 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -127,6 +127,9 @@ static inline __printf(1, 2) __cold
 static inline void printk_nmi_direct_exit(void) { }
 #endif /* PRINTK_NMI */
 
+extern void printk_force_sync_mode(void);
+extern void printk_relax_sync_mode(void);
+
 #ifdef CONFIG_PRINTK
 asmlinkage __printf(5, 0)
 int vprintk_emit(int facility, int level,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 377c004cdeb2..45181451e010 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2098,6 +2098,16 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
 }
 #endif
 
+void printk_force_sync_mode(void)
+{
+	force_printk_sync = true;
+}
+
+void printk_relax_sync_mode(void)
+{
+	force_printk_sync = false;
+}
+
 static int __add_preferred_console(char *name, int idx, char *options,
 				   char *brl_options)
 {
@@ -2211,7 +2221,7 @@ MODULE_PARM_DESC(console_suspend, "suspend console during suspend"
  */
 void suspend_console(void)
 {
-	force_printk_sync = true;
+	printk_force_sync_mode();
 
 	if (!console_suspend_enabled)
 		return;
@@ -2223,7 +2233,7 @@ void suspend_console(void)
 
 void resume_console(void)
 {
-	force_printk_sync = false;
+	printk_relax_sync_mode();
 
 	if (!console_suspend_enabled)
 		return;
-- 
1.8.5.6