Separate freezer from PM code
Subsystems (23)
cover Separate freezer from PM code
Hi,
The first patch in the series separates the tasks freezer from the PM code and moves it to kernel/freezer.c . Some cleanups of freezer.c proposed by Gautham will be sent in a separate patch.
The second one moves all of the freezer-specific per-task flags to a separate filed of task_struct and defines functions for manipulating them with the help of set_bit() and friends. I think I have addressed all of the outstanding issues with it.
The patches are against 2.6.21-rc7-mm2 with the Gautham's patch from
http://lkml.org/lkml/2007/4/26/250 applied.
Greetings,
Rafael
Signature · 3 lines
If you don't have the time to read, you don't have the time or the tools to write. - Stephen King
PATCH 1/2 Separate freezer from PM code
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.
--- arch/arm/Kconfig | 5 arch/avr32/Kconfig.debug | 5 arch/blackfin/Kconfig | 5 arch/frv/Kconfig | 5 arch/i386/Kconfig | 5 arch/ia64/Kconfig | 5 arch/mips/Kconfig | 5 arch/powerpc/Kconfig | 5 arch/ppc/Kconfig | 5 arch/s390/Kconfig | 5 arch/sh/Kconfig | 5 arch/sparc64/Kconfig | 5 arch/x86_64/Kconfig | 8 + include/linux/freezer.h | 2 kernel/Makefile | 1 kernel/freezer.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/kprobes.c | 2 kernel/power/Makefile | 2 kernel/power/process.c | 236 ----------------------------------------------- 19 files changed, 308 insertions(+), 239 deletions(-)
arch/x86_64/Kconfig +8 -0
@@ -703,6 +703,14 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y +# +# Use the tasks freezer +# +config FREEZER + bool + default y + depends on PM || KPROBES + menu "Power management options" source kernel/power/Kconfig
arch/avr32/Kconfig.debug +5 -0
@@ -24,3 +24,8 @@ source "kernel/Kconfig.marker" endmenu endmenu + +config FREEZER + bool + default y + depends on KPROBES
arch/frv/Kconfig +5 -0
@@ -364,6 +364,11 @@ source "drivers/pcmcia/Kconfig" # sleep-deprived psychotic hacker types can say Y now, everyone else # should probably wait a while. +config FREEZER + bool + default y + depends on PM + menu "Power management options" source kernel/power/Kconfig endmenu
arch/i386/Kconfig +5 -0
@@ -912,6 +912,11 @@ config ARCH_ENABLE_MEMORY_HOTPLUG def_bool y depends on HIGHMEM +config FREEZER + bool + default y + depends on PM || KPROBES + menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER
arch/ia64/Kconfig +5 -0
@@ -495,6 +495,11 @@ source "fs/Kconfig.binfmt" endmenu +config FREEZER + bool + default y + depends on PM || KPROBES + menu "Power management and ACPI" source "kernel/power/Kconfig"
arch/powerpc/Kconfig +5 -0
@@ -552,6 +552,11 @@ 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. +config FREEZER + bool + default y + depends on PM || KPROBES + if !44x || BROKEN source kernel/power/Kconfig endif
arch/ppc/Kconfig +5 -0
@@ -1154,6 +1154,11 @@ config PROC_HARDWARE source "drivers/zorro/Kconfig" if !44x || BROKEN +config FREEZER + bool + default y + depends on PM + source kernel/power/Kconfig endif
arch/s390/Kconfig +5 -0
@@ -564,6 +564,11 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +config FREEZER + bool + default y + depends on KPROBES + source "kernel/Kconfig.marker" source "lib/Kconfig.statistic"
arch/sh/Kconfig +5 -0
@@ -699,6 +699,11 @@ source "fs/Kconfig.binfmt" endmenu +config FREEZER + bool + default y + depends on PM + menu "Power management options (EXPERIMENTAL)" depends on EXPERIMENTAL
arch/sparc64/Kconfig +5 -0
@@ -435,6 +435,11 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +config FREEZER + bool + default y + depends on KPROBES + source "kernel/Kconfig.marker" endmenu
kernel/Makefile +1 -0
@@ -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
kernel/power/Makefile +1 -1
@@ -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
kernel/kprobes.c +1 -1
@@ -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;
include/linux/freezer.h +1 -1
@@ -2,7 +2,7 @@#include <linux/sched.h> -#ifdef CONFIG_PM +#ifdef CONFIG_FREEZER /* * Check if a process has been frozen */
arch/arm/Kconfig +5 -0
@@ -929,6 +929,11 @@ menu "Power management options" source "kernel/power/Kconfig" +config FREEZER + bool + default y + depends on PM + endmenu source "net/Kconfig"
arch/blackfin/Kconfig +5 -0
@@ -819,6 +819,11 @@ endmenu menu "Power management options" source "kernel/power/Kconfig" +config FREEZER + bool + default y + depends on PM + choice prompt "Select PM Wakeup Event Source" default PM_WAKEUP_GPIO_BY_SIC_IWR
arch/mips/Kconfig +5 -0
@@ -2138,6 +2138,11 @@ config BINFMT_ELF32 source "kernel/power/Kconfig" +config FREEZER + bool + default y + depends on PM + endmenu source "net/Kconfig"
kernel/freezer.c new file +236 -0
236 lines not on this page · raw message
kernel/power/process.c deleted +0 -236
236 lines not on this page · raw message
Quoted 8 lines · Rafael J. Wysocki
Index: linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig
===================================================================arch/x86_64/Kconfig +0
-0@@ -703,6 +703,14 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y
arch/x86_64/Kconfig config GENERIC_PENDING_IRQ · line 714
Quoted 10 lines
arch/x86_64/Kconfig +8
-0+# +# Use the tasks freezer +# +config FREEZER + bool + default y + depends on PM || KPROBES + menu "Power management options"
Could we have this in a generic Kconfig file instead? IIRC the depends on line may refer to unknown options without spitting out warnings.
Sam
Quoted 5 lines · Rafael J. Wysocki
arch/x86_64/Kconfig +0
-0@@ -703,6 +703,14 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y
arch/x86_64/Kconfig config GENERIC_PENDING_IRQ · line 714
Quoted 10 lines
arch/x86_64/Kconfig +8
-0+# +# Use the tasks freezer +# +config FREEZER + bool + default y + depends on PM || KPROBES +
Shouldn't PM and KPROBES "select" FREEZER if they want it? That way its easier for other future users of FREEZER to do so without having to change the Kconfig here (and the other 23000 Kconfigs).
J
Quoted 7 lines · Jeremy Fitzhardinge
Quoted 6 lines · Rafael J. Wysocki
arch/x86_64/Kconfig +0
-0@@ -703,6 +703,14 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y
Quoted 13 lines
arch/x86_64/Kconfig config GENERIC_PENDING_IRQ · line 714
Quoted 9 lines
arch/x86_64/Kconfig +8
-0+# +# Use the tasks freezer +# +config FREEZER + bool + default y + depends on PM || KPROBES +Shouldn't PM and KPROBES "select" FREEZER if they want it? That way its easier for other future users of FREEZER to do so without having to change the
Kconfighere (and the other 23000 Kconfigs).
Makes sense. Please have a look at the updated patch below.
Sam, does this one look better to you?
---
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.
--- arch/arm/Kconfig | 4 arch/avr32/Kconfig | 4 arch/avr32/Kconfig.debug | 1 arch/blackfin/Kconfig | 4 arch/frv/Kconfig | 4 arch/i386/Kconfig | 5 arch/ia64/Kconfig | 5 arch/mips/Kconfig | 4 arch/powerpc/Kconfig | 5 arch/ppc/Kconfig | 4 arch/s390/Kconfig | 5 arch/sh/Kconfig | 4 arch/sparc64/Kconfig | 5 arch/x86_64/Kconfig | 5 include/linux/freezer.h | 2 kernel/Makefile | 1 kernel/freezer.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/kprobes.c | 2 kernel/power/Kconfig | 1 kernel/power/Makefile | 2 kernel/power/process.c | 236 ----------------------------------------------- 21 files changed, 300 insertions(+), 239 deletions(-)
arch/x86_64/Kconfig +5 -0
@@ -129,6 +129,10 @@ config ARCH_HAS_ILOG2_U64 bool default n +config FREEZER + bool + default n + source "init/Kconfig"
@@ -791,6 +795,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
arch/avr32/Kconfig.debug +1 -0
@@ -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
arch/frv/Kconfig +4 -0
@@ -57,6 +57,10 @@ config ARCH_USES_SLAB_PAGE_STRUCT bool default y +config FREEZER + bool + default n + mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig"
arch/i386/Kconfig +5 -0
@@ -87,6 +87,10 @@ config DMI bool default y +config FREEZER + bool + default n + source "init/Kconfig" menu "Processor type and features"
@@ -1218,6 +1222,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
arch/ia64/Kconfig +5 -0
@@ -90,6 +90,10 @@ config AUDIT_ARCH bool default y +config FREEZER + bool + default n + choice prompt "System type" default IA64_GENERIC
@@ -582,6 +586,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
arch/powerpc/Kconfig +5 -0
@@ -123,6 +123,10 @@ config DEFAULT_UIMAGE Used to allow a board to specify it wants a uImage built by default default n +config FREEZER + bool + default n + menu "Processor support" choice prompt "Processor Type"
@@ -865,6 +869,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
arch/ppc/Kconfig +4 -0
@@ -65,6 +65,10 @@ config GENERIC_BUG default y depends on BUG +config FREEZER + bool + default n + source "init/Kconfig" menu "Processor"
arch/s390/Kconfig +5 -0
@@ -52,6 +52,10 @@ config NO_IOMEM config NO_DMA def_bool y +config FREEZER + bool + default n + mainmenu "Linux Kernel Configuration" config S390
@@ -557,6 +561,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
arch/sh/Kconfig +4 -0
@@ -74,6 +74,10 @@ config ARCH_HAS_ILOG2_U64 bool default n +config FREEZER + bool + default n + source "init/Kconfig" menu "System type"
arch/sparc64/Kconfig +5 -0
@@ -58,6 +58,10 @@ config AUDIT_ARCH bool default y +config FREEZER + bool + default n + choice prompt "Kernel page size" default SPARC64_PAGE_SIZE_8KB
@@ -428,6 +432,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
kernel/Makefile +1 -0
@@ -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
kernel/power/Makefile +1 -1
@@ -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
kernel/kprobes.c +1 -1
@@ -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;
include/linux/freezer.h +1 -1
@@ -2,7 +2,7 @@#include <linux/sched.h> -#ifdef CONFIG_PM +#ifdef CONFIG_FREEZER /* * Check if a process has been frozen */
arch/arm/Kconfig +4 -0
@@ -41,6 +41,10 @@ config NO_IOPORT bool default n +config FREEZER + bool + default n + config EISA bool ---help---
arch/blackfin/Kconfig +4 -0
@@ -69,6 +69,10 @@ config IRQCHIP_DEMUX_GPIO bool default y +config FREEZER + bool + default n + source "init/Kconfig" source "kernel/Kconfig.preempt"
arch/mips/Kconfig +4 -0
@@ -877,6 +877,10 @@ config GENERIC_HARDIRQS_NO__DO_IRQ bool default n +config FREEZER + bool + default n + # # Select some configuration options automatically based on user selections. #
kernel/freezer.c new file +236 -0
236 lines not on this page · raw message
kernel/power/process.c deleted +0 -236
236 lines not on this page · raw message
arch/avr32/Kconfig +4 -0
@@ -73,6 +73,10 @@ config GENERIC_BUG default y depends on BUG +config FREEZER + bool + default n + source "init/Kconfig" menu "System Type and features"
kernel/power/Kconfig +1 -0
@@ -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
Quoted 4 lines · Rafael J. Wysocki
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?
J
Quoted 8 lines · Jeremy Fitzhardinge
Quoted 4 lines · Rafael J. Wysocki
Makes sense. Please have a look at the updated patch below.
Sam, does this one look better to you?
If
freezer.cis inkernel/, then shouldn't the corresponding config var be in a non-archKconfigfile?
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.
--- 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(-)
arch/x86_64/Kconfig +3 -0
@@ -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
arch/avr32/Kconfig.debug +1 -0
@@ -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
arch/frv/Kconfig +2 -0
@@ -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
arch/i386/Kconfig +3 -0
@@ -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
arch/ia64/Kconfig +3 -0
@@ -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
arch/powerpc/Kconfig +3 -0
@@ -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
arch/ppc/Kconfig +2 -0
@@ -1153,6 +1153,8 @@ config PROC_HARDWARE source "drivers/zorro/Kconfig" +source "kernel/Kconfig.freezer" + if !44x || BROKEN source kernel/power/Kconfig endif
arch/s390/Kconfig +3 -0
@@ -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
arch/sh/Kconfig +2 -0
@@ -699,6 +699,8 @@ source "fs/Kconfig.binfmt" endmenu +source "kernel/Kconfig.freezer" + menu "Power management options (EXPERIMENTAL)" depends on EXPERIMENTAL
arch/sparc64/Kconfig +3 -0
@@ -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
kernel/Makefile +1 -0
@@ -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
kernel/power/Makefile +1 -1
@@ -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
kernel/kprobes.c +1 -1
@@ -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;
include/linux/freezer.h +1 -1
@@ -2,7 +2,7 @@#include <linux/sched.h> -#ifdef CONFIG_PM +#ifdef CONFIG_FREEZER /* * Check if a process has been frozen */
arch/arm/Kconfig +2 -0
@@ -925,6 +925,8 @@ config ARTHUR endmenu +source "kernel/Kconfig.freezer" + menu "Power management options" source "kernel/power/Kconfig"
arch/blackfin/Kconfig +2 -0
@@ -816,6 +816,8 @@ source "fs/Kconfig.binfmt" endmenu +source "kernel/Kconfig.freezer" + menu "Power management options" source "kernel/power/Kconfig"
arch/mips/Kconfig +2 -0
@@ -2067,6 +2067,8 @@ source "drivers/pci/hotplug/Kconfig" endmenu +source "kernel/Kconfig.freezer" + menu "Executable file formats" source "fs/Kconfig.binfmt"
kernel/freezer.c new file +236 -0
236 lines not on this page · raw message
kernel/power/process.c deleted +0 -236
236 lines not on this page · raw message
arch/avr32/Kconfig +2 -0
@@ -209,6 +209,8 @@ source "drivers/Kconfig" source "fs/Kconfig" +source "kernel/Kconfig.freezer" + source "arch/avr32/Kconfig.debug" source "security/Kconfig"
kernel/power/Kconfig +1 -0
@@ -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
kernel/Kconfig.freezer new file +5 -0
@@ -0,0 +1,5 @@ +# Tasks freezer configuration + +config FREEZER + bool + default n
Quoted 11 lines · Rafael J. Wysocki
Quoted 8 lines · Jeremy Fitzhardinge
Quoted 4 lines · Rafael J. Wysocki
Makes sense. Please have a look at the updated patch below.
Sam, does this one look better to you?
If
freezer.cis inkernel/, then shouldn't the corresponding config var be in a non-archKconfigfile?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
Quoted 825 lines
---
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_FREEZERoption 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
===================================================================arch/x86_64/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug
===================================================================arch/avr32/Kconfig.debug +1
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/frv/Kconfig
===================================================================arch/frv/Kconfig +2
-0@@ -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 endmenuIndex: linux-2.6.21-rc7-mm2/arch/i386/Kconfig
===================================================================arch/i386/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/ia64/Kconfig
===================================================================arch/ia64/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig
===================================================================arch/powerpc/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/ppc/Kconfig
===================================================================arch/ppc/Kconfig +2
-0@@ -1153,6 +1153,8 @@ config PROC_HARDWARE source "drivers/zorro/Kconfig" +source "kernel/Kconfig.freezer" + if !44x || BROKEN source kernel/power/Kconfig endifIndex: linux-2.6.21-rc7-mm2/arch/s390/Kconfig
===================================================================arch/s390/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/arch/sh/Kconfig
===================================================================arch/sh/Kconfig +2
-0@@ -699,6 +699,8 @@ source "fs/Kconfig.binfmt" endmenu +source "kernel/Kconfig.freezer" + menu "Power management options (EXPERIMENTAL)" depends on EXPERIMENTALIndex: linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig
===================================================================arch/sparc64/Kconfig +3
-0@@ -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() establishesIndex: linux-2.6.21-rc7-mm2/kernel/Makefile
===================================================================kernel/Makefile +1
-0@@ -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.oIndex: linux-2.6.21-rc7-mm2/kernel/power/Makefile
===================================================================kernel/power/Makefile +1
-1@@ -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.oIndex:
linux-2.6.21-rc7-mm2/kernel/kprobes.c
===================================================================kernel/kprobes.c +1
-1@@ -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
===================================================================include/linux/freezer.h +1
-1@@ -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
===================================================================arch/arm/Kconfig +2
-0@@ -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
===================================================================arch/blackfin/Kconfig +2
-0@@ -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
===================================================================arch/mips/Kconfig +2
-0@@ -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
===================================================================kernel/freezer.c new file +236
-0@@ -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
===================================================================kernel/power/process.c deleted +0
-236@@ -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
===================================================================arch/avr32/Kconfig +2
-0@@ -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
===================================================================kernel/power/Kconfig +1
-0@@ -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 notIndex: linux-2.6.21-rc7-mm2/kernel/Kconfig.freezer
===================================================================kernel/Kconfig.freezer new file +5
-1@@ -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/
PATCH 2/2 Introduce freezer flags
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Move all of the freezer-related flags to a separate field in task_struct and introduce functions to operate them using set_bit() etc.
--- Documentation/power/kernel_threads.txt | 2 - Documentation/power/swsusp.txt | 4 +- arch/i386/kernel/apm.c | 2 - drivers/block/loop.c | 2 - drivers/char/apm-emulation.c | 6 +-- drivers/ieee1394/ieee1394_core.c | 2 - drivers/md/md.c | 2 - drivers/mmc/card/queue.c | 3 + drivers/mtd/mtd_blkdevs.c | 3 + drivers/scsi/libsas/sas_scsi_host.c | 2 - drivers/scsi/scsi_error.c | 2 - drivers/usb/storage/usb.c | 2 - include/asm-arm/thread_info.h | 2 - include/asm-blackfin/thread_info.h | 2 - include/asm-frv/thread_info.h | 2 - include/asm-i386/thread_info.h | 2 - include/asm-ia64/thread_info.h | 2 - include/asm-mips/thread_info.h | 2 - include/asm-powerpc/thread_info.h | 2 - include/asm-sh/thread_info.h | 2 - include/asm-x86_64/thread_info.h | 2 - include/linux/freezer.h | 63 +++++++++++++++++++++++++++------ include/linux/sched.h | 8 ++-- kernel/fork.c | 5 ++ kernel/freezer.c | 10 ++--- kernel/kthread.c | 3 + kernel/rcutorture.c | 4 +- kernel/sched.c | 2 - kernel/softirq.c | 2 - kernel/softlockup.c | 2 - kernel/workqueue.c | 2 - 31 files changed, 90 insertions(+), 61 deletions(-)
include/linux/sched.h +4 -4
@@ -1006,7 +1006,10 @@ struct task_struct {/* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif - +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags; +#endif #ifdef CONFIG_DEBUG_MUTEXES /* mutex deadlock detection */ struct mutex_waiter *blocked_on;
@@ -1189,8 +1192,6 @@ static inline void put_task_struct(struc#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_NOFREEZE 0x00008000/* this thread should not be frozen */ -#define PF_FROZEN 0x00010000/* frozen for system suspend */ #define PF_FSTRANS 0x00020000/* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000/* I am kswapd */ #define PF_SWAPOFF 0x00080000/* I am in swapoff */
@@ -1202,7 +1203,6 @@ static inline void put_task_struct(struc#define PF_SPREAD_SLAB 0x02000000/* Spread some slab caches over cpuset */ #define PF_MEMPOLICY 0x10000000/* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000/* Thread belongs to the rt mutex tester */ -#define PF_FREEZER_SKIP 0x40000000/* Freezer should not count it as freezeable */ /* * Only the _current_ task can read/write to tsk->flags, but other
include/asm-arm/thread_info.h +0 -2
@@ -147,7 +147,6 @@ extern void iwmmxt_task_switch(struct th#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)
@@ -155,7 +154,6 @@ extern void iwmmxt_task_switch(struct th#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
include/asm-blackfin/thread_info.h +0 -2
@@ -125,7 +125,6 @@ static inline struct thread_info *currenTIF_NEED_RESCHED */ #define TIF_MEMDIE 5#define TIF_RESTORE_SIGMASK 6/* restore signal mask in do_signal() */ -#define TIF_FREEZE 7/* is freezing for suspend */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -134,7 +133,6 @@ static inline struct thread_info *curren#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) -#define _TIF_FREEZE (1<<TIF_FREEZE)#define _TIF_WORK_MASK 0x0000FFFE/* work to do on interrupt/exception return */
include/asm-frv/thread_info.h +0 -2
@@ -116,7 +116,6 @@ register struct thread_info *__current_t#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)
@@ -126,7 +125,6 @@ register struct thread_info *__current_t#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 */
include/asm-i386/thread_info.h +0 -2
@@ -136,7 +136,6 @@ static inline struct thread_info *curren#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)
@@ -150,7 +149,6 @@ static inline struct thread_info *curren#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 \
include/asm-ia64/thread_info.h +0 -2
@@ -89,7 +89,6 @@ 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)
@@ -101,7 +100,6 @@ 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)
include/asm-mips/thread_info.h +0 -2
@@ -118,7 +118,6 @@ register struct thread_info *__current_t#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 31/* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -130,7 +129,6 @@ register struct thread_info *__current_t#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)/* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
include/asm-powerpc/thread_info.h +0 -2
@@ -122,7 +122,6 @@ static inline struct thread_info *curren#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)
@@ -139,7 +138,6 @@ static inline struct thread_info *curren#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 | \
include/asm-sh/thread_info.h +0 -2
@@ -115,7 +115,6 @@ static inline struct thread_info *curren#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)
@@ -125,7 +124,6 @@ static inline struct thread_info *curren#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)#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 */
include/asm-x86_64/thread_info.h +0 -2
@@ -122,7 +122,6 @@ static inline struct thread_info *stack_#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)
@@ -138,7 +137,6 @@ static inline struct thread_info *stack_#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 \
include/linux/freezer.h +52 -11
125 lines not on this page · raw message
kernel/sched.c +1 -1
@@ -5478,7 +5478,7 @@ migration_call(struct notifier_block *nf p =kthread_create (migration_thread, hcpu,"migration/%d" ,cpu);if (IS_ERR (p))return NOTIFY_BAD ; - p->flags |=PF_NOFREEZE ; +freezer_exempt (p);kthread_bind (p, cpu);/* Must be high prio: stop_machine expects to yield to it. */ rq =task_rq_lock (p, &flags);
arch/i386/kernel/apm.c +1 -1
@@ -2313,7 +2313,7 @@ static int __init apm_init(void)remove_proc_entry ("apm" ,NULL );return err; } - kapmd_task->flags |=PF_NOFREEZE ; +freezer_exempt (kapmd_task);wake_up_process (kapmd_task);if (num_online_cpus () >1 && !smp ) {
drivers/block/loop.c +1 -1
@@ -582,7 +582,7 @@ static int loop_thread(void *data)* hence, it mustn't be stopped at all * because it could be indirectly used during suspension */ - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);set_user_nice (current,-20 );
drivers/char/apm-emulation.c +3 -3
@@ -336,7 +336,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);wait_event (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -372,7 +372,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);wait_event_interruptible (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -601,7 +601,7 @@ static int __init apm_init(void) kapmd_tsk =NULL ;return ret; } - kapmd_tsk->flags |=PF_NOFREEZE ; +freezer_exempt (kapmd_tsk);wake_up_process (kapmd_tsk);#ifdef CONFIG_PROC_FS
drivers/ieee1394/ieee1394_core.c +1 -1
@@ -1134,7 +1134,7 @@ static int hpsbpkt_thread(void *__hi)struct list_head tmp;int may_schedule; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);while (!kthread_should_stop ()) {
drivers/md/md.c +1 -1
@@ -4541,7 +4541,7 @@ static int md_thread(void * arg)* many dirty RAID5 blocks. */ - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);while (!kthread_should_stop ()) {/* We need to wait INTERRUPTIBLE so that
drivers/mmc/card/queue.c +2 -1
@@ -66,7 +66,8 @@ static int mmc_queue_thread(void *d)* Set iothread to ensure that we aren't put to sleep by * the process freezing. We handle suspension ourselves. */ - current->flags |=PF_MEMALLOC |PF_NOFREEZE ; + current->flags |=PF_MEMALLOC ; +freezer_exempt (current);down (&mq->thread_sem); do {
drivers/mtd/mtd_blkdevs.c +2 -1
@@ -81,7 +81,8 @@ static int mtd_blktrans_thread(void *argstruct request_queue *rq = tr->blkcore_priv->rq;/* we might get involved when memory gets low, so use PF_MEMALLOC */ - current->flags |=PF_MEMALLOC |PF_NOFREEZE ; + current->flags |=PF_MEMALLOC ; +freezer_exempt (current);spin_lock_irq (rq->queue_lock);while (!kthread_should_stop ()) {
drivers/scsi/libsas/sas_scsi_host.c +1 -1
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_hstruct sas_ha_struct *sas_ha = _sas_ha;struct scsi_core *core = &sas_ha->core; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);complete (&queue_th_comp);
drivers/scsi/scsi_error.c +1 -1
@@ -1536,7 +1536,7 @@ int scsi_error_handler(void *data) {struct Scsi_Host *shost = data; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);/* * We use TASK_INTERRUPTIBLE so that the thread is not
drivers/usb/storage/usb.c +1 -1
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(voidstruct us_data *us = (struct us_data *)__us;struct Scsi_Host *host =us_to_host (us); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {try_to_freeze ();
kernel/fork.c +4 -1
@@ -921,11 +921,14 @@ static inline void copy_flags(unsigned l {unsigned long new_flags = p->flags; - new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE ); + new_flags &= ~PF_SUPERPRIV ; new_flags |=PF_FORKNOEXEC ;if (!(clone_flags &CLONE_PTRACE )) p->ptrace =0 ; p->flags = new_flags; +#ifdef CONFIG_FREEZER + p->freezer_flags =0 ; +#endif }asmlinkage long sys_set_tid_address (int __user *tidptr)
kernel/rcutorture.c +2 -2
@@ -559,7 +559,7 @@ rcu_torture_fakewriter(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_fakewriter task started" );set_user_nice (current,19 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current); do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
@@ -590,7 +590,7 @@ rcu_torture_reader(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_reader task started" );set_user_nice (current,19 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current); do { idx = cur_ops->readlock();
kernel/softirq.c +1 -1
@@ -490,7 +490,7 @@ void __init softirq_init(void)static int ksoftirqd (void * __bind_cpu) {set_user_nice (current,15 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);set_current_state (TASK_INTERRUPTIBLE );
kernel/softlockup.c +1 -1
@@ -117,7 +117,7 @@ static int watchdog(void * __bind_cpu)struct sched_param param = { .sched_priority =MAX_RT_PRIO -1 };sched_setscheduler (current,SCHED_FIFO , ¶m); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);/* initialize timestamp */ touch_softlockup_watchdog ();
kernel/workqueue.c +1 -1
@@ -291,7 +291,7 @@ static int worker_thread(void *__cwq)DEFINE_WAIT (wait);if (!cwq->wq->freezeable) - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {prepare_to_wait (&cwq->more_work, &wait,TASK_INTERRUPTIBLE );
kernel/freezer.c +5 -5
@@ -26,7 +26,7 @@static inline int freezeable (struct task_struct * p) {if ((p == current) || - (p->flags &PF_NOFREEZE ) || +freezer_should_exempt (p) || (p->exit_state !=0 ))return 0 ;return 1 ;
@@ -37,11 +37,11 @@ static inline int freezeable(struct task*/ static inline void frozen_process (void ) { -if (!unlikely (current->flags &PF_NOFREEZE )) { - current->flags |=PF_FROZEN ; +if (!unlikely (freezer_should_exempt (current))) { +set_frozen_flag (current);wmb (); } -clear_tsk_thread_flag (current,TIF_FREEZE ); +clear_freeze_flag (current); }/* Refrigerator is place where frozen processes are stored :-). */
@@ -100,7 +100,7 @@ static void cancel_freezing(struct task_if (freezing (p)) {pr_debug (" clean up: %s\n" , p->comm); -do_not_freeze (p); +clear_freeze_flag (p);spin_lock_irqsave (&p->sighand->siglock, flags);recalc_sigpending_tsk (p);spin_unlock_irqrestore (&p->sighand->siglock, flags);
Documentation/power/kernel_threads.txt +1 -1
@@ -32,7 +32,7 @@ like this: */ daemonize("usb-storage"); - current->flags |= PF_NOFREEZE; + freezer_exempt(current); from drivers/usb/storage/usb.c::usb_stor_control_thread()
Documentation/power/swsusp.txt +2 -2
@@ -152,8 +152,8 @@ add: try_to_freeze(); If the thread is needed for writing the image to storage, you should -instead set the PF_NOFREEZE process flag when creating the thread (and -be very careful). +instead use freezer_exempt() to mark the thread as nonfreezable when creating +it (and be very careful). Q: What is the difference between "platform" and "shutdown"?
kernel/kthread.c +2 -1
@@ -13,6 +13,7 @@#include <linux/file.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/freezer.h> #include <asm/semaphore.h> static DEFINE_SPINLOCK (kthread_create_lock);
@@ -232,7 +233,7 @@ int kthreadd(void *unused)/* Setup a clean context for our children to inherit. */ kthreadd_setup (); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {set_current_state (TASK_INTERRUPTIBLE );
Re: [PATCH -mm 2/2] Introduce freezer flags
Quoted 6 lines · Rafael J. Wysocki
kernel/fork.c +0
-0@@ -921,11 +921,14 @@ static inline void copy_flags(unsigned l {unsigned long new_flags = p->flags;
kernel/fork.c static inline void copy_flags(unsigned l · line 932
Quoted 10 lines
kernel/fork.c +4
-1- new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE ); + new_flags &= ~PF_SUPERPRIV ; new_flags |=PF_FORKNOEXEC ;if (!(clone_flags &CLONE_PTRACE )) p->ptrace =0 ; p->flags = new_flags; +#ifdef CONFIG_FREEZER + p->freezer_flags =0 ; +#endif }
Could we have a dedicated clear_freeze_flag() so we could drop the ifdef?
kernel/fork.c static inline void copy_flags(unsigned l · line 933
Quoted 1 line
kernel/fork.c +1
-0+clear_freeze_flag (p);
Or maybe we have it already?
Sam
Re: [PATCH -mm 2/2] Introduce freezer flags
Quoted 20 lines · Sam Ravnborg
Quoted 6 lines · Rafael J. Wysocki
kernel/fork.c +0
-0@@ -921,11 +921,14 @@ static inline void copy_flags(unsigned l {unsigned long new_flags = p->flags;kernel/fork.c static inline void copy_flags(unsigned l · line 932
Quoted 10 lines
kernel/fork.c +4
-1- new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE ); + new_flags &= ~PF_SUPERPRIV ; new_flags |=PF_FORKNOEXEC ;if (!(clone_flags &CLONE_PTRACE )) p->ptrace =0 ; p->flags = new_flags; +#ifdef CONFIG_FREEZER + p->freezer_flags =0 ; +#endif }Could we have a dedicated
clear_freeze_flag()so we could drop the ifdef?
Quoted 1 line
kernel/fork.c static inline void copy_flags(unsigned l · line 933
Quoted 1 line
kernel/fork.c +1
-0+clear_freeze_flag (p);
That means something else. clear_freeze_flag() just clears the TFF_FREEZE flag and not necessarily everything.
Besides, this is the only place where we would need to clear all the bits of p->freezer_flags. Not sure if having a static inline helper function is worth it.
Quoted 2 lines
Or maybe we have it already?
We don't yet. But can if badly needed :-)
Quoted 3 lines
Sam
Thanks and Regards
gautham.
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"
Re: [PATCH -mm 2/2] Introduce freezer flags
In reply to Rafael J. WysockiQuoted 11 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Move all of the freezer-related flags to a separate field in
task_structand introduce functions to operate them usingset_bit()etc.Index:
linux-2.6.21-rc7-mm2/include/linux/sched.h
===================================================================
include/linux/sched.h struct task_struct { · line 1011
Quoted 7 lines
include/linux/sched.h +3
-1@@ -1006,7 +1006,10 @@ struct task_struct {/* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif - +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;
unsigned long freezer_flags; ??
Else it throws the following warnings.
include/linux/freezer.h: In function `frozen':include/linux/freezer.h:22: warning: passing arg 2 of constant_test_bit' from incompatible pointer type include/linux/freezer.h:22: warning: passing arg 2 of variable_test_bit' from incompatible pointer type include/linux/freezer.h: In function `set_frozen_flag':include/linux/freezer.h:27: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `clear_frozen_flag':include/linux/freezer.h:32: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezing':include/linux/freezer.h:40: warning: passing arg 2 of constant_test_bit' from incompatible pointer type include/linux/freezer.h:40: warning: passing arg 2 of variable_test_bit' from incompatible pointer type include/linux/freezer.h: In function `freeze':include/linux/freezer.h:48: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `clear_freeze_flag':include/linux/freezer.h:56: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_should_exempt':include/linux/freezer.h:64: warning: passing arg 2 of constant_test_bit' from incompatible pointer type include/linux/freezer.h:64: warning: passing arg 2 of variable_test_bit' from incompatible pointer type include/linux/freezer.h: In function `freezer_exempt':include/linux/freezer.h:72: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_do_not_count':include/linux/freezer.h:132: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_count':include/linux/freezer.h:142: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_should_skip':include/linux/freezer.h:152: warning: passing arg 2 of constant_test_bit' from incompatible pointer type include/linux/freezer.h:152: warning: passing arg 2 of variable_test_bit' from incompatible pointer type
Regards
gautham.
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"
Re: [PATCH -mm 2/2] Introduce freezer flags
Quoted 7 lines · Gautham R Shenoy
Quoted 6 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Move all of the freezer-related flags to a separate field in
task_structand introduce functions to operate them usingset_bit()etc.
Quoted 14 lines
include/linux/sched.h struct task_struct { · line 1011
Quoted 12 lines
Index:
linux-2.6.21-rc7-mm2/include/linux/sched.h
===================================================================include/linux/sched.h +3
-1@@ -1006,7 +1006,10 @@ struct task_struct {/* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif - +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;unsigned long
freezer_flags; ??
I guess so.
Quoted 1 line
Else it throws the following warnings.
On which arch is that? I've tested on x86_64 ...
Quoted 33 lines
include/linux/freezer.h: In function `frozen':include/linux/freezer.h:22: warning: passing arg 2 ofconstant_test_bit' from incompatible pointer type include/linux/freezer.h:22: warning: passing arg 2 ofvariable_test_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `set_frozen_flag':include/linux/freezer.h:27: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `clear_frozen_flag':include/linux/freezer.h:32: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezing':include/linux/freezer.h:40: warning: passing arg 2 ofconstant_test_bit' from incompatible pointer type include/linux/freezer.h:40: warning: passing arg 2 ofvariable_test_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freeze':include/linux/freezer.h:48: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `clear_freeze_flag':include/linux/freezer.h:56: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_should_exempt':include/linux/freezer.h:64: warning: passing arg 2 ofconstant_test_bit' from incompatible pointer type include/linux/freezer.h:64: warning: passing arg 2 ofvariable_test_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_exempt':include/linux/freezer.h:72: warning: passing arg 2 of `set_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_do_not_count':include/linux/freezer.h:132: warning: passing arg 2 of `set_bit' from incompatible pointer type
Quoted 8 lines
include/linux/freezer.h: In function `freezer_count':include/linux/freezer.h:142: warning: passing arg 2 of `clear_bit' from incompatible pointer typeinclude/linux/freezer.h: In function `freezer_should_skip':include/linux/freezer.h:152: warning: passing arg 2 ofconstant_test_bit' from incompatible pointer type include/linux/freezer.h:152: warning: passing arg 2 ofvariable_test_bit' from incompatible pointer type
Greetings,
Rafael
Re: [PATCH -mm 2/2] Introduce freezer flags
Quoted 7 lines · Rafael J. Wysocki
Quoted 6 lines
include/linux/sched.h struct task_struct { · line 1011
Quoted 4 lines
include/linux/sched.h +3
-1- +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;unsigned long
freezer_flags; ??
Quoted 5 lines
I guess so.
Quoted 1 line
Else it throws the following warnings.
On which arch is that? I've tested on
x86_64...
I compile tested it on i386 with gcc v4.1.2.
Quoted 4 lines
Greetings,
Rafael
Regards
gautham.
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"
Re: [PATCH -mm 2/2] Introduce freezer flags
In reply to Rafael J. WysockiQuoted 23 lines · Rafael J. Wysocki
Quoted 7 lines · Gautham R Shenoy
Quoted 6 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Move all of the freezer-related flags to a separate field in
task_structand introduce functions to operate them usingset_bit()etc.Quoted 14 lines
include/linux/sched.h struct task_struct { · line 1011
Quoted 12 lines
Index:
linux-2.6.21-rc7-mm2/include/linux/sched.h
===================================================================include/linux/sched.h +3
-1@@ -1006,7 +1006,10 @@ struct task_struct {/* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif - +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;unsigned long
freezer_flags; ??
Quoted 1 line
I guess so.
Still, on x86_64, for example, we'll waste 4 bytes by using 'unsigned long' here, which I wouldn't like to do.
Is it acceptable to use explicit type casting in set_bit() and friends?
Rafael
Re: [PATCH -mm 2/2] Introduce freezer flags
Hi!
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
include/linux/sched.h struct task_struct { · line 1011
Quoted 3 lines
include/linux/sched.h +3
-0+#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;unsigned long
freezer_flags; ??
Quoted 6 lines
Quoted 1 line
I guess so.
Still, on
x86_64, for example, we'll waste 4 bytes by using 'unsigned long' here, which I wouldn't like to do.Is it acceptable to use explicit type casting in
set_bit()and friends?
I'm afraid set_bit & friends are only defined on unsigned long. You can cast, but you may run into some nasty surprise... like damaging surrounding bytes on 64-bit architectures != x86_64.
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH -mm 2/2] Introduce freezer flags
Quoted 8 lines · Pavel Machek
Hi!
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+#ifdef CONFIG_FREEZER + /* Used by the process freezer, defined in freezer.h */ + unsigned int freezer_flags;unsigned long
freezer_flags; ??
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
I guess so.
Still, on
x86_64, for example, we'll waste 4 bytes by using 'unsigned long' here, which I wouldn't like to do.Is it acceptable to use explicit type casting in
set_bit()and friends?I'm afraid
set_bit& friends are only defined on unsigned long.
On x86_64 they are defined on anything, even on huge bitmaps.
Quoted 2 lines
You can cast, but you may run into some nasty surprise... like damaging surrounding bytes on 64-bit architectures !=
x86_64.
Let's use unsigned long, then, but I'm not really happy with that.
---
From: Rafael J. Wysocki <[email protected]>
Move all of the freezer-related flags to a separate field in task_struct and introduce functions to operate them using set_bit() etc.
--- Documentation/power/kernel_threads.txt | 2 - Documentation/power/swsusp.txt | 4 +- arch/i386/kernel/apm.c | 2 - drivers/block/loop.c | 2 - drivers/char/apm-emulation.c | 6 +-- drivers/ieee1394/ieee1394_core.c | 2 - drivers/md/md.c | 2 - drivers/mmc/card/queue.c | 3 + drivers/mtd/mtd_blkdevs.c | 3 + drivers/scsi/libsas/sas_scsi_host.c | 2 - drivers/scsi/scsi_error.c | 2 - drivers/usb/storage/usb.c | 2 - include/asm-arm/thread_info.h | 2 - include/asm-blackfin/thread_info.h | 2 - include/asm-frv/thread_info.h | 2 - include/asm-i386/thread_info.h | 2 - include/asm-ia64/thread_info.h | 2 - include/asm-mips/thread_info.h | 2 - include/asm-powerpc/thread_info.h | 2 - include/asm-sh/thread_info.h | 2 - include/asm-x86_64/thread_info.h | 2 - include/linux/freezer.h | 63 +++++++++++++++++++++++++++------ include/linux/sched.h | 8 ++-- kernel/fork.c | 5 ++ kernel/freezer.c | 10 ++--- kernel/kthread.c | 3 + kernel/rcutorture.c | 4 +- kernel/sched.c | 2 - kernel/softirq.c | 2 - kernel/softlockup.c | 2 - kernel/workqueue.c | 2 - 31 files changed, 90 insertions(+), 61 deletions(-)
include/linux/sched.h +4 -4
@@ -1006,7 +1006,10 @@ struct task_struct {/* Deadlock detection and priority inheritance handling */ struct rt_mutex_waiter *pi_blocked_on;#endif - +#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned long freezer_flags; +#endif #ifdef CONFIG_DEBUG_MUTEXES /* mutex deadlock detection */ struct mutex_waiter *blocked_on;
@@ -1189,8 +1192,6 @@ static inline void put_task_struct(struc#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_NOFREEZE 0x00008000/* this thread should not be frozen */ -#define PF_FROZEN 0x00010000/* frozen for system suspend */ #define PF_FSTRANS 0x00020000/* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000/* I am kswapd */ #define PF_SWAPOFF 0x00080000/* I am in swapoff */
@@ -1202,7 +1203,6 @@ static inline void put_task_struct(struc#define PF_SPREAD_SLAB 0x02000000/* Spread some slab caches over cpuset */ #define PF_MEMPOLICY 0x10000000/* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000/* Thread belongs to the rt mutex tester */ -#define PF_FREEZER_SKIP 0x40000000/* Freezer should not count it as freezeable */ /* * Only the _current_ task can read/write to tsk->flags, but other
include/asm-arm/thread_info.h +0 -2
@@ -147,7 +147,6 @@ extern void iwmmxt_task_switch(struct th#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)
@@ -155,7 +154,6 @@ extern void iwmmxt_task_switch(struct th#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
include/asm-blackfin/thread_info.h +0 -2
@@ -125,7 +125,6 @@ static inline struct thread_info *currenTIF_NEED_RESCHED */ #define TIF_MEMDIE 5#define TIF_RESTORE_SIGMASK 6/* restore signal mask in do_signal() */ -#define TIF_FREEZE 7/* is freezing for suspend */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -134,7 +133,6 @@ static inline struct thread_info *curren#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) -#define _TIF_FREEZE (1<<TIF_FREEZE)#define _TIF_WORK_MASK 0x0000FFFE/* work to do on interrupt/exception return */
include/asm-frv/thread_info.h +0 -2
@@ -116,7 +116,6 @@ register struct thread_info *__current_t#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)
@@ -126,7 +125,6 @@ register struct thread_info *__current_t#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 */
include/asm-i386/thread_info.h +0 -2
@@ -136,7 +136,6 @@ static inline struct thread_info *curren#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)
@@ -150,7 +149,6 @@ static inline struct thread_info *curren#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 \
include/asm-ia64/thread_info.h +0 -2
@@ -89,7 +89,6 @@ 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)
@@ -101,7 +100,6 @@ 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)
include/asm-mips/thread_info.h +0 -2
@@ -118,7 +118,6 @@ register struct thread_info *__current_t#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 31/* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -130,7 +129,6 @@ register struct thread_info *__current_t#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)/* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
include/asm-powerpc/thread_info.h +0 -2
@@ -122,7 +122,6 @@ static inline struct thread_info *curren#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)
@@ -139,7 +138,6 @@ static inline struct thread_info *curren#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 | \
include/asm-sh/thread_info.h +0 -2
@@ -115,7 +115,6 @@ static inline struct thread_info *curren#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)
@@ -125,7 +124,6 @@ static inline struct thread_info *curren#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)#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 */
include/asm-x86_64/thread_info.h +0 -2
@@ -122,7 +122,6 @@ static inline struct thread_info *stack_#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)
@@ -138,7 +137,6 @@ static inline struct thread_info *stack_#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 \
include/linux/freezer.h +52 -11
125 lines not on this page · raw message
kernel/sched.c +1 -1
@@ -5478,7 +5478,7 @@ migration_call(struct notifier_block *nf p =kthread_create (migration_thread, hcpu,"migration/%d" ,cpu);if (IS_ERR (p))return NOTIFY_BAD ; - p->flags |=PF_NOFREEZE ; +freezer_exempt (p);kthread_bind (p, cpu);/* Must be high prio: stop_machine expects to yield to it. */ rq =task_rq_lock (p, &flags);
arch/i386/kernel/apm.c +1 -1
@@ -2313,7 +2313,7 @@ static int __init apm_init(void)remove_proc_entry ("apm" ,NULL );return err; } - kapmd_task->flags |=PF_NOFREEZE ; +freezer_exempt (kapmd_task);wake_up_process (kapmd_task);if (num_online_cpus () >1 && !smp ) {
drivers/block/loop.c +1 -1
@@ -582,7 +582,7 @@ static int loop_thread(void *data)* hence, it mustn't be stopped at all * because it could be indirectly used during suspension */ - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);set_user_nice (current,-20 );
drivers/char/apm-emulation.c +3 -3
@@ -336,7 +336,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);wait_event (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -372,7 +372,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);wait_event_interruptible (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -601,7 +601,7 @@ static int __init apm_init(void) kapmd_tsk =NULL ;return ret; } - kapmd_tsk->flags |=PF_NOFREEZE ; +freezer_exempt (kapmd_tsk);wake_up_process (kapmd_tsk);#ifdef CONFIG_PROC_FS
drivers/ieee1394/ieee1394_core.c +1 -1
@@ -1134,7 +1134,7 @@ static int hpsbpkt_thread(void *__hi)struct list_head tmp;int may_schedule; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);while (!kthread_should_stop ()) {
drivers/md/md.c +1 -1
@@ -4541,7 +4541,7 @@ static int md_thread(void * arg)* many dirty RAID5 blocks. */ - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);while (!kthread_should_stop ()) {/* We need to wait INTERRUPTIBLE so that
drivers/mmc/card/queue.c +2 -1
@@ -66,7 +66,8 @@ static int mmc_queue_thread(void *d)* Set iothread to ensure that we aren't put to sleep by * the process freezing. We handle suspension ourselves. */ - current->flags |=PF_MEMALLOC |PF_NOFREEZE ; + current->flags |=PF_MEMALLOC ; +freezer_exempt (current);down (&mq->thread_sem); do {
drivers/mtd/mtd_blkdevs.c +2 -1
@@ -81,7 +81,8 @@ static int mtd_blktrans_thread(void *argstruct request_queue *rq = tr->blkcore_priv->rq;/* we might get involved when memory gets low, so use PF_MEMALLOC */ - current->flags |=PF_MEMALLOC |PF_NOFREEZE ; + current->flags |=PF_MEMALLOC ; +freezer_exempt (current);spin_lock_irq (rq->queue_lock);while (!kthread_should_stop ()) {
drivers/scsi/libsas/sas_scsi_host.c +1 -1
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_hstruct sas_ha_struct *sas_ha = _sas_ha;struct scsi_core *core = &sas_ha->core; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);complete (&queue_th_comp);
drivers/scsi/scsi_error.c +1 -1
@@ -1536,7 +1536,7 @@ int scsi_error_handler(void *data) {struct Scsi_Host *shost = data; - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);/* * We use TASK_INTERRUPTIBLE so that the thread is not
drivers/usb/storage/usb.c +1 -1
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(voidstruct us_data *us = (struct us_data *)__us;struct Scsi_Host *host =us_to_host (us); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {try_to_freeze ();
kernel/fork.c +4 -1
@@ -921,11 +921,14 @@ static inline void copy_flags(unsigned l {unsigned long new_flags = p->flags; - new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE ); + new_flags &= ~PF_SUPERPRIV ; new_flags |=PF_FORKNOEXEC ;if (!(clone_flags &CLONE_PTRACE )) p->ptrace =0 ; p->flags = new_flags; +#ifdef CONFIG_FREEZER + p->freezer_flags =0 ; +#endif }asmlinkage long sys_set_tid_address (int __user *tidptr)
kernel/rcutorture.c +2 -2
@@ -559,7 +559,7 @@ rcu_torture_fakewriter(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_fakewriter task started" );set_user_nice (current,19 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current); do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
@@ -590,7 +590,7 @@ rcu_torture_reader(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_reader task started" );set_user_nice (current,19 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current); do { idx = cur_ops->readlock();
kernel/softirq.c +1 -1
@@ -490,7 +490,7 @@ void __init softirq_init(void)static int ksoftirqd (void * __bind_cpu) {set_user_nice (current,15 ); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);set_current_state (TASK_INTERRUPTIBLE );
kernel/softlockup.c +1 -1
@@ -117,7 +117,7 @@ static int watchdog(void * __bind_cpu)struct sched_param param = { .sched_priority =MAX_RT_PRIO -1 };sched_setscheduler (current,SCHED_FIFO , ¶m); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);/* initialize timestamp */ touch_softlockup_watchdog ();
kernel/workqueue.c +1 -1
@@ -291,7 +291,7 @@ static int worker_thread(void *__cwq)DEFINE_WAIT (wait);if (!cwq->wq->freezeable) - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {prepare_to_wait (&cwq->more_work, &wait,TASK_INTERRUPTIBLE );
kernel/freezer.c +5 -5
@@ -26,7 +26,7 @@static inline int freezeable (struct task_struct * p) {if ((p == current) || - (p->flags &PF_NOFREEZE ) || +freezer_should_exempt (p) || (p->exit_state !=0 ))return 0 ;return 1 ;
@@ -37,11 +37,11 @@ static inline int freezeable(struct task*/ static inline void frozen_process (void ) { -if (!unlikely (current->flags &PF_NOFREEZE )) { - current->flags |=PF_FROZEN ; +if (!unlikely (freezer_should_exempt (current))) { +set_frozen_flag (current);wmb (); } -clear_tsk_thread_flag (current,TIF_FREEZE ); +clear_freeze_flag (current); }/* Refrigerator is place where frozen processes are stored :-). */
@@ -100,7 +100,7 @@ static void cancel_freezing(struct task_if (freezing (p)) {pr_debug (" clean up: %s\n" , p->comm); -do_not_freeze (p); +clear_freeze_flag (p);spin_lock_irqsave (&p->sighand->siglock, flags);recalc_sigpending_tsk (p);spin_unlock_irqrestore (&p->sighand->siglock, flags);
Documentation/power/kernel_threads.txt +1 -1
@@ -32,7 +32,7 @@ like this: */ daemonize("usb-storage"); - current->flags |= PF_NOFREEZE; + freezer_exempt(current); from drivers/usb/storage/usb.c::usb_stor_control_thread()
Documentation/power/swsusp.txt +2 -2
@@ -152,8 +152,8 @@ add: try_to_freeze(); If the thread is needed for writing the image to storage, you should -instead set the PF_NOFREEZE process flag when creating the thread (and -be very careful). +instead use freezer_exempt() to mark the thread as nonfreezable when creating +it (and be very careful). Q: What is the difference between "platform" and "shutdown"?
kernel/kthread.c +2 -1
@@ -13,6 +13,7 @@#include <linux/file.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/freezer.h> #include <asm/semaphore.h> static DEFINE_SPINLOCK (kthread_create_lock);
@@ -232,7 +233,7 @@ int kthreadd(void *unused)/* Setup a clean context for our children to inherit. */ kthreadd_setup (); - current->flags |=PF_NOFREEZE ; +freezer_exempt (current);for (;;) {set_current_state (TASK_INTERRUPTIBLE );
Re: [PATCH -mm 2/2] Introduce freezer flags
Hi!
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
Quoted 7 lines
Quoted 5 lines
include/linux/sched.h struct task_struct {
Quoted 3 lines
include/linux/sched.h +3
-0+#ifdef CONFIG_FREEZER +/* Used by the process freezer, defined in freezer.h */ +unsigned int freezer_flags;unsigned long
freezer_flags; ??I guess so.
Still, on
x86_64, for example, we'll waste 4 bytes by using 'unsigned long' here, which I wouldn't like to do.Is it acceptable to use explicit type casting in
set_bit()and friends?
Quoted 8 lines
Quoted 1 line
I'm afraid
set_bit& friends are only defined on unsigned long.On
x86_64they are defined on anything, even on huge bitmaps.Quoted 2 lines
You can cast, but you may run into some nasty surprise... like damaging surrounding bytes on 64-bit architectures !=
x86_64.Let's use unsigned long, then, but I'm not really happy with that.
Ask the architecture people, but comments like
/data/l/linux/include/linux/agpgart.h: long access_flags; /* long req'd for set_bit --RR */
Make me think long is needed.
* bitmaps provide bit arrays that consume one or more unsigned
* longs. The bitmap interface and available operations are listed
* here, in bitmap.h
...I'm afraid we need ulongs.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
PATCH 1/1 Allow selective freezing of the system for different events
In reply to Rafael J. WysockiThis patch
* Provides an interface to selectively freeze the system for different events.
* Allows tasks to exempt themselves or other tasks from specific freeze events.
* Allow nesting of freezer calls. For eg:
freeze_processes(EVENT_A); /* Do something with respect to event A */ . . . freeze_processes(EVENT_B); /* Do something with respect to event B */ . . . thaw_processes(EVENT_B); . . . thaw_processes(EVENT_B);
This type of behaviour would be required when cpu hotplug would start using the process freezer, where EVENT_A would be SUSPEND and EVENT_B would be HOTPLUG_CPU.
This patch applies on the top of 2.6.21-rc7-mm2 + Rafael's freezer changes from http://lkml.org/lkml/2007/4/27/302.
--- arch/i386/kernel/apm.c | 2 - drivers/block/loop.c | 2 - drivers/char/apm-emulation.c | 6 +-- drivers/ieee1394/ieee1394_core.c | 2 - drivers/md/md.c | 2 - drivers/mmc/card/queue.c | 2 - drivers/mtd/mtd_blkdevs.c | 2 - drivers/scsi/libsas/sas_scsi_host.c | 2 - drivers/scsi/scsi_error.c | 2 - drivers/usb/storage/usb.c | 2 - include/linux/freezer.h | 44 +++++++++++++++++++----- kernel/freezer.c | 64 ++++++++++++++++++++++++++++++------ kernel/kprobes.c | 4 +- kernel/kthread.c | 2 - kernel/power/disk.c | 4 +- kernel/power/main.c | 8 ++-- kernel/power/user.c | 6 +-- kernel/rcutorture.c | 4 +- kernel/sched.c | 2 - kernel/softirq.c | 2 - kernel/softlockup.c | 2 - kernel/workqueue.c | 2 - 22 files changed, 119 insertions(+), 49 deletions(-)
include/linux/freezer.h +34 -10
@@ -4,17 +4,27 @@#ifdef CONFIG_FREEZER +/* * Per task flags used by the freezer * * They should not be referred to directly outside of this file. */ -#define TFF_NOFREEZE 0/* task should not be frozen */ +#define TFF_FE_SUSPEND 0/* Do not freeze task for software suspend */ +#define TFF_FE_KPROBES 1/* Do not freeze task for kprobes */ #define TFF_FREEZE 8/* task should go to the refrigerator ASAP */ #define TFF_SKIP 9/* do not count this task as freezable */ #define TFF_FROZEN 10/* task is frozen */ /* +* Codes of different events which use the freezer +* These are the only flags that can be referred outside this file +*/ +#define FE_SUSPEND (1 << TFF_FE_SUSPEND)/* Software Suspend */ +#define FE_KPROBES (1 << TFF_FE_KPROBES)/* Kprobes */ +#define FE_ALL (FE_SUSPEND | FE_KPROBES)/* All events using freezer */ + +/* * Check if a process has been frozen */ static inline int frozen (struct task_struct *p)
@@ -57,19 +67,29 @@ static inline void clear_freeze_flag(str }/* -* Check if the task wants to be exempted from freezing +* Check if the task wants to be exempted from freezing for +* freeze_event. */ -static inline int freezer_should_exempt (struct task_struct *p) +static inline int freezer_should_exempt (struct task_struct *p, +unsigned long freeze_event) { -return test_bit (TFF_NOFREEZE , &p->freezer_flags); +return p->freezer_flags & freeze_event; }/* * Tell the freezer to exempt this task from freezing +* for events in freeze_event_mask. */ -static inline void freezer_exempt (struct task_struct *p) +static inline void freezer_exempt (struct task_struct *p, +unsigned long freeze_event_mask) +{ +atomic_set_mask (freeze_event_mask, &p->freezer_flags); +} + +/* Returns the mask of the events for which this process is freezeable */ +static inline unsigned long freezeable_event_mask (struct task_struct *p) { -set_bit (TFF_NOFREEZE , &p->freezer_flags); +return ~p->freezer_flags &FE_ALL ; }/*
@@ -96,8 +116,8 @@ static inline int thaw_process(struct ta }extern void refrigerator (void ); -extern int freeze_processes (void ); -extern void thaw_processes (void ); +extern int freeze_processes (unsigned long freeze_event); +extern void thaw_processes (unsigned long freeze_event);static inline int try_to_freeze (void ) {
@@ -160,11 +180,15 @@ static inline int freezing(struct task_sstatic inline void freeze (struct task_struct *p) {BUG (); }static inline int freezer_should_exempt (struct task_struct *p) {return 0 ; }static inline void freezer_exempt (struct task_struct *p) {} +static inline unsigned long freezeable_event_mask (struct task_struct *p) +{ +return 0 ; +}static inline int thaw_process (struct task_struct *p) {return 1 ; }static inline void refrigerator (void ) {} -static inline int freeze_processes (void ) {BUG ();return 0 ; } -static inline void thaw_processes (void ) {} +static inline int freeze_processes (unsigned long ) {BUG ();return 0 ; } +static inline void thaw_processes (unsigned long ) {}static inline int try_to_freeze (void ) {return 0 ; }
kernel/freezer.c +55 -9
122 lines not on this page · raw message
arch/i386/kernel/apm.c +1 -1
@@ -2313,7 +2313,7 @@ static int __init apm_init(void)remove_proc_entry ("apm" ,NULL );return err; } -freezer_exempt (kapmd_task); +freezer_exempt (kapmd_task,FE_ALL );wake_up_process (kapmd_task);if (num_online_cpus () >1 && !smp ) {
drivers/block/loop.c +1 -1
@@ -582,7 +582,7 @@ static int loop_thread(void *data)* hence, it mustn't be stopped at all * because it could be indirectly used during suspension */ -freezer_exempt (current); +freezer_exempt (current,FE_ALL );set_user_nice (current,-20 );
drivers/char/apm-emulation.c +3 -3
@@ -336,7 +336,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );wait_event (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -372,7 +372,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );wait_event_interruptible (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );
@@ -601,7 +601,7 @@ static int __init apm_init(void) kapmd_tsk =NULL ;return ret; } -freezer_exempt (kapmd_tsk); +freezer_exempt (kapmd_tsk,FE_ALL );wake_up_process (kapmd_tsk);#ifdef CONFIG_PROC_FS
drivers/ieee1394/ieee1394_core.c +1 -1
@@ -1134,7 +1134,7 @@ static int hpsbpkt_thread(void *__hi)struct list_head tmp;int may_schedule; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );while (!kthread_should_stop ()) {
drivers/md/md.c +1 -1
@@ -4541,7 +4541,7 @@ static int md_thread(void * arg)* many dirty RAID5 blocks. */ -freezer_exempt (current); +freezer_exempt (current,FE_ALL );while (!kthread_should_stop ()) {/* We need to wait INTERRUPTIBLE so that
drivers/mmc/card/queue.c +1 -1
@@ -67,7 +67,7 @@ static int mmc_queue_thread(void *d)* the process freezing. We handle suspension ourselves. */ current->flags |=PF_MEMALLOC ; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );down (&mq->thread_sem); do {
drivers/mtd/mtd_blkdevs.c +1 -1
@@ -82,7 +82,7 @@ static int mtd_blktrans_thread(void *arg/* we might get involved when memory gets low, so use PF_MEMALLOC */ current->flags |=PF_MEMALLOC ; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );spin_lock_irq (rq->queue_lock);while (!kthread_should_stop ()) {
drivers/scsi/libsas/sas_scsi_host.c +1 -1
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_hstruct sas_ha_struct *sas_ha = _sas_ha;struct scsi_core *core = &sas_ha->core; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );complete (&queue_th_comp);
drivers/scsi/scsi_error.c +1 -1
@@ -1536,7 +1536,7 @@ int scsi_error_handler(void *data) {struct Scsi_Host *shost = data; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );/* * We use TASK_INTERRUPTIBLE so that the thread is not
drivers/usb/storage/usb.c +1 -1
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(voidstruct us_data *us = (struct us_data *)__us;struct Scsi_Host *host =us_to_host (us); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {try_to_freeze ();
kernel/kthread.c +1 -1
@@ -233,7 +233,7 @@ int kthreadd(void *unused)/* Setup a clean context for our children to inherit. */ kthreadd_setup (); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {set_current_state (TASK_INTERRUPTIBLE );
kernel/rcutorture.c +2 -2
@@ -559,7 +559,7 @@ rcu_torture_fakewriter(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_fakewriter task started" );set_user_nice (current,19 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL ); do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
@@ -590,7 +590,7 @@ rcu_torture_reader(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_reader task started" );set_user_nice (current,19 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL ); do { idx = cur_ops->readlock();
kernel/sched.c +1 -1
@@ -5478,7 +5478,7 @@ migration_call(struct notifier_block *nf p =kthread_create (migration_thread, hcpu,"migration/%d" ,cpu);if (IS_ERR (p))return NOTIFY_BAD ; -freezer_exempt (p); +freezer_exempt (p,FE_ALL );kthread_bind (p, cpu);/* Must be high prio: stop_machine expects to yield to it. */ rq =task_rq_lock (p, &flags);
kernel/softirq.c +1 -1
@@ -490,7 +490,7 @@ void __init softirq_init(void)static int ksoftirqd (void * __bind_cpu) {set_user_nice (current,15 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );set_current_state (TASK_INTERRUPTIBLE );
kernel/softlockup.c +1 -1
@@ -117,7 +117,7 @@ static int watchdog(void * __bind_cpu)struct sched_param param = { .sched_priority =MAX_RT_PRIO -1 };sched_setscheduler (current,SCHED_FIFO , ¶m); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );/* initialize timestamp */ touch_softlockup_watchdog ();
kernel/workqueue.c +1 -1
@@ -291,7 +291,7 @@ static int worker_thread(void *__cwq)DEFINE_WAIT (wait);if (!cwq->wq->freezeable) -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {prepare_to_wait (&cwq->more_work, &wait,TASK_INTERRUPTIBLE );
kernel/kprobes.c +2 -2
@@ -109,7 +109,7 @@ static int __kprobes check_safety(void) {int ret =0 ;#ifdef CONFIG_PREEMPT - ret =freeze_processes (); + ret =freeze_processes (FE_KPROBES );if (ret ==0 ) {struct task_struct *p, *q; do_each_thread(p, q) {
@@ -122,7 +122,7 @@ static int __kprobes check_safety(void) } while_each_thread(p, q); } loop_end: -thaw_processes (); +thaw_processes (FE_KPROBES );#else synchronize_sched ();#endif
kernel/power/disk.c +2 -2
@@ -103,7 +103,7 @@ static inline void platform_finish(void)static void unprepare_processes (void ) { -thaw_processes (); +thaw_processes (FE_SUSPEND );pm_restore_console (); }
@@ -112,7 +112,7 @@ static int prepare_processes(void)int error =0 ;pm_prepare_console (); -if (freeze_processes ()) { +if (freeze_processes (FE_SUSPEND )) { error = -EBUSY ;unprepare_processes (); }
kernel/power/main.c +4 -4
@@ -90,9 +90,9 @@ static int suspend_prepare(suspend_stateif (error) goto Finish; -if (freeze_processes ()) { +if (freeze_processes (FE_SUSPEND )) { error = -EAGAIN ; -thaw_processes (); +thaw_processes (FE_SUSPEND ); goto Finish; }
@@ -133,7 +133,7 @@ static int suspend_prepare(suspend_stateresume_console (); Thaw:suspend_notifier_call_chain (SUSPEND_THAW_PREPARE ); -thaw_processes (); +thaw_processes (FE_SUSPEND ); Finish:pm_restore_console ();suspend_notifier_call_chain (SUSPEND_FINISHED );
@@ -185,7 +185,7 @@ static void suspend_finish(suspend_statedevice_resume ();resume_console ();suspend_notifier_call_chain (SUSPEND_THAW_PREPARE ); -thaw_processes (); +thaw_processes (FE_SUSPEND );pm_restore_console ();suspend_notifier_call_chain (SUSPEND_FINISHED ); }
kernel/power/user.c +3 -3
@@ -81,7 +81,7 @@ static void snapshot_unfreeze(struct snareturn ;mutex_lock (&pm_mutex); -thaw_processes (); +thaw_processes (FE_SUSPEND );suspend_notifier_call_chain (SUSPEND_FINISHED );mutex_unlock (&pm_mutex); data->frozen =0 ;
@@ -257,8 +257,8 @@ static int snapshot_ioctl(struct inode *if (error)break ; -if (freeze_processes ()) { -thaw_processes (); +if (freeze_processes (FE_SUSPEND )) { +thaw_processes (FE_SUSPEND );suspend_notifier_call_chain (SUSPEND_FINISHED ); error = -EBUSY ; }
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"
Andrew Morton
maintainerRe: [PATCH -mm] Allow selective freezing of the system for different events
Quoted 22 lines · On Sat, 28 Apr 2007 07:04:46 +0530 Gautham R Shenoy <[email protected]> wrote:
This patch
* Provides an interface to selectively freeze the system for different events.
* Allows tasks to exempt themselves or other tasks from specific freeze events.
* Allow nesting of freezer calls. For eg:freeze_processes(EVENT_A); /* Do something with respect to event A */ . . . freeze_processes(EVENT_B); /* Do something with respect to event B */ . . . thaw_processes(EVENT_B); . . . thaw_processes(EVENT_B);
Quoted 6 lines
This type of behaviour would be required when cpu hotplug would start using the process freezer, where
EVENT_Awould be SUSPEND andEVENT_Bwould beHOTPLUG_CPU.This patch applies on the top of 2.6.21-rc7-mm2 + Rafael's freezer changes from http://lkml.org/lkml/2007/4/27/302.
I think I'll duck this. We have more than enough kthread/freezer/etc work queued for 2.6.22. Let's please for now concentrate on reviewing and testing the existing changes. Once that has all landed and settled in, let's start thinking about the next round.
Re: [PATCH -mm] Allow selective freezing of the system for different events
Quoted 28 lines · Andrew Morton
Quoted 26 lines · On Sat, 28 Apr 2007 07:04:46 +0530 Gautham R Shenoy <[email protected]> wrote:
This patch
* Provides an interface to selectively freeze the system for different events.
* Allows tasks to exempt themselves or other tasks from specific freeze events.
* Allow nesting of freezer calls. For eg:freeze_processes(EVENT_A); /* Do something with respect to event A */ . . . freeze_processes(EVENT_B); /* Do something with respect to event B */ . . . thaw_processes(EVENT_B); . . . thaw_processes(EVENT_B);This type of behaviour would be required when cpu hotplug would start using the process freezer, where
EVENT_Awould be SUSPEND andEVENT_Bwould beHOTPLUG_CPU.
Quoted 5 lines
Quoted 2 lines
This patch applies on the top of 2.6.21-rc7-mm2 + Rafael's freezer changes from http://lkml.org/lkml/2007/4/27/302.
I think I'll duck this. We have more than enough kthread/freezer/etc work queued for 2.6.22.
Sure, not a problem :-)
I just wanted to get a sense, if this was a right way to do it. Besides, I am plannning to send it again once I port the cpuhotplug patches on top of all these changes and get some satisfactory numbers.
Quoted 4 lines
Let's please for now concentrate on reviewing and
testing the existing changes. Once that has all landed and settled in, let's start thinking about the next round.
Ok.
Thanks and Regards
gautham.
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"
Re: [PATCH -mm] Allow selective freezing of the system for different events
In reply to Gautham R ShenoyHi,
Sorry for the delay.
Quoted 99 lines · Gautham R Shenoy
This patch
* Provides an interface to selectively freeze the system for different events.
* Allows tasks to exempt themselves or other tasks from specific freeze events.
* Allow nesting of freezer calls. For eg:freeze_processes(EVENT_A); /* Do something with respect to event A */ . . . freeze_processes(EVENT_B); /* Do something with respect to event B */ . . . thaw_processes(EVENT_B); . . . thaw_processes(EVENT_B);This type of behaviour would be required when cpu hotplug would start using the process freezer, where
EVENT_Awould be SUSPEND andEVENT_Bwould beHOTPLUG_CPU.This patch applies on the top of 2.6.21-rc7-mm2 + Rafael's freezer changes from http://lkml.org/lkml/2007/4/27/302.
Signed-off-by Gautham R Shenoy <[email protected]>--- arch/i386/kernel/apm.c | 2 - drivers/block/loop.c | 2 - drivers/char/apm-emulation.c | 6 +-- drivers/ieee1394/ieee1394_core.c | 2 - drivers/md/md.c | 2 - drivers/mmc/card/queue.c | 2 - drivers/mtd/mtd_blkdevs.c | 2 - drivers/scsi/libsas/sas_scsi_host.c | 2 - drivers/scsi/scsi_error.c | 2 - drivers/usb/storage/usb.c | 2 - include/linux/freezer.h | 44 +++++++++++++++++++----- kernel/freezer.c | 64 ++++++++++++++++++++++++++++++------ kernel/kprobes.c | 4 +- kernel/kthread.c | 2 - kernel/power/disk.c | 4 +- kernel/power/main.c | 8 ++-- kernel/power/user.c | 6 +-- kernel/rcutorture.c | 4 +- kernel/sched.c | 2 - kernel/softirq.c | 2 - kernel/softlockup.c | 2 - kernel/workqueue.c | 2 - 22 files changed, 119 insertions(+), 49 deletions(-)Index:
linux-2.6.21-rc7/include/linux/freezer.h
===================================================================include/linux/freezer.h +15
-3@@ -4,17 +4,27 @@#ifdef CONFIG_FREEZER +/* * Per task flags used by the freezer * * They should not be referred to directly outside of this file. */ -#define TFF_NOFREEZE 0/* task should not be frozen */ +#define TFF_FE_SUSPEND 0/* Do not freeze task for software suspend */ +#define TFF_FE_KPROBES 1/* Do not freeze task for kprobes */ #define TFF_FREEZE 8/* task should go to the refrigerator ASAP */ #define TFF_SKIP 9/* do not count this task as freezable */ #define TFF_FROZEN 10/* task is frozen */ /* +* Codes of different events which use the freezer +* These are the only flags that can be referred outside this file +*/ +#define FE_SUSPEND (1 << TFF_FE_SUSPEND)/* Software Suspend */ +#define FE_KPROBES (1 << TFF_FE_KPROBES)/* Kprobes */ +#define FE_ALL (FE_SUSPEND | FE_KPROBES)/* All events using freezer */ + +/* * Check if a process has been frozen */ static inline int frozen (struct task_struct *p)@@ -57,19 +67,29 @@ static inline void clear_freeze_flag(str }/* -* Check if the task wants to be exempted from freezing +* Check if the task wants to be exempted from freezing for +* freeze_event. */ -static inline int freezer_should_exempt (struct task_struct *p) +static inline int freezer_should_exempt (struct task_struct *p, +unsigned long freeze_event)
include/linux/freezer.h static inline void clear_freeze_flag(str · line 70
Quoted 10 lines
include/linux/freezer.h +2
-2{ -return test_bit (TFF_NOFREEZE , &p->freezer_flags); +return p->freezer_flags & freeze_event; }/* * Tell the freezer to exempt this task from freezing +* for events in freeze_event_mask. */ -static inline void freezer_exempt (struct task_struct *p)
I, personally, would introduce
static inline void freezer_exempt_event(struct task_struct *p,
unsigned long freeze_event_mask)
{
atomic_set_mask(freeze_event_mask, &p->freezer_flags);
}and then
static inline void freezer_exempt(struct task_struct *p)
{
freezer_exempt_event(p, FE_ALL);
}The patch would be shorter. ;-)
[In that case I'd probably rename freezer_should_exempt() to freezer_should_exempt_event(), for symmetry.]
Quoted 73 lines
include/linux/freezer.h +17
-5+static inline void freezer_exempt (struct task_struct *p, +unsigned long freeze_event_mask) +{ +atomic_set_mask (freeze_event_mask, &p->freezer_flags); +} + +/* Returns the mask of the events for which this process is freezeable */ +static inline unsigned long freezeable_event_mask (struct task_struct *p) { -set_bit (TFF_NOFREEZE , &p->freezer_flags); +return ~p->freezer_flags &FE_ALL ; }/* @@ -96,8 +116,8 @@ static inline int thaw_process(struct ta }extern void refrigerator (void ); -extern int freeze_processes (void ); -extern void thaw_processes (void ); +extern int freeze_processes (unsigned long freeze_event); +extern void thaw_processes (unsigned long freeze_event);static inline int try_to_freeze (void ) {@@ -160,11 +180,15 @@ static inline int freezing(struct task_sstatic inline void freeze (struct task_struct *p) {BUG (); }static inline int freezer_should_exempt (struct task_struct *p) {return 0 ; }static inline void freezer_exempt (struct task_struct *p) {} +static inline unsigned long freezeable_event_mask (struct task_struct *p) +{ +return 0 ; +}static inline int thaw_process (struct task_struct *p) {return 1 ; }static inline void refrigerator (void ) {} -static inline int freeze_processes (void ) {BUG ();return 0 ; } -static inline void thaw_processes (void ) {} +static inline int freeze_processes (unsigned long ) {BUG ();return 0 ; } +static inline void thaw_processes (unsigned long ) {}static inline int try_to_freeze (void ) {return 0 ; }Index:
linux-2.6.21-rc7/kernel/freezer.c
===================================================================kernel/freezer.c +13
-1@@ -23,21 +23,44 @@#define FREEZER_KERNEL_THREADS 0#define FREEZER_USER_SPACE 1 +static DEFINE_MUTEX (freezer_mutex); +/* Mask of the events for which the system is currently frozen */ +unsigned long system_frozen_event_mask; +/* The event for which the freeze request has been raised */ +unsigned long current_freezer_event; +static inline int freezeable (struct task_struct * p) {if ((p == current) || -freezer_should_exempt (p) || +freezer_should_exempt (p, current_freezer_event) || (p->exit_state !=0 ))return 0 ;return 1 ; } +/* Returns the mask of events for which p is currently frozen */ +static inline unsigned long process_frozen_event_mask (struct task_struct *p) +{ +return (freezeable_event_mask (p) & system_frozen_event_mask); +} +
kernel/freezer.c line 56
Quoted 10 lines
kernel/freezer.c +10
-0+static inline int thawable (struct task_struct *p) +{ +if (!freezeable (p)) +return 0 ; + +/* Thaw p iff it is frozen for current_freezer_event alone */ +if (process_frozen_event_mask (p) & ~current_freezer_event) +return 0 ; + +return 1 ;
I would do
return !(process_frozen_event_mask(p) & ~current_freezer_event);
Quoted 38 lines
kernel/freezer.c +14
-4+}/* * freezing is complete, mark current process as frozen */ static inline void frozen_process (void ) { -if (!unlikely (freezer_should_exempt (current))) { +if (!unlikely (freezer_should_exempt (current, current_freezer_event))) {set_frozen_flag (current);wmb (); }@@ -185,26 +208,39 @@ static unsigned int try_to_freeze_tasks(/** * freeze_processes - tell processes to enter the refrigerator * +* @freeze_event : Event that's requesting the services +* of the process freezer to freeze the system +* * Returns 0 on success, or the number of processes that didn't freeze, * although they were told to. */ -int freeze_processes (void ) +int freeze_processes (unsigned long freeze_event) { -unsigned int nr_unfrozen; +unsigned int nr_unfrozen =0 ; + +mutex_lock (&freezer_mutex); +if (system_frozen_event_mask & freeze_event) + goto out; + + current_freezer_event = freeze_event;printk ("Stopping tasks ... " ); nr_unfrozen =try_to_freeze_tasks (FREEZER_USER_SPACE );if (nr_unfrozen) -return nr_unfrozen; + goto out;
kernel/freezer.c static unsigned int try_to_freeze_tasks( · line 239
Quoted 10 lines
kernel/freezer.c +2
-1sys_sync (); nr_unfrozen =try_to_freeze_tasks (FREEZER_KERNEL_THREADS );if (nr_unfrozen) -return nr_unfrozen; + goto out; + system_frozen_event_mask |= current_freezer_event;printk ("done.\n" );BUG_ON (in_atomic ());
The BUG_ON() is still valid if tasks are already frozen for this event.
Quoted 18 lines
kernel/freezer.c +5
-2-return 0 ; +out: + current_freezer_event =0 ; +mutex_unlock (&freezer_mutex); +return nr_unfrozen; }static void thaw_tasks (int thaw_user_space)@@ -213,7 +249,7 @@ static void thaw_tasks(int thaw_user_sparead_lock (&tasklist_lock); do_each_thread(g, p) { -if (!freezeable (p)) +if (!thawable (p))continue ;if (is_user_space (p) == !thaw_user_space)
kernel/freezer.c static void thaw_tasks(int thaw_user_spa · line 267
Quoted 9 lines
kernel/freezer.c +4
-1@@ -224,13 +260,23 @@ static void thaw_tasks(int thaw_user_sparead_unlock (&tasklist_lock); } -void thaw_processes (void ) +void thaw_processes (unsigned long thaw_event) { +mutex_lock (&freezer_mutex); +if (!(system_frozen_event_mask & thaw_event)) { +WARN_ON (1 );
Hmm, I wouldn't use the WARN_ON() here. There's nothing wrong in calling this twice in a row as long as we do the sanity checking. There's even one case in which that may be convenient, actually.
Quoted 352 lines
kernel/freezer.c +7
-0+ goto out; + } + current_freezer_event = thaw_event;printk ("Restarting tasks ... " );thaw_tasks (FREEZER_KERNEL_THREADS );thaw_tasks (FREEZER_USER_SPACE ); + system_frozen_event_mask &= ~current_freezer_event;schedule ();printk ("done.\n" ); +out: + current_freezer_event =0 ; +mutex_unlock (&freezer_mutex); }EXPORT_SYMBOL (refrigerator);Index:
linux-2.6.21-rc7/arch/i386/kernel/apm.c
===================================================================arch/i386/kernel/apm.c +1
-1@@ -2313,7 +2313,7 @@ static int __init apm_init(void)remove_proc_entry ("apm" ,NULL );return err; } -freezer_exempt (kapmd_task); +freezer_exempt (kapmd_task,FE_ALL );wake_up_process (kapmd_task);if (num_online_cpus () >1 && !smp ) {Index:
linux-2.6.21-rc7/drivers/block/loop.c
===================================================================drivers/block/loop.c +1
-1@@ -582,7 +582,7 @@ static int loop_thread(void *data)* hence, it mustn't be stopped at all * because it could be indirectly used during suspension */ -freezer_exempt (current); +freezer_exempt (current,FE_ALL );set_user_nice (current,-20 );Index:
linux-2.6.21-rc7/drivers/char/apm-emulation.c
===================================================================drivers/char/apm-emulation.c +3
-3@@ -336,7 +336,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );wait_event (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );@@ -372,7 +372,7 @@ apm_ioctl(struct inode * inode, struct f* threads. */ flags = current->flags; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );wait_event_interruptible (apm_suspend_waitqueue, as->suspend_state ==SUSPEND_DONE );@@ -601,7 +601,7 @@ static int __init apm_init(void) kapmd_tsk =NULL ;return ret; } -freezer_exempt (kapmd_tsk); +freezer_exempt (kapmd_tsk,FE_ALL );wake_up_process (kapmd_tsk);#ifdef CONFIG_PROC_FS Index:
linux-2.6.21-rc7/drivers/ieee1394/ieee1394_core.c
===================================================================drivers/ieee1394/ieee1394_core.c +1
-1@@ -1134,7 +1134,7 @@ static int hpsbpkt_thread(void *__hi)struct list_head tmp;int may_schedule; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );while (!kthread_should_stop ()) {Index:
linux-2.6.21-rc7/drivers/md/md.c
===================================================================drivers/md/md.c +1
-1@@ -4541,7 +4541,7 @@ static int md_thread(void * arg)* many dirty RAID5 blocks. */ -freezer_exempt (current); +freezer_exempt (current,FE_ALL );while (!kthread_should_stop ()) {/* We need to wait INTERRUPTIBLE so that Index:
linux-2.6.21-rc7/drivers/mmc/card/queue.c
===================================================================drivers/mmc/card/queue.c +1
-1@@ -67,7 +67,7 @@ static int mmc_queue_thread(void *d)* the process freezing. We handle suspension ourselves. */ current->flags |=PF_MEMALLOC ; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );down (&mq->thread_sem); do {Index:
linux-2.6.21-rc7/drivers/mtd/mtd_blkdevs.c
===================================================================drivers/mtd/mtd_blkdevs.c +1
-1@@ -82,7 +82,7 @@ static int mtd_blktrans_thread(void *arg/* we might get involved when memory gets low, so use PF_MEMALLOC */ current->flags |=PF_MEMALLOC ; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );spin_lock_irq (rq->queue_lock);while (!kthread_should_stop ()) {Index:
linux-2.6.21-rc7/drivers/scsi/libsas/sas_scsi_host.c
===================================================================drivers/scsi/libsas/sas_scsi_host.c +1
-1@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_hstruct sas_ha_struct *sas_ha = _sas_ha;struct scsi_core *core = &sas_ha->core; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );complete (&queue_th_comp);Index:
linux-2.6.21-rc7/drivers/scsi/scsi_error.c
===================================================================drivers/scsi/scsi_error.c +1
-1@@ -1536,7 +1536,7 @@ int scsi_error_handler(void *data) {struct Scsi_Host *shost = data; -freezer_exempt (current); +freezer_exempt (current,FE_ALL );/* * We use TASK_INTERRUPTIBLE so that the thread is not Index:
linux-2.6.21-rc7/drivers/usb/storage/usb.c
===================================================================drivers/usb/storage/usb.c +1
-1@@ -301,7 +301,7 @@ static int usb_stor_control_thread(voidstruct us_data *us = (struct us_data *)__us;struct Scsi_Host *host =us_to_host (us); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {try_to_freeze ();Index:
linux-2.6.21-rc7/kernel/kthread.c
===================================================================kernel/kthread.c +1
-1@@ -233,7 +233,7 @@ int kthreadd(void *unused)/* Setup a clean context for our children to inherit. */ kthreadd_setup (); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {set_current_state (TASK_INTERRUPTIBLE );Index:
linux-2.6.21-rc7/kernel/rcutorture.c
===================================================================kernel/rcutorture.c +2
-2@@ -559,7 +559,7 @@ rcu_torture_fakewriter(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_fakewriter task started" );set_user_nice (current,19 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL ); do { schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);@@ -590,7 +590,7 @@ rcu_torture_reader(void *arg)VERBOSE_PRINTK_STRING ("rcu_torture_reader task started" );set_user_nice (current,19 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL ); do { idx = cur_ops->readlock();Index:
linux-2.6.21-rc7/kernel/sched.c
===================================================================kernel/sched.c +1
-1@@ -5478,7 +5478,7 @@ migration_call(struct notifier_block *nf p =kthread_create (migration_thread, hcpu,"migration/%d" ,cpu);if (IS_ERR (p))return NOTIFY_BAD ; -freezer_exempt (p); +freezer_exempt (p,FE_ALL );kthread_bind (p, cpu);/* Must be high prio: stop_machine expects to yield to it. */ rq =task_rq_lock (p, &flags);Index:
linux-2.6.21-rc7/kernel/softirq.c
===================================================================kernel/softirq.c +1
-1@@ -490,7 +490,7 @@ void __init softirq_init(void)static int ksoftirqd (void * __bind_cpu) {set_user_nice (current,15 ); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );set_current_state (TASK_INTERRUPTIBLE );Index:
linux-2.6.21-rc7/kernel/softlockup.c
===================================================================kernel/softlockup.c +1
-1@@ -117,7 +117,7 @@ static int watchdog(void * __bind_cpu)struct sched_param param = { .sched_priority =MAX_RT_PRIO -1 };sched_setscheduler (current,SCHED_FIFO , ¶m); -freezer_exempt (current); +freezer_exempt (current,FE_ALL );/* initialize timestamp */ touch_softlockup_watchdog ();Index:
linux-2.6.21-rc7/kernel/workqueue.c
===================================================================kernel/workqueue.c +1
-1@@ -291,7 +291,7 @@ static int worker_thread(void *__cwq)DEFINE_WAIT (wait);if (!cwq->wq->freezeable) -freezer_exempt (current); +freezer_exempt (current,FE_ALL );for (;;) {prepare_to_wait (&cwq->more_work, &wait,TASK_INTERRUPTIBLE );Index:
linux-2.6.21-rc7/kernel/kprobes.c
===================================================================kernel/kprobes.c +2
-2@@ -109,7 +109,7 @@ static int __kprobes check_safety(void) {int ret =0 ;#ifdef CONFIG_PREEMPT - ret =freeze_processes (); + ret =freeze_processes (FE_KPROBES );if (ret ==0 ) {struct task_struct *p, *q; do_each_thread(p, q) {@@ -122,7 +122,7 @@ static int __kprobes check_safety(void) } while_each_thread(p, q); } loop_end: -thaw_processes (); +thaw_processes (FE_KPROBES );#else synchronize_sched ();#endif Index:
linux-2.6.21-rc7/kernel/power/disk.c
===================================================================kernel/power/disk.c +2
-2@@ -103,7 +103,7 @@ static inline void platform_finish(void)static void unprepare_processes (void ) { -thaw_processes (); +thaw_processes (FE_SUSPEND );pm_restore_console (); }@@ -112,7 +112,7 @@ static int prepare_processes(void)int error =0 ;pm_prepare_console (); -if (freeze_processes ()) { +if (freeze_processes (FE_SUSPEND )) { error = -EBUSY ;unprepare_processes (); }Index:
linux-2.6.21-rc7/kernel/power/main.c
===================================================================kernel/power/main.c +4
-4@@ -90,9 +90,9 @@ static int suspend_prepare(suspend_stateif (error) goto Finish; -if (freeze_processes ()) { +if (freeze_processes (FE_SUSPEND )) { error = -EAGAIN ; -thaw_processes (); +thaw_processes (FE_SUSPEND ); goto Finish; }@@ -133,7 +133,7 @@ static int suspend_prepare(suspend_stateresume_console (); Thaw:suspend_notifier_call_chain (SUSPEND_THAW_PREPARE ); -thaw_processes (); +thaw_processes (FE_SUSPEND ); Finish:pm_restore_console ();suspend_notifier_call_chain (SUSPEND_FINISHED );@@ -185,7 +185,7 @@ static void suspend_finish(suspend_statedevice_resume ();resume_console ();suspend_notifier_call_chain (SUSPEND_THAW_PREPARE ); -thaw_processes (); +thaw_processes (FE_SUSPEND );pm_restore_console ();suspend_notifier_call_chain (SUSPEND_FINISHED ); }Index:
linux-2.6.21-rc7/kernel/power/user.c
===================================================================kernel/power/user.c +3
-3@@ -81,7 +81,7 @@ static void snapshot_unfreeze(struct snareturn ;mutex_lock (&pm_mutex); -thaw_processes (); +thaw_processes (FE_SUSPEND );suspend_notifier_call_chain (SUSPEND_FINISHED );mutex_unlock (&pm_mutex); data->frozen =0 ;@@ -257,8 +257,8 @@ static int snapshot_ioctl(struct inode *if (error)break ; -if (freeze_processes ()) { -thaw_processes (); +if (freeze_processes (FE_SUSPEND )) { +thaw_processes (FE_SUSPEND );suspend_notifier_call_chain (SUSPEND_FINISHED ); error = -EBUSY ; }
Re: [PATCH -mm] Allow selective freezing of the system for different events
Quoted 3 lines · Rafael J. Wysocki
Hi,
Sorry for the delay.
No problems! Even I was out for the weekend.
Quoted 14 lines
Quoted 5 lines
/*
* Tell the freezer to exempt this task from freezing
+ * for events infreeze_event_mask.
*/
-static inline voidfreezer_exempt(struct task_struct *p)I, personally, would introduce
static inline void freezer_exempt_event(struct
task_struct*p,
unsigned longfreeze_event_mask){ atomic_set_mask(freeze_event_mask, &p->freezer_flags); }
Quoted 9 lines
and then
static inline void
freezer_exempt(struct task_struct *p){ freezer_exempt_event(p, FE_ALL); }The patch would be shorter. ;-)
Agreed. Will do that.
Quoted 3 lines
[In that case I'd probably rename
freezer_should_exempt()tofreezer_should_exempt_event(), for symmetry.]
Ok.
Quoted 14 lines
kernel/freezer.c line 56
Quoted 11 lines
kernel/freezer.c +11
-0+ +static inline int thawable (struct task_struct *p) +{ +if (!freezeable (p)) +return 0 ; + +/* Thaw p iff it is frozen for current_freezer_event alone */ +if (process_frozen_event_mask (p) & ~current_freezer_event) +return 0 ; + +return 1 ;I would do
Quoted 1 line
return !(process_frozen_event_mask(p) & ~current_freezer_event);
I was wondering if the statement
if (process_frozen_event_mask(p) & ~current_freezer_event) return 0;
would be readable in the first place!
Yeah, we can do what you have suggested.
Quoted 24 lines
Quoted 24 lines
kernel/freezer.c +10
-4-int freeze_processes (void ) +int freeze_processes (unsigned long freeze_event) { -unsigned int nr_unfrozen; +unsigned int nr_unfrozen =0 ; + +mutex_lock (&freezer_mutex); +if (system_frozen_event_mask & freeze_event) + goto out; + + current_freezer_event = freeze_event;printk ("Stopping tasks ... " ); nr_unfrozen =try_to_freeze_tasks (FREEZER_USER_SPACE );if (nr_unfrozen) -return nr_unfrozen; + goto out;sys_sync (); nr_unfrozen =try_to_freeze_tasks (FREEZER_KERNEL_THREADS );if (nr_unfrozen) -return nr_unfrozen; + goto out;
Quoted 5 lines
kernel/freezer.c static unsigned int try_to_freeze_tasks( · line 239
Quoted 3 lines
kernel/freezer.c +1
-0+ system_frozen_event_mask |= current_freezer_event;printk ("done.\n" );BUG_ON (in_atomic ());The
BUG_ON()is still valid if tasks are already frozen for this event.
Right! So we would need one more label. How about the following?
mutex_lock(&freezer_mutex); /* check if already frozen for the event */ if (system_frozen_event_mask & freeze_event) goto out_frozen; . . .
out_frozen:
BUG_ON(in_atomic()); out: current_freezer_event = 0; mutex_unlock(&freezer_mutex); return nr_unfrozen; }
Quoted 12 lines
kernel/freezer.c static void thaw_tasks(int thaw_user_spa · line 267
Quoted 8 lines
kernel/freezer.c +4
-1-void thaw_processes (void ) +void thaw_processes (unsigned long thaw_event) { +mutex_lock (&freezer_mutex); +if (!(system_frozen_event_mask & thaw_event)) { +WARN_ON (1 );Hmm, I wouldn't use the
WARN_ON()here. There's nothing wrong in calling this twice in a row as long as we do the sanity checking. There's even one case in which that may be convenient, actually.
Well, yes. But I put the warn on from the perspective of someone trying to thaw_processes for the event for which they have not frozen. I hadn't thought about a double thaw. Will rethink.
Thanks for the Review.
Regards
gautham.
Signature · 5 lines
Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!"