diff options
-rw-r--r-- | include/asm-arm/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-frv/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-i386/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-ia64/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-powerpc/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-sh/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-x86_64/thread_info.h | 2 | ||||
-rw-r--r-- | include/linux/freezer.h | 11 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | kernel/power/process.c | 17 |
10 files changed, 30 insertions, 13 deletions
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index d9b8bddc873..5014794f9eb 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -147,6 +147,7 @@ extern void iwmmxt_task_switch(struct thread_info *); #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 +#define TIF_FREEZE 19 #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -154,6 +155,7 @@ extern void iwmmxt_task_switch(struct thread_info *); #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) +#define _TIF_FREEZE (1 << TIF_FREEZE) /* * Change these and you break ASM code in entry-common.S diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h index d66c48e6ef1..d881f518e6a 100644 --- a/include/asm-frv/thread_info.h +++ b/include/asm-frv/thread_info.h @@ -116,6 +116,7 @@ register struct thread_info *__current_thread_info asm("gr15"); #define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 17 /* OOM killer killed process */ +#define TIF_FREEZE 18 /* freezing for suspend */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info asm("gr15"); #define _TIF_IRET (1 << TIF_IRET) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) +#define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h index 46d32ad9208..4b187bb377b 100644 --- a/include/asm-i386/thread_info.h +++ b/include/asm-i386/thread_info.h @@ -134,6 +134,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 16 #define TIF_DEBUG 17 /* uses debug registers */ #define TIF_IO_BITMAP 18 /* uses I/O bitmap */ +#define TIF_FREEZE 19 /* is freezing for suspend */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) @@ -147,6 +148,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_DEBUG (1<<TIF_DEBUG) #define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP) +#define _TIF_FREEZE (1<<TIF_FREEZE) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h index 8adcde0934c..9b505b25544 100644 --- a/include/asm-ia64/thread_info.h +++ b/include/asm-ia64/thread_info.h @@ -88,6 +88,7 @@ struct thread_info { #define TIF_MEMDIE 17 #define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ +#define TIF_FREEZE 20 /* is freezing for suspend */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) @@ -98,6 +99,7 @@ struct thread_info { #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_MCA_INIT (1 << TIF_MCA_INIT) #define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED) +#define _TIF_FREEZE (1 << TIF_FREEZE) /* "work to do on user-return" bits */ #define TIF_ALLWORK_MASK (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index d339e2e88b1..3f32ca8bfec 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -122,6 +122,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 14 /* Force successful syscall return */ #define TIF_RESTORE_SIGMASK 15 /* Restore signal mask in do_signal */ +#define TIF_FREEZE 16 /* Freezing for suspend */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) @@ -138,6 +139,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_RESTOREALL (1<<TIF_RESTOREALL) #define _TIF_NOERROR (1<<TIF_NOERROR) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) +#define _TIF_FREEZE (1<<TIF_FREEZE) #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) #define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index 0c01dc55081..879f741105d 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 +#define TIF_FREEZE 19 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) @@ -114,6 +115,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) +#define _TIF_FREEZE (1<<TIF_FREEZE) #define _TIF_WORK_MASK 0x000000FE /* work to do on interrupt/exception return */ #define _TIF_ALLWORK_MASK 0x000000FF /* work to do on any return to u-space */ diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h index 787a08114b4..74a6c74397f 100644 --- a/include/asm-x86_64/thread_info.h +++ b/include/asm-x86_64/thread_info.h @@ -122,6 +122,7 @@ static inline struct thread_info *stack_thread_info(void) #define TIF_MEMDIE 20 #define TIF_DEBUG 21 /* uses debug registers */ #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ +#define TIF_FREEZE 23 /* is freezing for suspend */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) @@ -137,6 +138,7 @@ static inline struct thread_info *stack_thread_info(void) #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) #define _TIF_DEBUG (1<<TIF_DEBUG) #define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP) +#define _TIF_FREEZE (1<<TIF_FREEZE) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 39306309613..5e75e26d478 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -16,16 +16,15 @@ static inline int frozen(struct task_struct *p) */ static inline int freezing(struct task_struct *p) { - return p->flags & PF_FREEZE; + return test_tsk_thread_flag(p, TIF_FREEZE); } /* * Request that a process be frozen - * FIXME: SMP problem. We may not modify other process' flags! */ static inline void freeze(struct task_struct *p) { - p->flags |= PF_FREEZE; + set_tsk_thread_flag(p, TIF_FREEZE); } /* @@ -33,7 +32,7 @@ static inline void freeze(struct task_struct *p) */ static inline void do_not_freeze(struct task_struct *p) { - p->flags &= ~PF_FREEZE; + clear_tsk_thread_flag(p, TIF_FREEZE); } /* @@ -54,7 +53,9 @@ static inline int thaw_process(struct task_struct *p) */ static inline void frozen_process(struct task_struct *p) { - p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN; + p->flags |= PF_FROZEN; + wmb(); + clear_tsk_thread_flag(p, TIF_FREEZE); } extern void refrigerator(void); diff --git a/include/linux/sched.h b/include/linux/sched.h index ea92e5c8908..44637353519 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1144,7 +1144,6 @@ static inline void put_task_struct(struct task_struct *t) #define PF_MEMALLOC 0x00000800 /* Allocating memory */ #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ -#define PF_FREEZE 0x00004000 /* this task is being frozen for suspend now */ #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ diff --git a/kernel/power/process.c b/kernel/power/process.c index b9a32860bef..6d566bf7085 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -60,13 +60,16 @@ static inline void freeze_process(struct task_struct *p) unsigned long flags; if (!freezing(p)) { - if (p->state == TASK_STOPPED) - force_sig_specific(SIGSTOP, p); - - freeze(p); - spin_lock_irqsave(&p->sighand->siglock, flags); - signal_wake_up(p, p->state == TASK_STOPPED); - spin_unlock_irqrestore(&p->sighand->siglock, flags); + rmb(); + if (!frozen(p)) { + if (p->state == TASK_STOPPED) + force_sig_specific(SIGSTOP, p); + + freeze(p); + spin_lock_irqsave(&p->sighand->siglock, flags); + signal_wake_up(p, p->state == TASK_STOPPED); + spin_unlock_irqrestore(&p->sighand->siglock, flags); + } } } |