On Fri, Apr 27, 2007 at 11:29:34PM +0200, Rafael J. Wysocki wrote: > On Friday, 27 April 2007 22:20, Jeremy Fitzhardinge wrote: > > Rafael J. Wysocki wrote: > > > Makes sense. Please have a look at the updated patch below. > > > > > > Sam, does this one look better to you? > > > > > > > If freezer.c is in kernel/, then shouldn't the corresponding config var > > be in a non-arch Kconfig file? > > Well, I though it would look strange. Still, I can do that, of course:
It would have been much better to have a single kernel/Kconfig so you avoided all the arch specific source lines. But thats not this patch and can come later. So I'm OK with this one. Sam > > --- > From: Rafael J. Wysocki <[EMAIL PROTECTED]> > > Now that the freezer is used by kprobes, it is no longer a PM-specific piece > of > code. Move the freezer code out of kernel/power and introduce the > CONFIG_FREEZER option that will be chosen automatically if PM or KPROBES is > set. > > Signed-off-by: Rafael J. Wysocki <[EMAIL PROTECTED]> > --- > arch/arm/Kconfig | 2 > arch/avr32/Kconfig | 2 > arch/avr32/Kconfig.debug | 1 > arch/blackfin/Kconfig | 2 > arch/frv/Kconfig | 2 > arch/i386/Kconfig | 3 > arch/ia64/Kconfig | 3 > arch/mips/Kconfig | 2 > arch/powerpc/Kconfig | 3 > arch/ppc/Kconfig | 2 > arch/s390/Kconfig | 3 > arch/sh/Kconfig | 2 > arch/sparc64/Kconfig | 3 > arch/x86_64/Kconfig | 3 > include/linux/freezer.h | 2 > kernel/Kconfig.freezer | 5 > kernel/Makefile | 1 > kernel/freezer.c | 236 > +++++++++++++++++++++++++++++++++++++++++++++++ > kernel/kprobes.c | 2 > kernel/power/Kconfig | 1 > kernel/power/Makefile | 2 > kernel/power/process.c | 236 > ----------------------------------------------- > 22 files changed, 279 insertions(+), 239 deletions(-) > > Index: linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/x86_64/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig 2007-04-27 23:20:43.000000000 > +0200 > @@ -703,6 +703,8 @@ config GENERIC_PENDING_IRQ > depends on GENERIC_HARDIRQS && SMP > default y > > +source "kernel/Kconfig.freezer" > + > menu "Power management options" > > source kernel/power/Kconfig > @@ -791,6 +793,7 @@ source "arch/x86_64/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on KALLSYMS && EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/avr32/Kconfig.debug 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug 2007-04-27 > 21:54:19.000000000 +0200 > @@ -12,6 +12,7 @@ menu "Instrumentation Support" > config KPROBES > bool "Kprobes" > depends on DEBUG_KERNEL > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/frv/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/frv/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/frv/Kconfig 2007-04-27 23:13:27.000000000 > +0200 > @@ -364,6 +364,8 @@ source "drivers/pcmcia/Kconfig" > # sleep-deprived psychotic hacker types can say Y now, everyone else > # should probably wait a while. > > +source "kernel/Kconfig.freezer" > + > menu "Power management options" > source kernel/power/Kconfig > endmenu > Index: linux-2.6.21-rc7-mm2/arch/i386/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/i386/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/i386/Kconfig 2007-04-27 23:17:36.000000000 > +0200 > @@ -912,6 +912,8 @@ config ARCH_ENABLE_MEMORY_HOTPLUG > def_bool y > depends on HIGHMEM > > +source "kernel/Kconfig.freezer" > + > menu "Power management options (ACPI, APM)" > depends on !X86_VOYAGER > > @@ -1218,6 +1220,7 @@ source "arch/i386/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on KALLSYMS && EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/ia64/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/ia64/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/ia64/Kconfig 2007-04-27 23:21:40.000000000 > +0200 > @@ -495,6 +495,8 @@ source "fs/Kconfig.binfmt" > > endmenu > > +source "kernel/Kconfig.freezer" > + > menu "Power management and ACPI" > > source "kernel/power/Kconfig" > @@ -582,6 +584,7 @@ source "arch/ia64/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on KALLSYMS && EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/powerpc/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig 2007-04-27 23:15:12.000000000 > +0200 > @@ -552,6 +552,8 @@ config CMDLINE > some command-line options at build time by entering them here. In > most cases you will need to specify the root device here. > > +source kernel/Kconfig.freezer > + > if !44x || BROKEN > source kernel/power/Kconfig > endif > @@ -865,6 +867,7 @@ source "arch/powerpc/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on !BOOKE && !4xx && KALLSYMS && EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/ppc/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/ppc/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/ppc/Kconfig 2007-04-27 23:15:25.000000000 > +0200 > @@ -1153,6 +1153,8 @@ config PROC_HARDWARE > > source "drivers/zorro/Kconfig" > > +source "kernel/Kconfig.freezer" > + > if !44x || BROKEN > source kernel/power/Kconfig > endif > Index: linux-2.6.21-rc7-mm2/arch/s390/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/s390/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/s390/Kconfig 2007-04-27 23:23:19.000000000 > +0200 > @@ -550,6 +550,8 @@ source "drivers/net/Kconfig" > > source "fs/Kconfig" > > +source "kernel/Kconfig.freezer" > + > menu "Instrumentation Support" > > source "arch/s390/oprofile/Kconfig" > @@ -557,6 +559,7 @@ source "arch/s390/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/arch/sh/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/sh/Kconfig 2007-04-27 21:41:05.000000000 > +0200 > +++ linux-2.6.21-rc7-mm2/arch/sh/Kconfig 2007-04-27 23:23:33.000000000 > +0200 > @@ -699,6 +699,8 @@ source "fs/Kconfig.binfmt" > > endmenu > > +source "kernel/Kconfig.freezer" > + > menu "Power management options (EXPERIMENTAL)" > depends on EXPERIMENTAL > > Index: linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/sparc64/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig 2007-04-27 23:23:44.000000000 > +0200 > @@ -420,6 +420,8 @@ source "drivers/fc4/Kconfig" > > source "fs/Kconfig" > > +source "kernel/Kconfig.freezer" > + > menu "Instrumentation Support" > depends on EXPERIMENTAL > > @@ -428,6 +430,7 @@ source "arch/sparc64/oprofile/Kconfig" > config KPROBES > bool "Kprobes (EXPERIMENTAL)" > depends on KALLSYMS && EXPERIMENTAL && MODULES > + select FREEZER > help > Kprobes allows you to trap at almost any kernel address and > execute a callback function. register_kprobe() establishes > Index: linux-2.6.21-rc7-mm2/kernel/Makefile > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/kernel/Makefile 2007-04-27 21:41:05.000000000 > +0200 > +++ linux-2.6.21-rc7-mm2/kernel/Makefile 2007-04-27 21:41:28.000000000 > +0200 > @@ -33,6 +33,7 @@ obj-$(CONFIG_MODULES) += module.o > obj-$(CONFIG_KALLSYMS) += kallsyms.o > obj-$(CONFIG_STACK_UNWIND) += unwind.o > obj-$(CONFIG_PM) += power/ > +obj-$(CONFIG_FREEZER) += freezer.o > obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o > obj-$(CONFIG_KEXEC) += kexec.o > obj-$(CONFIG_COMPAT) += compat.o > Index: linux-2.6.21-rc7-mm2/kernel/power/Makefile > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/kernel/power/Makefile 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/kernel/power/Makefile 2007-04-27 > 21:41:28.000000000 +0200 > @@ -3,7 +3,7 @@ ifeq ($(CONFIG_PM_DEBUG),y) > EXTRA_CFLAGS += -DDEBUG > endif > > -obj-y := main.o process.o console.o notify.o > +obj-y := main.o console.o notify.o > obj-$(CONFIG_PM_LEGACY) += pm.o > obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o swap.o > user.o > > Index: linux-2.6.21-rc7-mm2/kernel/kprobes.c > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/kernel/kprobes.c 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/kernel/kprobes.c 2007-04-27 21:41:28.000000000 > +0200 > @@ -108,7 +108,7 @@ static int collect_garbage_slots(void); > static int __kprobes check_safety(void) > { > int ret = 0; > -#if defined(CONFIG_PREEMPT) && defined(CONFIG_PM) > +#ifdef CONFIG_PREEMPT > ret = freeze_processes(); > if (ret == 0) { > struct task_struct *p, *q; > Index: linux-2.6.21-rc7-mm2/include/linux/freezer.h > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/include/linux/freezer.h 2007-04-27 > 21:41:27.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/include/linux/freezer.h 2007-04-27 > 23:20:23.000000000 +0200 > @@ -2,7 +2,7 @@ > > #include <linux/sched.h> > > -#ifdef CONFIG_PM > +#ifdef CONFIG_FREEZER > /* > * Check if a process has been frozen > */ > Index: linux-2.6.21-rc7-mm2/arch/arm/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/arm/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/arm/Kconfig 2007-04-27 23:11:10.000000000 > +0200 > @@ -925,6 +925,8 @@ config ARTHUR > > endmenu > > +source "kernel/Kconfig.freezer" > + > menu "Power management options" > > source "kernel/power/Kconfig" > Index: linux-2.6.21-rc7-mm2/arch/blackfin/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/blackfin/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/blackfin/Kconfig 2007-04-27 > 23:13:09.000000000 +0200 > @@ -816,6 +816,8 @@ source "fs/Kconfig.binfmt" > > endmenu > > +source "kernel/Kconfig.freezer" > + > menu "Power management options" > source "kernel/power/Kconfig" > > Index: linux-2.6.21-rc7-mm2/arch/mips/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/mips/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/mips/Kconfig 2007-04-27 23:22:37.000000000 > +0200 > @@ -2067,6 +2067,8 @@ source "drivers/pci/hotplug/Kconfig" > > endmenu > > +source "kernel/Kconfig.freezer" > + > menu "Executable file formats" > > source "fs/Kconfig.binfmt" > Index: linux-2.6.21-rc7-mm2/kernel/freezer.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.21-rc7-mm2/kernel/freezer.c 2007-04-27 23:20:23.000000000 > +0200 > @@ -0,0 +1,236 @@ > +/* > + * linux/kernel/freezer.c > + * > + * Generic mechanism for freezing and thawing tasks, originally from swsusp. > + * > + * Distributed under the GPLv2 > + */ > + > + > +#undef DEBUG > + > +#include <linux/sched.h> > +#include <linux/interrupt.h> > +#include <linux/module.h> > +#include <linux/syscalls.h> > +#include <linux/freezer.h> > + > +/* > + * Timeout for stopping processes > + */ > +#define TIMEOUT (20 * HZ) > + > +#define FREEZER_KERNEL_THREADS 0 > +#define FREEZER_USER_SPACE 1 > + > +static inline int freezeable(struct task_struct * p) > +{ > + if ((p == current) || > + (p->flags & PF_NOFREEZE) || > + (p->exit_state != 0)) > + return 0; > + return 1; > +} > + > +/* > + * freezing is complete, mark current process as frozen > + */ > +static inline void frozen_process(void) > +{ > + if (!unlikely(current->flags & PF_NOFREEZE)) { > + current->flags |= PF_FROZEN; > + wmb(); > + } > + clear_tsk_thread_flag(current, TIF_FREEZE); > +} > + > +/* Refrigerator is place where frozen processes are stored :-). */ > +void refrigerator(void) > +{ > + /* Hmm, should we be allowed to suspend when there are realtime > + processes around? */ > + long save; > + > + task_lock(current); > + if (freezing(current)) { > + frozen_process(); > + task_unlock(current); > + } else { > + task_unlock(current); > + return; > + } > + save = current->state; > + pr_debug("%s entered refrigerator\n", current->comm); > + > + spin_lock_irq(¤t->sighand->siglock); > + recalc_sigpending(); /* We sent fake signal, clean it up */ > + spin_unlock_irq(¤t->sighand->siglock); > + > + for (;;) { > + set_current_state(TASK_UNINTERRUPTIBLE); > + if (!frozen(current)) > + break; > + schedule(); > + } > + pr_debug("%s left refrigerator\n", current->comm); > + current->state = save; > +} > + > +static inline void freeze_process(struct task_struct *p) > +{ > + unsigned long flags; > + > + if (!freezing(p)) { > + 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); > + } > + } > +} > + > +static void cancel_freezing(struct task_struct *p) > +{ > + unsigned long flags; > + > + if (freezing(p)) { > + pr_debug(" clean up: %s\n", p->comm); > + do_not_freeze(p); > + spin_lock_irqsave(&p->sighand->siglock, flags); > + recalc_sigpending_tsk(p); > + spin_unlock_irqrestore(&p->sighand->siglock, flags); > + } > +} > + > +static inline int is_user_space(struct task_struct *p) > +{ > + int ret; > + > + task_lock(p); > + ret = p->mm && !(p->flags & PF_BORROWED_MM); > + task_unlock(p); > + return ret; > +} > + > +static unsigned int try_to_freeze_tasks(int freeze_user_space) > +{ > + struct task_struct *g, *p; > + unsigned long end_time; > + unsigned int todo; > + > + end_time = jiffies + TIMEOUT; > + do { > + todo = 0; > + read_lock(&tasklist_lock); > + do_each_thread(g, p) { > + if (!freezeable(p)) > + continue; > + > + if (frozen(p)) > + continue; > + > + if (p->state == TASK_TRACED && frozen(p->parent)) { > + cancel_freezing(p); > + continue; > + } > + if (freeze_user_space && !is_user_space(p)) > + continue; > + > + freeze_process(p); > + if (!freezer_should_skip(p)) > + todo++; > + } while_each_thread(g, p); > + read_unlock(&tasklist_lock); > + yield(); /* Yield is okay here */ > + if (todo && time_after(jiffies, end_time)) > + break; > + } while (todo); > + > + if (todo) { > + /* This does not unfreeze processes that are already frozen > + * (we have slightly ugly calling convention in that respect, > + * and caller must call thaw_processes() if something fails), > + * but it cleans up leftover PF_FREEZE requests. > + */ > + printk("\n"); > + printk(KERN_ERR "Stopping %s timed out after %d seconds " > + "(%d tasks refusing to freeze):\n", > + freeze_user_space ? "user space processes" : > + "kernel threads", > + TIMEOUT / HZ, todo); > + read_lock(&tasklist_lock); > + do_each_thread(g, p) { > + if (freeze_user_space && !is_user_space(p)) > + continue; > + > + task_lock(p); > + if (freezeable(p) && !frozen(p) && > + !freezer_should_skip(p)) > + printk(KERN_ERR " %s\n", p->comm); > + > + cancel_freezing(p); > + task_unlock(p); > + } while_each_thread(g, p); > + read_unlock(&tasklist_lock); > + } > + > + return todo; > +} > + > +/** > + * freeze_processes - tell processes to enter the refrigerator > + * > + * Returns 0 on success, or the number of processes that didn't freeze, > + * although they were told to. > + */ > +int freeze_processes(void) > +{ > + unsigned int nr_unfrozen; > + > + printk("Stopping tasks ... "); > + nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE); > + if (nr_unfrozen) > + return nr_unfrozen; > + > + sys_sync(); > + nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); > + if (nr_unfrozen) > + return nr_unfrozen; > + > + printk("done.\n"); > + BUG_ON(in_atomic()); > + return 0; > +} > + > +static void thaw_tasks(int thaw_user_space) > +{ > + struct task_struct *g, *p; > + > + read_lock(&tasklist_lock); > + do_each_thread(g, p) { > + if (!freezeable(p)) > + continue; > + > + if (is_user_space(p) == !thaw_user_space) > + continue; > + > + thaw_process(p); > + } while_each_thread(g, p); > + read_unlock(&tasklist_lock); > +} > + > +void thaw_processes(void) > +{ > + printk("Restarting tasks ... "); > + thaw_tasks(FREEZER_KERNEL_THREADS); > + thaw_tasks(FREEZER_USER_SPACE); > + schedule(); > + printk("done.\n"); > +} > + > +EXPORT_SYMBOL(refrigerator); > Index: linux-2.6.21-rc7-mm2/kernel/power/process.c > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/kernel/power/process.c 2007-04-27 > 21:41:27.000000000 +0200 > +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 > @@ -1,236 +0,0 @@ > -/* > - * drivers/power/process.c - Functions for starting/stopping processes on > - * suspend transitions. > - * > - * Originally from swsusp. > - */ > - > - > -#undef DEBUG > - > -#include <linux/sched.h> > -#include <linux/interrupt.h> > -#include <linux/suspend.h> > -#include <linux/module.h> > -#include <linux/syscalls.h> > -#include <linux/freezer.h> > - > -/* > - * Timeout for stopping processes > - */ > -#define TIMEOUT (20 * HZ) > - > -#define FREEZER_KERNEL_THREADS 0 > -#define FREEZER_USER_SPACE 1 > - > -static inline int freezeable(struct task_struct * p) > -{ > - if ((p == current) || > - (p->flags & PF_NOFREEZE) || > - (p->exit_state != 0)) > - return 0; > - return 1; > -} > - > -/* > - * freezing is complete, mark current process as frozen > - */ > -static inline void frozen_process(void) > -{ > - if (!unlikely(current->flags & PF_NOFREEZE)) { > - current->flags |= PF_FROZEN; > - wmb(); > - } > - clear_tsk_thread_flag(current, TIF_FREEZE); > -} > - > -/* Refrigerator is place where frozen processes are stored :-). */ > -void refrigerator(void) > -{ > - /* Hmm, should we be allowed to suspend when there are realtime > - processes around? */ > - long save; > - > - task_lock(current); > - if (freezing(current)) { > - frozen_process(); > - task_unlock(current); > - } else { > - task_unlock(current); > - return; > - } > - save = current->state; > - pr_debug("%s entered refrigerator\n", current->comm); > - > - spin_lock_irq(¤t->sighand->siglock); > - recalc_sigpending(); /* We sent fake signal, clean it up */ > - spin_unlock_irq(¤t->sighand->siglock); > - > - for (;;) { > - set_current_state(TASK_UNINTERRUPTIBLE); > - if (!frozen(current)) > - break; > - schedule(); > - } > - pr_debug("%s left refrigerator\n", current->comm); > - current->state = save; > -} > - > -static inline void freeze_process(struct task_struct *p) > -{ > - unsigned long flags; > - > - if (!freezing(p)) { > - 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); > - } > - } > -} > - > -static void cancel_freezing(struct task_struct *p) > -{ > - unsigned long flags; > - > - if (freezing(p)) { > - pr_debug(" clean up: %s\n", p->comm); > - do_not_freeze(p); > - spin_lock_irqsave(&p->sighand->siglock, flags); > - recalc_sigpending_tsk(p); > - spin_unlock_irqrestore(&p->sighand->siglock, flags); > - } > -} > - > -static inline int is_user_space(struct task_struct *p) > -{ > - int ret; > - > - task_lock(p); > - ret = p->mm && !(p->flags & PF_BORROWED_MM); > - task_unlock(p); > - return ret; > -} > - > -static unsigned int try_to_freeze_tasks(int freeze_user_space) > -{ > - struct task_struct *g, *p; > - unsigned long end_time; > - unsigned int todo; > - > - end_time = jiffies + TIMEOUT; > - do { > - todo = 0; > - read_lock(&tasklist_lock); > - do_each_thread(g, p) { > - if (!freezeable(p)) > - continue; > - > - if (frozen(p)) > - continue; > - > - if (p->state == TASK_TRACED && frozen(p->parent)) { > - cancel_freezing(p); > - continue; > - } > - if (freeze_user_space && !is_user_space(p)) > - continue; > - > - freeze_process(p); > - if (!freezer_should_skip(p)) > - todo++; > - } while_each_thread(g, p); > - read_unlock(&tasklist_lock); > - yield(); /* Yield is okay here */ > - if (todo && time_after(jiffies, end_time)) > - break; > - } while (todo); > - > - if (todo) { > - /* This does not unfreeze processes that are already frozen > - * (we have slightly ugly calling convention in that respect, > - * and caller must call thaw_processes() if something fails), > - * but it cleans up leftover PF_FREEZE requests. > - */ > - printk("\n"); > - printk(KERN_ERR "Stopping %s timed out after %d seconds " > - "(%d tasks refusing to freeze):\n", > - freeze_user_space ? "user space processes" : > - "kernel threads", > - TIMEOUT / HZ, todo); > - read_lock(&tasklist_lock); > - do_each_thread(g, p) { > - if (freeze_user_space && !is_user_space(p)) > - continue; > - > - task_lock(p); > - if (freezeable(p) && !frozen(p) && > - !freezer_should_skip(p)) > - printk(KERN_ERR " %s\n", p->comm); > - > - cancel_freezing(p); > - task_unlock(p); > - } while_each_thread(g, p); > - read_unlock(&tasklist_lock); > - } > - > - return todo; > -} > - > -/** > - * freeze_processes - tell processes to enter the refrigerator > - * > - * Returns 0 on success, or the number of processes that didn't freeze, > - * although they were told to. > - */ > -int freeze_processes(void) > -{ > - unsigned int nr_unfrozen; > - > - printk("Stopping tasks ... "); > - nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE); > - if (nr_unfrozen) > - return nr_unfrozen; > - > - sys_sync(); > - nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); > - if (nr_unfrozen) > - return nr_unfrozen; > - > - printk("done.\n"); > - BUG_ON(in_atomic()); > - return 0; > -} > - > -static void thaw_tasks(int thaw_user_space) > -{ > - struct task_struct *g, *p; > - > - read_lock(&tasklist_lock); > - do_each_thread(g, p) { > - if (!freezeable(p)) > - continue; > - > - if (is_user_space(p) == !thaw_user_space) > - continue; > - > - thaw_process(p); > - } while_each_thread(g, p); > - read_unlock(&tasklist_lock); > -} > - > -void thaw_processes(void) > -{ > - printk("Restarting tasks ... "); > - thaw_tasks(FREEZER_KERNEL_THREADS); > - thaw_tasks(FREEZER_USER_SPACE); > - schedule(); > - printk("done.\n"); > -} > - > -EXPORT_SYMBOL(refrigerator); > Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/arch/avr32/Kconfig 2007-04-27 > 01:00:50.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/arch/avr32/Kconfig 2007-04-27 23:12:42.000000000 > +0200 > @@ -209,6 +209,8 @@ source "drivers/Kconfig" > > source "fs/Kconfig" > > +source "kernel/Kconfig.freezer" > + > source "arch/avr32/Kconfig.debug" > > source "security/Kconfig" > Index: linux-2.6.21-rc7-mm2/kernel/power/Kconfig > =================================================================== > --- linux-2.6.21-rc7-mm2.orig/kernel/power/Kconfig 2007-04-27 > 21:41:05.000000000 +0200 > +++ linux-2.6.21-rc7-mm2/kernel/power/Kconfig 2007-04-27 21:42:52.000000000 > +0200 > @@ -1,6 +1,7 @@ > config PM > bool "Power Management support" > depends on !IA64_HP_SIM > + select FREEZER > ---help--- > "Power Management" means that parts of your computer are shut > off or put into a power conserving "sleep" mode if they are not > Index: linux-2.6.21-rc7-mm2/kernel/Kconfig.freezer > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.21-rc7-mm2/kernel/Kconfig.freezer 2007-04-27 > 23:06:52.000000000 +0200 > @@ -0,0 +1,5 @@ > +# Tasks freezer configuration > + > +config FREEZER > + bool > + default n > > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/