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