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>
This commit is contained in:
committed by
Linus Torvalds
parent
787d2214c1
commit
8314418629
@@ -392,6 +392,7 @@ static int kauditd_thread(void *dummy)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
set_freezable();
|
||||
while (!kthread_should_stop()) {
|
||||
skb = skb_dequeue(&audit_skb_queue);
|
||||
wake_up(&audit_backlog_wait);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <linux/mempolicy.h>
|
||||
#include <linux/taskstats_kern.h>
|
||||
#include <linux/delayacct.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/cpuset.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/signal.h>
|
||||
@@ -387,6 +388,11 @@ void daemonize(const char *name, ...)
|
||||
* they would be locked into memory.
|
||||
*/
|
||||
exit_mm(current);
|
||||
/*
|
||||
* We don't want to have TIF_FREEZE set if the system-wide hibernation
|
||||
* or suspend transition begins right now.
|
||||
*/
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
set_special_pids(1, 1);
|
||||
proc_clear_tty(current);
|
||||
|
||||
+1
-1
@@ -923,7 +923,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
|
||||
{
|
||||
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;
|
||||
|
||||
+1
-3
@@ -40,6 +40,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -518,7 +519,6 @@ rcu_torture_writer(void *arg)
|
||||
|
||||
VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
|
||||
set_user_nice(current, 19);
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
do {
|
||||
schedule_timeout_uninterruptible(1);
|
||||
@@ -558,7 +558,6 @@ rcu_torture_fakewriter(void *arg)
|
||||
|
||||
VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
|
||||
set_user_nice(current, 19);
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
do {
|
||||
schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
|
||||
@@ -589,7 +588,6 @@ rcu_torture_reader(void *arg)
|
||||
|
||||
VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
|
||||
set_user_nice(current, 19);
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
do {
|
||||
idx = cur_ops->readlock();
|
||||
|
||||
@@ -260,6 +260,7 @@ static int test_func(void *data)
|
||||
int ret;
|
||||
|
||||
current->flags |= PF_MUTEX_TESTER;
|
||||
set_freezable();
|
||||
allow_signal(SIGHUP);
|
||||
|
||||
for(;;) {
|
||||
|
||||
@@ -4912,8 +4912,6 @@ static int migration_thread(void *data)
|
||||
struct migration_req *req;
|
||||
struct list_head *head;
|
||||
|
||||
try_to_freeze();
|
||||
|
||||
spin_lock_irq(&rq->lock);
|
||||
|
||||
if (cpu_is_offline(cpu)) {
|
||||
@@ -5147,7 +5145,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
|
||||
p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
|
||||
if (IS_ERR(p))
|
||||
return NOTIFY_BAD;
|
||||
p->flags |= PF_NOFREEZE;
|
||||
kthread_bind(p, cpu);
|
||||
/* Must be high prio: stop_machine expects to yield to it. */
|
||||
rq = task_rq_lock(p, &flags);
|
||||
|
||||
+1
-2
@@ -14,6 +14,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/smp.h>
|
||||
@@ -488,8 +489,6 @@ void __init softirq_init(void)
|
||||
|
||||
static int ksoftirqd(void * __bind_cpu)
|
||||
{
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
|
||||
+1
-1
@@ -10,6 +10,7 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/module.h>
|
||||
@@ -116,7 +117,6 @@ static int watchdog(void * __bind_cpu)
|
||||
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
|
||||
|
||||
sched_setscheduler(current, SCHED_FIFO, ¶m);
|
||||
current->flags |= PF_NOFREEZE;
|
||||
|
||||
/* initialize timestamp */
|
||||
touch_softlockup_watchdog();
|
||||
|
||||
+2
-2
@@ -282,8 +282,8 @@ static int worker_thread(void *__cwq)
|
||||
struct cpu_workqueue_struct *cwq = __cwq;
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
if (!cwq->wq->freezeable)
|
||||
current->flags |= PF_NOFREEZE;
|
||||
if (cwq->wq->freezeable)
|
||||
set_freezable();
|
||||
|
||||
set_user_nice(current, -5);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user