Freezer: Avoid freezing kernel threads prematurely
Subsystems (3)
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).
Signed-off-by Rafael J. Wysocki <[email protected]>
--- 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
@@ -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 tawake_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
@@ -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); }