Hi! > > That said... Linus, can I get latest version of that patch? I'll fix > > it up to work with s2disk... > > I don't think I've done anything but fix the SYSTEM_RUNNING thing you > noticed and fixed a header problem that DaveJ noticed with > CONFIG_VT_CONSOLE not being enabled. But here it is again. Okay, console switches are really needed -- so that X gets it chance to save graphics state. Try your version from accelerated X -- it would break AFAICS. So we basically need the old code -- to switch consoles -- and then your new code -- to prevent writing to console that is suspended. Oh and I'm not sure about that system_state. We probably should have SYSTEM_SUSPENDING, and definitely should not be setting this from console-handling routines... is setting system_state needed at all? Does this solve your problem? It will probably break compilation in some weird setups, and definitely has some wrong warnings... Pavel diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index f8d5e2a..b9d24a4 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c @@ -72,5 +72,6 @@ void dpm_resume(void) void device_resume(void) { + pm_unfreeze_console(); down(&dpm_sem); dpm_resume(); up(&dpm_sem); diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 9231942..41ba63a 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c @@ -86,5 +86,6 @@ int device_suspend(pm_message_t state) int error = 0; + pm_freeze_console(); down(&dpm_sem); down(&dpm_list_sem); while (!list_empty(&dpm_active) && error == 0) { diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 37c1c76..c03b17f 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -43,13 +43,9 @@ extern void mark_free_pages(struct zone /* kernel/power/swsusp.c */ extern int software_suspend(void); -#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) extern int pm_prepare_console(void); extern void pm_restore_console(void); -#else -static inline int pm_prepare_console(void) { return 0; } -static inline void pm_restore_console(void) {} -#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */ + #else static inline int software_suspend(void) { diff --git a/kernel/power/console.c b/kernel/power/console.c index 623786d..2be3ef2 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -9,24 +9,25 @@ #include <linux/console.h> #include "power.h" -#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) static int orig_fgconsole, orig_kmsg; +extern int console_suspended; int pm_prepare_console(void) { acquire_console_sem(); - orig_fgconsole = fg_console; if (vc_allocate(SUSPEND_CONSOLE)) { - /* we can't have a free VC for now. Too bad, - * we don't want to mess the screen for now. */ + /* we can't have a free VC for now. Too bad, + * we don't want to mess the screen for now. */ release_console_sem(); return 1; } + /* We need to switch to text-mode console, so that X has chance + to save its state. */ set_console(SUSPEND_CONSOLE); release_console_sem(); @@ -36,15 +37,31 @@ int pm_prepare_console(void) } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; + return 0; +} + +void pm_freeze_console(void) +{ + acquire_console_sem(); + console_suspended = 1; + system_state = SYSTEM_BOOTING; return 0; } +void pm_unfreeze_console(void) +{ + console_suspended = 0; + system_state = SYSTEM_RUNNING; + release_console_sem(); + return; +} + void pm_restore_console(void) { acquire_console_sem(); set_console(orig_fgconsole); + release_console_sem(); kmsg_redirect = orig_kmsg; return; } -#endif diff --git a/kernel/printk.c b/kernel/printk.c index c056f33..8adb9ed 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -67,6 +67,7 @@ EXPORT_SYMBOL(oops_in_progress); * driver system. */ static DECLARE_MUTEX(console_sem); +static DECLARE_MUTEX(secondary_console_sem); struct console *console_drivers; /* * This is used for debugging the mess that is the VT code by @@ -77,6 +78,7 @@ struct console *console_drivers; * locked without the console sempahore held */ static int console_locked; +int console_suspended; /* * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars @@ -707,6 +709,11 @@ int __init add_preferred_console(char *n */ void acquire_console_sem(void) { + if (console_suspended) { + down(&secondary_console_sem); + return; + } + BUG_ON(in_interrupt()); down(&console_sem); console_locked = 1; @@ -750,6 +757,11 @@ void release_console_sem(void) unsigned long _con_start, _log_end; unsigned long wake_klogd = 0; + if (console_suspended) { + up(&secondary_console_sem); + return; + } + for ( ; ; ) { spin_lock_irqsave(&logbuf_lock, flags); wake_klogd |= log_start - log_end; -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html