aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-07-17 07:03:35 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:02 -0400
commit831441862956fffa17b9801db37e6ea1650b0f69 (patch)
treeb0334921341f8f1734bdd3243de76d676329d21c /kernel
parent787d2214c19bcc9b6ac48af0ce098277a801eded (diff)
Freezer: make kernel threads nonfreezable by default
Currently, the freezer treats all tasks as freezable, except for the kernel threads that explicitly set the PF_NOFREEZE flag for themselves. This approach is problematic, since it requires every kernel thread to either set PF_NOFREEZE explicitly, or call try_to_freeze(), even if it doesn't care for the freezing of tasks at all. It seems better to only require the kernel threads that want to or need to be frozen to use some freezer-related code and to remove any freezer-related code from the other (nonfreezable) kernel threads, which is done in this patch. The patch causes all kernel threads to be nonfreezable by default (ie. to have PF_NOFREEZE set by default) and introduces the set_freezable() function that should be called by the freezable kernel threads in order to unset PF_NOFREEZE. It also makes all of the currently freezable kernel threads call set_freezable(), so it shouldn't cause any (intentional) change of behaviour to appear. Additionally, it updates documentation to describe the freezing of tasks more accurately. [akpm@linux-foundation.org: build fixes] Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Nigel Cunningham <nigel@nigel.suspend2.net> Cc: Pavel Machek <pavel@ucw.cz> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Gautham R Shenoy <ego@in.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c1
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/rcutorture.c4
-rw-r--r--kernel/rtmutex-tester.c1
-rw-r--r--kernel/sched.c3
-rw-r--r--kernel/softirq.c3
-rw-r--r--kernel/softlockup.c2
-rw-r--r--kernel/workqueue.c4
9 files changed, 14 insertions, 12 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 5ce8851facf7..eb0f9165b401 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -392,6 +392,7 @@ static int kauditd_thread(void *dummy)
392{ 392{
393 struct sk_buff *skb; 393 struct sk_buff *skb;
394 394
395 set_freezable();
395 while (!kthread_should_stop()) { 396 while (!kthread_should_stop()) {
396 skb = skb_dequeue(&audit_skb_queue); 397 skb = skb_dequeue(&audit_skb_queue);
397 wake_up(&audit_backlog_wait); 398 wake_up(&audit_backlog_wait);
diff --git a/kernel/exit.c b/kernel/exit.c
index 57626692cd90..e8af8d0c2483 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -31,6 +31,7 @@
31#include <linux/mempolicy.h> 31#include <linux/mempolicy.h>
32#include <linux/taskstats_kern.h> 32#include <linux/taskstats_kern.h>
33#include <linux/delayacct.h> 33#include <linux/delayacct.h>
34#include <linux/freezer.h>
34#include <linux/cpuset.h> 35#include <linux/cpuset.h>
35#include <linux/syscalls.h> 36#include <linux/syscalls.h>
36#include <linux/signal.h> 37#include <linux/signal.h>
@@ -387,6 +388,11 @@ void daemonize(const char *name, ...)
387 * they would be locked into memory. 388 * they would be locked into memory.
388 */ 389 */
389 exit_mm(current); 390 exit_mm(current);
391 /*
392 * We don't want to have TIF_FREEZE set if the system-wide hibernation
393 * or suspend transition begins right now.
394 */
395 current->flags |= PF_NOFREEZE;
390 396
391 set_special_pids(1, 1); 397 set_special_pids(1, 1);
392 proc_clear_tty(current); 398 proc_clear_tty(current);
diff --git a/kernel/fork.c b/kernel/fork.c
index 7c5c5888e00a..ba39bdb2a7b8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -923,7 +923,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
923{ 923{
924 unsigned long new_flags = p->flags; 924 unsigned long new_flags = p->flags;
925 925
926 new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE); 926 new_flags &= ~PF_SUPERPRIV;
927 new_flags |= PF_FORKNOEXEC; 927 new_flags |= PF_FORKNOEXEC;
928 if (!(clone_flags & CLONE_PTRACE)) 928 if (!(clone_flags & CLONE_PTRACE))
929 p->ptrace = 0; 929 p->ptrace = 0;
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 55ba82a85a66..ddff33247785 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -40,6 +40,7 @@
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/percpu.h> 41#include <linux/percpu.h>
42#include <linux/notifier.h> 42#include <linux/notifier.h>
43#include <linux/freezer.h>
43#include <linux/cpu.h> 44#include <linux/cpu.h>
44#include <linux/random.h> 45#include <linux/random.h>
45#include <linux/delay.h> 46#include <linux/delay.h>
@@ -518,7 +519,6 @@ rcu_torture_writer(void *arg)
518 519
519 VERBOSE_PRINTK_STRING("rcu_torture_writer task started"); 520 VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
520 set_user_nice(current, 19); 521 set_user_nice(current, 19);
521 current->flags |= PF_NOFREEZE;
522 522
523 do { 523 do {
524 schedule_timeout_uninterruptible(1); 524 schedule_timeout_uninterruptible(1);
@@ -558,7 +558,6 @@ rcu_torture_fakewriter(void *arg)
558 558
559 VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started"); 559 VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
560 set_user_nice(current, 19); 560 set_user_nice(current, 19);
561 current->flags |= PF_NOFREEZE;
562 561
563 do { 562 do {
564 schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); 563 schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
@@ -589,7 +588,6 @@ rcu_torture_reader(void *arg)
589 588
590 VERBOSE_PRINTK_STRING("rcu_torture_reader task started"); 589 VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
591 set_user_nice(current, 19); 590 set_user_nice(current, 19);
592 current->flags |= PF_NOFREEZE;
593 591
594 do { 592 do {
595 idx = cur_ops->readlock(); 593 idx = cur_ops->readlock();
diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c
index 015fc633c96c..e3055ba69159 100644
--- a/kernel/rtmutex-tester.c
+++ b/kernel/rtmutex-tester.c
@@ -260,6 +260,7 @@ static int test_func(void *data)
260 int ret; 260 int ret;
261 261
262 current->flags |= PF_MUTEX_TESTER; 262 current->flags |= PF_MUTEX_TESTER;
263 set_freezable();
263 allow_signal(SIGHUP); 264 allow_signal(SIGHUP);
264 265
265 for(;;) { 266 for(;;) {
diff --git a/kernel/sched.c b/kernel/sched.c
index 1c8076676eb1..cb31fb4a1379 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4912,8 +4912,6 @@ static int migration_thread(void *data)
4912 struct migration_req *req; 4912 struct migration_req *req;
4913 struct list_head *head; 4913 struct list_head *head;
4914 4914
4915 try_to_freeze();
4916
4917 spin_lock_irq(&rq->lock); 4915 spin_lock_irq(&rq->lock);
4918 4916
4919 if (cpu_is_offline(cpu)) { 4917 if (cpu_is_offline(cpu)) {
@@ -5147,7 +5145,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5147 p = kthread_create(migration_thread, hcpu, "migration/%d", cpu); 5145 p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
5148 if (IS_ERR(p)) 5146 if (IS_ERR(p))
5149 return NOTIFY_BAD; 5147 return NOTIFY_BAD;
5150 p->flags |= PF_NOFREEZE;
5151 kthread_bind(p, cpu); 5148 kthread_bind(p, cpu);
5152 /* Must be high prio: stop_machine expects to yield to it. */ 5149 /* Must be high prio: stop_machine expects to yield to it. */
5153 rq = task_rq_lock(p, &flags); 5150 rq = task_rq_lock(p, &flags);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 8de267790166..0f546ddea43d 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -14,6 +14,7 @@
14#include <linux/notifier.h> 14#include <linux/notifier.h>
15#include <linux/percpu.h> 15#include <linux/percpu.h>
16#include <linux/cpu.h> 16#include <linux/cpu.h>
17#include <linux/freezer.h>
17#include <linux/kthread.h> 18#include <linux/kthread.h>
18#include <linux/rcupdate.h> 19#include <linux/rcupdate.h>
19#include <linux/smp.h> 20#include <linux/smp.h>
@@ -488,8 +489,6 @@ void __init softirq_init(void)
488 489
489static int ksoftirqd(void * __bind_cpu) 490static int ksoftirqd(void * __bind_cpu)
490{ 491{
491 current->flags |= PF_NOFREEZE;
492
493 set_current_state(TASK_INTERRUPTIBLE); 492 set_current_state(TASK_INTERRUPTIBLE);
494 493
495 while (!kthread_should_stop()) { 494 while (!kthread_should_stop()) {
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 0131e296ffb4..708d4882c0c3 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -10,6 +10,7 @@
10#include <linux/cpu.h> 10#include <linux/cpu.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/freezer.h>
13#include <linux/kthread.h> 14#include <linux/kthread.h>
14#include <linux/notifier.h> 15#include <linux/notifier.h>
15#include <linux/module.h> 16#include <linux/module.h>
@@ -116,7 +117,6 @@ static int watchdog(void * __bind_cpu)
116 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; 117 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
117 118
118 sched_setscheduler(current, SCHED_FIFO, &param); 119 sched_setscheduler(current, SCHED_FIFO, &param);
119 current->flags |= PF_NOFREEZE;
120 120
121 /* initialize timestamp */ 121 /* initialize timestamp */
122 touch_softlockup_watchdog(); 122 touch_softlockup_watchdog();
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index d7d3fa3072e5..1935302cc645 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -282,8 +282,8 @@ static int worker_thread(void *__cwq)
282 struct cpu_workqueue_struct *cwq = __cwq; 282 struct cpu_workqueue_struct *cwq = __cwq;
283 DEFINE_WAIT(wait); 283 DEFINE_WAIT(wait);
284 284
285 if (!cwq->wq->freezeable) 285 if (cwq->wq->freezeable)
286 current->flags |= PF_NOFREEZE; 286 set_freezable();
287 287
288 set_user_nice(current, -5); 288 set_user_nice(current, -5);
289 289