mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Unfreeze tasks after an oops in the freezer
@ 2011-07-27 10:35 Oliver Neukum
  2011-07-28 21:14 ` Rafael J. Wysocki
  0 siblings, 1 reply; 2+ messages in thread
From: Oliver Neukum @ 2011-07-27 10:35 UTC (permalink / raw)
  To: Andrew Morton, Rafael J. Wysocki, linux-pm, linux-kernel

>From ee5849f0bc39d554ef91747ff80c307ac3e05cdd Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@neukum.org>
Date: Wed, 27 Jul 2011 12:27:00 +0200
Subject: [PATCH] Unfreeze tasks after an oops in the freezer

If an oops kills the task suspending or snapshotting
is system, the system is dead because the action is
never completed and the tasks never thawed.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
 include/linux/freezer.h |    2 ++
 kernel/panic.c          |    8 ++++++++
 kernel/power/process.c  |   11 +++++++++++
 3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 1effc8b..ab0168a 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -50,6 +50,7 @@ extern int thaw_process(struct task_struct *p);
 extern void refrigerator(void);
 extern int freeze_processes(void);
 extern void thaw_processes(void);
+extern void thaw_in_oops(void);
 
 static inline int try_to_freeze(void)
 {
@@ -181,6 +182,7 @@ static inline void freezer_count(void) {}
 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 static inline void set_freezable(void) {}
 static inline void set_freezable_with_signal(void) {}
+static inline void thaw_in_oops(void) {}
 
 #define wait_event_freezable(wq, condition)				\
 		wait_event_interruptible(wq, condition)
diff --git a/kernel/panic.c b/kernel/panic.c
index 6923167..ccdd834 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/nmi.h>
 #include <linux/dmi.h>
+#include <linux/freezer.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -355,6 +356,13 @@ void oops_exit(void)
 	do_oops_enter_exit();
 	print_oops_end_marker();
 	kmsg_dump(KMSG_DUMP_OOPS);
+	/*
+	 * if we oops while tasks are frozen, the system
+	 * will stop dead because the task that would thaw it
+	 * has been killed. So the system must be explicitly
+	 * thawed here.
+	 */
+	thaw_in_oops();
 }
 
 #ifdef WANT_WARN_ON_SLOWPATH
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 0cf3a27..c03e88b 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -22,6 +22,9 @@
  */
 #define TIMEOUT	(20 * HZ)
 
+/* in case we oops while processes are frozen */
+static bool tasks_frozen = false;
+
 static inline int freezable(struct task_struct * p)
 {
 	if ((p == current) ||
@@ -131,6 +134,7 @@ static int try_to_freeze_tasks(bool sig_only)
 			elapsed_csecs % 100);
 	}
 
+	tasks_frozen = (todo == 0);
 	return todo ? -EBUSY : 0;
 }
 
@@ -189,7 +193,14 @@ void thaw_processes(void)
 	thaw_workqueues();
 	thaw_tasks(true);
 	thaw_tasks(false);
+	tasks_frozen = false;
 	schedule();
 	printk("done.\n");
 }
 
+void thaw_in_oops(void)
+{
+	if (tasks_frozen)
+		thaw_processes();
+}
+
-- 
1.7.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Unfreeze tasks after an oops in the freezer
  2011-07-27 10:35 [PATCH] Unfreeze tasks after an oops in the freezer Oliver Neukum
@ 2011-07-28 21:14 ` Rafael J. Wysocki
  0 siblings, 0 replies; 2+ messages in thread
From: Rafael J. Wysocki @ 2011-07-28 21:14 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: Andrew Morton, linux-pm, linux-kernel

On Wednesday, July 27, 2011, Oliver Neukum wrote:
> From ee5849f0bc39d554ef91747ff80c307ac3e05cdd Mon Sep 17 00:00:00 2001
> From: Oliver Neukum <oliver@neukum.org>
> Date: Wed, 27 Jul 2011 12:27:00 +0200
> Subject: [PATCH] Unfreeze tasks after an oops in the freezer
> 
> If an oops kills the task suspending or snapshotting
> is system, the system is dead because the action is
> never completed and the tasks never thawed.
> 
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
>  include/linux/freezer.h |    2 ++
>  kernel/panic.c          |    8 ++++++++
>  kernel/power/process.c  |   11 +++++++++++
>  3 files changed, 21 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/freezer.h b/include/linux/freezer.h
> index 1effc8b..ab0168a 100644
> --- a/include/linux/freezer.h
> +++ b/include/linux/freezer.h
> @@ -50,6 +50,7 @@ extern int thaw_process(struct task_struct *p);
>  extern void refrigerator(void);
>  extern int freeze_processes(void);
>  extern void thaw_processes(void);
> +extern void thaw_in_oops(void);
>  
>  static inline int try_to_freeze(void)
>  {
> @@ -181,6 +182,7 @@ static inline void freezer_count(void) {}
>  static inline int freezer_should_skip(struct task_struct *p) { return 0; }
>  static inline void set_freezable(void) {}
>  static inline void set_freezable_with_signal(void) {}
> +static inline void thaw_in_oops(void) {}
>  
>  #define wait_event_freezable(wq, condition)				\
>  		wait_event_interruptible(wq, condition)
> diff --git a/kernel/panic.c b/kernel/panic.c
> index 6923167..ccdd834 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -23,6 +23,7 @@
>  #include <linux/init.h>
>  #include <linux/nmi.h>
>  #include <linux/dmi.h>
> +#include <linux/freezer.h>
>  
>  #define PANIC_TIMER_STEP 100
>  #define PANIC_BLINK_SPD 18
> @@ -355,6 +356,13 @@ void oops_exit(void)
>  	do_oops_enter_exit();
>  	print_oops_end_marker();
>  	kmsg_dump(KMSG_DUMP_OOPS);
> +	/*
> +	 * if we oops while tasks are frozen, the system
> +	 * will stop dead because the task that would thaw it
> +	 * has been killed. So the system must be explicitly
> +	 * thawed here.
> +	 */
> +	thaw_in_oops();
>  }
>  
>  #ifdef WANT_WARN_ON_SLOWPATH
> diff --git a/kernel/power/process.c b/kernel/power/process.c
> index 0cf3a27..c03e88b 100644
> --- a/kernel/power/process.c
> +++ b/kernel/power/process.c
> @@ -22,6 +22,9 @@
>   */
>  #define TIMEOUT	(20 * HZ)
>  
> +/* in case we oops while processes are frozen */
> +static bool tasks_frozen = false;
> +
>  static inline int freezable(struct task_struct * p)
>  {
>  	if ((p == current) ||
> @@ -131,6 +134,7 @@ static int try_to_freeze_tasks(bool sig_only)
>  			elapsed_csecs % 100);
>  	}
>  
> +	tasks_frozen = (todo == 0);

I'd prefer it to be set by freeze_processes(), when oom_killer_disable()
is called.

>  	return todo ? -EBUSY : 0;
>  }
>  
> @@ -189,7 +193,14 @@ void thaw_processes(void)
>  	thaw_workqueues();
>  	thaw_tasks(true);
>  	thaw_tasks(false);
> +	tasks_frozen = false;
>  	schedule();
>  	printk("done.\n");
>  }
>  
> +void thaw_in_oops(void)
> +{
> +	if (tasks_frozen)
> +		thaw_processes();
> +}
> +

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-07-28 21:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-27 10:35 [PATCH] Unfreeze tasks after an oops in the freezer Oliver Neukum
2011-07-28 21:14 ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®