Skip to contentSkip to conversation

Separate freezer from PM code

PATCH In review Rafael J. Wysocki 6 participants 23 messages Apr 27, 2007 – Apr 30, 2007

Subsystems (23)
Arm (32-bit) SCSI USB PowerPC +19 more subsystems
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
Index: linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug
===================================================================
@@ -24,3 +24,8 @@ source "kernel/Kconfig.marker"
 endmenu
 
 endmenu
+
+config FREEZER
+	bool
+	default y
+	depends on KPROBES
arch/frv/Kconfig +5 -0
Index: linux-2.6.21-rc7-mm2/arch/frv/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/i386/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ia64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ppc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/s390/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sh/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/power/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/kprobes.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/linux/freezer.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/arm/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/blackfin/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/mips/Kconfig
===================================================================
@@ -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

#2 lore raw
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

#3 lore raw
In reply to Rafael J. Wysocki
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

#4 lore raw
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 Kconfig here (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
Index: linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/frv/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/i386/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ia64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ppc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/s390/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sh/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/power/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/kprobes.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/linux/freezer.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/arm/Kconfig
===================================================================
@@ -41,6 +41,10 @@ config NO_IOPORT
 	bool
 	default n
 
+config FREEZER
+	bool
+	default n
+
 config EISA
 	bool
 	---help---
arch/blackfin/Kconfig +4 -0
Index: linux-2.6.21-rc7-mm2/arch/blackfin/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/mips/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/power/Kconfig
===================================================================
@@ -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
#5 lore raw
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

#6 lore raw
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.c is in kernel/, then shouldn't the corresponding config var be in a non-arch Kconfig file?

Well, I though it would look strange. Still, I can do that, of course:

---
From: Rafael J. Wysocki <[email protected]>

Now that the freezer is used by kprobes, it is no longer a PM-specific piece of code. Move the freezer code out of kernel/power and introduce the CONFIG_FREEZER option that will be chosen automatically if PM or KPROBES is set.

---
 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
Index: linux-2.6.21-rc7-mm2/arch/x86_64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig.debug
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/frv/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/i386/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ia64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/powerpc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/ppc/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/s390/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sh/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/sparc64/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/power/Makefile
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/kprobes.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/linux/freezer.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/arm/Kconfig
===================================================================
@@ -925,6 +925,8 @@ config ARTHUR
 
 endmenu
 
+source "kernel/Kconfig.freezer"
+
 menu "Power management options"
 
 source "kernel/power/Kconfig"
arch/blackfin/Kconfig +2 -0
Index: linux-2.6.21-rc7-mm2/arch/blackfin/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/mips/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/avr32/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/power/Kconfig
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/Kconfig.freezer
===================================================================
@@ -0,0 +1,5 @@
+# Tasks freezer configuration
+
+config FREEZER
+	bool
+	default n
#7 lore raw
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.c is in kernel/, then shouldn't the corresponding config var be in a non-arch Kconfig file?

Well, I though it would look strange. Still, I can do that, of course:

It would have been much better to have a single kernel/Kconfig so you avoided all the arch specific source lines. But thats not this patch and can come later.

So I'm OK with this one.

Sam

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_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(-)

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() establishes

Index: 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() establishes

Index: 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
 endmenu

Index: 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() establishes

Index: 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() establishes

Index: 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() establishes

Index: 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
 endif

Index: 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() establishes

Index: 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 EXPERIMENTAL
 

Index: 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() establishes

Index: 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.o

Index: 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.o
 

Index: 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(&current->sighand->siglock);
+	recalc_sigpending(); /* We sent fake signal, clean it up */
+	spin_unlock_irq(&current->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(&current->sighand->siglock);
-	recalc_sigpending(); /* We sent fake signal, clean it up */
-	spin_unlock_irq(&current->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 not

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

#8 lore raw

PATCH 2/2 Introduce freezer flags

In reply to Rafael J. Wysocki

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
Index: linux-2.6.21-rc7-mm2/include/linux/sched.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-arm/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-blackfin/thread_info.h
===================================================================
@@ -125,7 +125,6 @@ static inline struct thread_info *curren
 					   TIF_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
Index: linux-2.6.21-rc7-mm2/include/asm-frv/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-i386/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-ia64/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-mips/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-powerpc/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-sh/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-x86_64/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/sched.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/i386/kernel/apm.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/block/loop.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/char/apm-emulation.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/ieee1394/ieee1394_core.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/md/md.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/mmc/card/queue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/mtd/mtd_blkdevs.c
===================================================================
@@ -81,7 +81,8 @@ static int mtd_blktrans_thread(void *arg
 	struct 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
Index: linux-2.6.21-rc7-mm2/drivers/scsi/libsas/sas_scsi_host.c
===================================================================
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_h
 	struct 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
Index: linux-2.6.21-rc7-mm2/drivers/scsi/scsi_error.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/usb/storage/usb.c
===================================================================
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(void 
 	struct 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
Index: linux-2.6.21-rc7-mm2/kernel/fork.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/rcutorture.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/softirq.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/softlockup.c
===================================================================
@@ -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, &param);
-	current->flags |= PF_NOFREEZE;
+	freezer_exempt(current);
 
 	/* initialize timestamp */
 	touch_softlockup_watchdog();
kernel/workqueue.c +1 -1
Index: linux-2.6.21-rc7-mm2/kernel/workqueue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/freezer.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/Documentation/power/kernel_threads.txt
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/Documentation/power/swsusp.txt
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/kthread.c
===================================================================
@@ -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);
#9 lore raw

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

#10 lore raw

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!"
#11 lore raw

Re: [PATCH -mm 2/2] Introduce freezer flags

In reply to Rafael J. Wysocki
Quoted 11 lines · Rafael J. Wysocki

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.

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 type
include/linux/freezer.h: In function `clear_frozen_flag':
include/linux/freezer.h:32: warning: passing arg 2 of `clear_bit' from incompatible pointer type
include/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 type
include/linux/freezer.h: In function `clear_freeze_flag':
include/linux/freezer.h:56: warning: passing arg 2 of `clear_bit' from incompatible pointer type
include/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 type
include/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
include/linux/freezer.h: In function `freezer_count':
include/linux/freezer.h:142: warning: passing arg 2 of `clear_bit' from incompatible pointer type
include/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!"
#12 lore raw

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_struct and introduce functions to operate them using set_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 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 type
include/linux/freezer.h: In function `clear_frozen_flag':
include/linux/freezer.h:32: warning: passing arg 2 of `clear_bit' from incompatible pointer type
include/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 type
include/linux/freezer.h: In function `clear_freeze_flag':
include/linux/freezer.h:56: warning: passing arg 2 of `clear_bit' from incompatible pointer type
include/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 type
include/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 type
include/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

Greetings,
Rafael

#13 lore raw

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!"
#14 lore raw

Re: [PATCH -mm 2/2] Introduce freezer flags

In reply to Rafael J. Wysocki
Quoted 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_struct and introduce functions to operate them using set_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

#15 lore raw

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
#16 lore raw

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
Index: linux-2.6.21-rc7-mm2/include/linux/sched.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-arm/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-blackfin/thread_info.h
===================================================================
@@ -125,7 +125,6 @@ static inline struct thread_info *curren
 					   TIF_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
Index: linux-2.6.21-rc7-mm2/include/asm-frv/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-i386/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-ia64/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-mips/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-powerpc/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-sh/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/include/asm-x86_64/thread_info.h
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/sched.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/arch/i386/kernel/apm.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/block/loop.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/char/apm-emulation.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/ieee1394/ieee1394_core.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/md/md.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/mmc/card/queue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/mtd/mtd_blkdevs.c
===================================================================
@@ -81,7 +81,8 @@ static int mtd_blktrans_thread(void *arg
 	struct 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
Index: linux-2.6.21-rc7-mm2/drivers/scsi/libsas/sas_scsi_host.c
===================================================================
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_h
 	struct 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
Index: linux-2.6.21-rc7-mm2/drivers/scsi/scsi_error.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/drivers/usb/storage/usb.c
===================================================================
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(void 
 	struct 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
Index: linux-2.6.21-rc7-mm2/kernel/fork.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/rcutorture.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/softirq.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/softlockup.c
===================================================================
@@ -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, &param);
-	current->flags |= PF_NOFREEZE;
+	freezer_exempt(current);
 
 	/* initialize timestamp */
 	touch_softlockup_watchdog();
kernel/workqueue.c +1 -1
Index: linux-2.6.21-rc7-mm2/kernel/workqueue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/freezer.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/Documentation/power/kernel_threads.txt
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/Documentation/power/swsusp.txt
===================================================================
@@ -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
Index: linux-2.6.21-rc7-mm2/kernel/kthread.c
===================================================================
@@ -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);
#17 lore raw

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_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.

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
#18 lore raw

PATCH 1/1 Allow selective freezing of the system for different events

In reply to Rafael J. Wysocki

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_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
Index: linux-2.6.21-rc7/include/linux/freezer.h
===================================================================
@@ -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_s
 static 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
Index: linux-2.6.21-rc7/arch/i386/kernel/apm.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/block/loop.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/char/apm-emulation.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/ieee1394/ieee1394_core.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/md/md.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/mmc/card/queue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/mtd/mtd_blkdevs.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/scsi/libsas/sas_scsi_host.c
===================================================================
@@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_h
 	struct 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
Index: linux-2.6.21-rc7/drivers/scsi/scsi_error.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/drivers/usb/storage/usb.c
===================================================================
@@ -301,7 +301,7 @@ static int usb_stor_control_thread(void 
 	struct 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
Index: linux-2.6.21-rc7/kernel/kthread.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/rcutorture.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/sched.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/softirq.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/softlockup.c
===================================================================
@@ -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, &param);
-	freezer_exempt(current);
+	freezer_exempt(current, FE_ALL);
 
 	/* initialize timestamp */
 	touch_softlockup_watchdog();
kernel/workqueue.c +1 -1
Index: linux-2.6.21-rc7/kernel/workqueue.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/kprobes.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/power/disk.c
===================================================================
@@ -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
Index: linux-2.6.21-rc7/kernel/power/main.c
===================================================================
@@ -90,9 +90,9 @@ static int suspend_prepare(suspend_state
 	if (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_state
 	resume_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_state
 	device_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
Index: linux-2.6.21-rc7/kernel/power/user.c
===================================================================
@@ -81,7 +81,7 @@ static void snapshot_unfreeze(struct sna
 		return;
 
 	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!"
maintainer
#19 lore raw

Re: [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_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.

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.

#20 lore raw

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_A would be SUSPEND and EVENT_B would be HOTPLUG_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!"
#21 lore raw

Re: [PATCH -mm] Allow selective freezing of the system for different events

In reply to Gautham R Shenoy

Hi,

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_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(-)

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_s
 static 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 -1
 
 	sys_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_spa
 
 	read_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_spa
 	read_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_h
 	struct 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(void 
 	struct 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, &param);
-	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_state
 	if (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_state
 	resume_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_state
 	device_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 sna
 		return;
 
 	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;
 		}
#22 lore raw

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 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);
}
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() to freezer_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!"