Skip to contentSkip to conversation

Freezer: Avoid freezing kernel threads prematurely

RFC PATCH New Rafael J. Wysocki 1 participant 1 message May 19, 2007

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 Freezer: Avoid freezing kernel threads prematurely

From: Rafael J. Wysocki <[email protected]>

Kernel threads should not have TIF_FREEZE set when user space processes are being frozen, since otherwise some of them might be frozen prematurely. To prevent this from happening we can make exit_mm() unset TIF_FREEZE unconditionally just after clearing tsk->mm and when user space processes are to be frozen, try_to_freeze_tasks() should check if p->mm is different from zero and PF_BORROWED_MM is unset in p->flags (this must be done under task_lock() to prevent potential races with exit_mm() or or use_mm()/unuse_mm() from occuring).

---
 include/linux/freezer.h |    9 +++---
 kernel/exit.c           |    3 ++
 kernel/power/process.c  |   64 ++++++++++++++++++++++++------------------------
 3 files changed, 41 insertions(+), 35 deletions(-)
include/linux/freezer.h +5 -4
Index: linux-2.6.22-rc2/include/linux/freezer.h
===================================================================
@@ -22,7 +22,7 @@ static inline int freezing(struct task_s
 /*
  * Request that a process be frozen
  */
-static inline void freeze(struct task_struct *p)
+static inline void set_freeze_flag(struct task_struct *p)
 {
 	set_tsk_thread_flag(p, TIF_FREEZE);
 }
@@ -30,7 +30,7 @@ static inline void freeze(struct task_st
 /*
  * Sometimes we may need to cancel the previous 'freeze' request
  */
-static inline void do_not_freeze(struct task_struct *p)
+static inline void clear_freeze_flag(struct task_struct *p)
 {
 	clear_tsk_thread_flag(p, TIF_FREEZE);
 }
@@ -53,7 +53,7 @@ static inline int thaw_process(struct ta
 		wake_up_process(p);
 		return 1;
 	}
-	clear_tsk_thread_flag(p, TIF_FREEZE);
+	clear_freeze_flag(p);
 	task_unlock(p);
 	return 0;
 }
@@ -118,7 +118,8 @@ static inline int freezer_should_skip(st
 #else
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
-static inline void freeze(struct task_struct *p) { BUG(); }
+static inline void set_freeze_flag(struct task_struct *p) {}
+static inline void clear_freeze_flag(struct task_struct *p) {}
 static inline int thaw_process(struct task_struct *p) { return 1; }
 
 static inline void refrigerator(void) {}
kernel/power/process.c +33 -31

123 lines not on this page · raw message

kernel/exit.c +3 -0
Index: linux-2.6.22-rc2/kernel/exit.c
===================================================================
@@ -44,6 +44,7 @@
 #include <linux/resource.h>
 #include <linux/blkdev.h>
 #include <linux/task_io_accounting_ops.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -589,6 +590,8 @@ static void exit_mm(struct task_struct *
 	tsk->mm = NULL;
 	up_read(&mm->mmap_sem);
 	enter_lazy_tlb(mm, current);
+	/* We don't want this task to be frozen prematurely */
+	clear_freeze_flag(tsk);
 	task_unlock(tsk);
 	mmput(mm);
 }