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: --- 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/