From: Gautham R Shenoy <ego@in.ibm.com>
To: akpm@osdl.org, paulmck@us.ibm.com, mingo@elte.hu
Cc: vatsa@in.ibm.com, dipankar@in.ibm.com,
venkatesh.pallipadi@intel.com, linux-kernel@vger.kernel.org,
oleg@tv-sign.ru, rjw@sisk.pl
Subject: [RFC PATCH(Experimental) 1/4] freezer-cpu-hotplug core
Date: Wed, 14 Feb 2007 20:12:29 +0530 [thread overview]
Message-ID: <20070214144229.GA19789@in.ibm.com> (raw)
In-Reply-To: <20070214144031.GA15257@in.ibm.com>
This patch implements process_freezer based cpu-hotplug
core.
The sailent features are:
o No more (un)lock_cpu_hotplug.
o No more CPU_LOCK_ACQUIRE and CPU_LOCK_RELEASE. Hence no per-subsystem
hotcpu mutexes.
o Calls freeze_process/thaw_processes at the beginning/end of
the hotplug operation.
o Splits CPU_DEAD into two events namely
- CPU_DEAD: which will be handled while the processes are still
frozen.
- CPU_DEAD_KILL_THREADS: To be handled after we thaw_processes.
This split is required because stopping of the per-cpu threads
using kthread_stop cannot be done while the system is in the frozen
state. Hence we need subsystems which have created per-cpu threads
have to stop them once thaw_processes have been called.
o Handles CPU_DEAD and CPU_DEAD_KILL_THREADS for subsystems which
create per-cpu threads.
Points to ponder:
o Can calling CPU_DOWN_PREPARE/CPU_UP_PREPARE in the
frozen context create any dirty dependencies in the future?
o Can the SYSTEM_RUNNING hack in _cpu_up be avoided by some cleaner means.
Signed-off-by : Srivatsa Vaddagiri <vatsa@in.ibm.com>
Signed-off-by : Gautham R Shenoy <ego@in.ibm.com>
--
include/linux/notifier.h | 3 --
kernel/cpu.c | 68 +++++++++++++++++++----------------------------
kernel/sched.c | 7 +++-
kernel/softirq.c | 10 ++++--
kernel/softlockup.c | 3 +-
kernel/workqueue.c | 16 ++++++++++-
6 files changed, 58 insertions(+), 49 deletions(-)
Index: hotplug/kernel/cpu.c
===================================================================
--- hotplug.orig/kernel/cpu.c
+++ hotplug/kernel/cpu.c
@@ -14,6 +14,7 @@
#include <linux/kthread.h>
#include <linux/stop_machine.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
/* This protects CPUs going up and down... */
static DEFINE_MUTEX(cpu_add_remove_lock);
@@ -28,38 +29,15 @@ static int cpu_hotplug_disabled;
#ifdef CONFIG_HOTPLUG_CPU
-/* Crappy recursive lock-takers in cpufreq! Complain loudly about idiots */
-static struct task_struct *recursive;
-static int recursive_depth;
-
void lock_cpu_hotplug(void)
{
- struct task_struct *tsk = current;
-
- if (tsk == recursive) {
- static int warnings = 10;
- if (warnings) {
- printk(KERN_ERR "Lukewarm IQ detected in hotplug locking\n");
- WARN_ON(1);
- warnings--;
- }
- recursive_depth++;
- return;
- }
- mutex_lock(&cpu_bitmask_lock);
- recursive = tsk;
+ return;
}
EXPORT_SYMBOL_GPL(lock_cpu_hotplug);
void unlock_cpu_hotplug(void)
{
- WARN_ON(recursive != current);
- if (recursive_depth) {
- recursive_depth--;
- return;
- }
- recursive = NULL;
- mutex_unlock(&cpu_bitmask_lock);
+ return;
}
EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
@@ -133,7 +111,11 @@ static int _cpu_down(unsigned int cpu)
if (!cpu_online(cpu))
return -EINVAL;
- raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu);
+ if (freeze_processes()) {
+ thaw_processes();
+ return -EBUSY;
+ }
+
err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
hcpu, -1, &nr_calls);
if (err == NOTIFY_BAD) {
@@ -141,8 +123,8 @@ static int _cpu_down(unsigned int cpu)
nr_calls, NULL);
printk("%s: attempt to take down CPU %u failed\n",
__FUNCTION__, cpu);
- err = -EINVAL;
- goto out_release;
+ thaw_processes();
+ return -EINVAL;
}
/* Ensure that we are not runnable on dying cpu */
@@ -151,9 +133,7 @@ static int _cpu_down(unsigned int cpu)
cpu_clear(cpu, tmp);
set_cpus_allowed(current, tmp);
- mutex_lock(&cpu_bitmask_lock);
p = __stop_machine_run(take_cpu_down, NULL, cpu);
- mutex_unlock(&cpu_bitmask_lock);
if (IS_ERR(p) || cpu_online(cpu)) {
/* CPU didn't die: tell everyone. Can't complain. */
@@ -161,9 +141,12 @@ static int _cpu_down(unsigned int cpu)
hcpu) == NOTIFY_BAD)
BUG();
+ set_cpus_allowed(current, old_allowed);
+ thaw_processes();
+
if (IS_ERR(p)) {
err = PTR_ERR(p);
- goto out_allowed;
+ return err;
}
goto out_thread;
}
@@ -185,13 +168,12 @@ static int _cpu_down(unsigned int cpu)
check_for_tasks(cpu);
+ thaw_processes();
+
+ if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD_KILL_THREADS, hcpu) == NOTIFY_BAD)
+ BUG();
out_thread:
err = kthread_stop(p);
-out_allowed:
- set_cpus_allowed(current, old_allowed);
-out_release:
- raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE,
- (void *)(long)cpu);
return err;
}
@@ -219,7 +201,12 @@ static int __cpuinit _cpu_up(unsigned in
if (cpu_online(cpu) || !cpu_present(cpu))
return -EINVAL;
- raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu);
+ if (system_state == SYSTEM_RUNNING && freeze_processes()) {
+ if (system_state == SYSTEM_RUNNING)
+ thaw_processes();
+ return -EBUSY;
+ }
+
ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu,
-1, &nr_calls);
if (ret == NOTIFY_BAD) {
@@ -229,10 +216,9 @@ static int __cpuinit _cpu_up(unsigned in
goto out_notify;
}
+
/* Arch-specific enabling code. */
- mutex_lock(&cpu_bitmask_lock);
ret = __cpu_up(cpu);
- mutex_unlock(&cpu_bitmask_lock);
if (ret != 0)
goto out_notify;
BUG_ON(!cpu_online(cpu));
@@ -241,10 +227,12 @@ static int __cpuinit _cpu_up(unsigned in
raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
out_notify:
+ if (system_state == SYSTEM_RUNNING)
+ thaw_processes();
+
if (ret != 0)
__raw_notifier_call_chain(&cpu_chain,
CPU_UP_CANCELED, hcpu, nr_calls, NULL);
- raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu);
return ret;
}
Index: hotplug/kernel/softirq.c
===================================================================
--- hotplug.orig/kernel/softirq.c
+++ hotplug/kernel/softirq.c
@@ -18,6 +18,7 @@
#include <linux/rcupdate.h>
#include <linux/smp.h>
#include <linux/tick.h>
+#include <linux/freezer.h>
#include <asm/irq.h>
/*
@@ -489,7 +490,6 @@ void __init softirq_init(void)
static int ksoftirqd(void * __bind_cpu)
{
set_user_nice(current, 19);
- current->flags |= PF_NOFREEZE;
set_current_state(TASK_INTERRUPTIBLE);
@@ -515,6 +515,9 @@ static int ksoftirqd(void * __bind_cpu)
preempt_disable();
}
preempt_enable();
+ try_to_freeze();
+ if (cpu_is_offline((long)__bind_cpu))
+ goto wait_to_die;
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
@@ -612,11 +615,12 @@ static int __cpuinit cpu_callback(struct
kthread_bind(per_cpu(ksoftirqd, hotcpu),
any_online_cpu(cpu_online_map));
case CPU_DEAD:
+ takeover_tasklets(hotcpu);
+ break;
+ case CPU_DEAD_KILL_THREADS:
p = per_cpu(ksoftirqd, hotcpu);
per_cpu(ksoftirqd, hotcpu) = NULL;
kthread_stop(p);
- takeover_tasklets(hotcpu);
- break;
#endif /* CONFIG_HOTPLUG_CPU */
}
return NOTIFY_OK;
Index: hotplug/kernel/sched.c
===================================================================
--- hotplug.orig/kernel/sched.c
+++ hotplug/kernel/sched.c
@@ -5519,8 +5519,6 @@ migration_call(struct notifier_block *nf
case CPU_DEAD:
migrate_live_tasks(cpu);
rq = cpu_rq(cpu);
- kthread_stop(rq->migration_thread);
- rq->migration_thread = NULL;
/* Idle task back to normal (off runqueue, low prio) */
rq = task_rq_lock(rq->idle, &flags);
deactivate_task(rq->idle, rq);
@@ -5545,6 +5543,11 @@ migration_call(struct notifier_block *nf
}
spin_unlock_irq(&rq->lock);
break;
+ case CPU_DEAD_KILL_THREADS:
+ rq = cpu_rq(cpu);
+ kthread_stop(rq->migration_thread);
+ rq->migration_thread = NULL;
+ break;
#endif
case CPU_LOCK_RELEASE:
mutex_unlock(&sched_hotcpu_mutex);
Index: hotplug/kernel/softlockup.c
===================================================================
--- hotplug.orig/kernel/softlockup.c
+++ hotplug/kernel/softlockup.c
@@ -13,6 +13,7 @@
#include <linux/kthread.h>
#include <linux/notifier.h>
#include <linux/module.h>
+#include <linux/freezer.h>
static DEFINE_SPINLOCK(print_lock);
@@ -132,7 +133,7 @@ cpu_callback(struct notifier_block *nfb,
/* Unbind so it can run. Fall thru. */
kthread_bind(per_cpu(watchdog_task, hotcpu),
any_online_cpu(cpu_online_map));
- case CPU_DEAD:
+ case CPU_DEAD_KILL_THREADS:
p = per_cpu(watchdog_task, hotcpu);
per_cpu(watchdog_task, hotcpu) = NULL;
kthread_stop(p);
Index: hotplug/kernel/workqueue.c
===================================================================
--- hotplug.orig/kernel/workqueue.c
+++ hotplug/kernel/workqueue.c
@@ -368,6 +368,7 @@ static int worker_thread(void *__cwq)
DEFINE_WAIT(wait);
struct k_sigaction sa;
sigset_t blocked;
+ int bind_cpu = smp_processor_id();
if (!cwq->wq->freezeable)
current->flags |= PF_NOFREEZE;
@@ -392,8 +393,11 @@ static int worker_thread(void *__cwq)
do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
for (;;) {
- if (cwq->wq->freezeable)
+ if (cwq->wq->freezeable) {
try_to_freeze();
+ if (cpu_is_offline(bind_cpu))
+ goto wait_to_die;
+ }
prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
if (!cwq->should_stop && list_empty(&cwq->worklist))
@@ -407,6 +411,16 @@ static int worker_thread(void *__cwq)
}
return 0;
+
+wait_to_die:
+ /* Wait for kthread_stop */
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!kthread_should_stop()) {
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ __set_current_state(TASK_RUNNING);
+ return 0;
}
struct wq_barrier {
Index: hotplug/include/linux/notifier.h
===================================================================
--- hotplug.orig/include/linux/notifier.h
+++ hotplug/include/linux/notifier.h
@@ -194,8 +194,7 @@ extern int __srcu_notifier_call_chain(st
#define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */
#define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */
#define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */
-#define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */
-#define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */
+#define CPU_DEAD_KILL_THREADS 0x0008 /* Kill per-cpu threads after dead */
#endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */
--
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!"
next prev parent reply other threads:[~2007-02-14 14:42 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-14 14:40 [RFC PATCH(Experimental) 0/4] Freezer based Cpu-hotplug Gautham R Shenoy
2007-02-14 14:42 ` Gautham R Shenoy [this message]
2007-02-14 14:43 ` [RFC PATCH(Experimental) 2/4] Revert changes to workqueue.c Gautham R Shenoy
2007-02-14 14:43 ` [RFC PATCH(Experimental) 3/4] Revert changes to sched.c and slab.c Gautham R Shenoy
2007-02-14 14:44 ` [RFC PATCH(Experimental) 4/4] Rip out lock_cpu_hotplug from linux Gautham R Shenoy
2007-02-14 14:59 ` [RFC PATCH(Experimental) 2/4] Revert changes to workqueue.c Srivatsa Vaddagiri
2007-02-14 15:24 ` Srivatsa Vaddagiri
2007-02-14 20:23 ` Oleg Nesterov
2007-02-14 20:09 ` Oleg Nesterov
2007-02-16 5:26 ` Srivatsa Vaddagiri
2007-02-16 15:33 ` Oleg Nesterov
2007-02-16 16:47 ` Srivatsa Vaddagiri
2007-02-16 18:45 ` Oleg Nesterov
2007-02-16 23:59 ` Oleg Nesterov
2007-02-17 2:29 ` Srivatsa Vaddagiri
2007-02-17 21:59 ` Oleg Nesterov
2007-02-20 15:12 ` Srivatsa Vaddagiri
2007-02-20 20:09 ` Oleg Nesterov
2007-02-21 6:29 ` Srivatsa Vaddagiri
2007-02-21 14:30 ` Oleg Nesterov
2007-02-21 14:37 ` Gautham R Shenoy
2007-02-21 15:53 ` Srivatsa Vaddagiri
2007-02-14 15:31 ` [RFC PATCH(Experimental) 1/4] freezer-cpu-hotplug core Srivatsa Vaddagiri
2007-02-14 19:47 ` Oleg Nesterov
2007-02-16 6:48 ` Srivatsa Vaddagiri
2007-02-16 15:47 ` Oleg Nesterov
2007-02-14 20:22 ` Oleg Nesterov
2007-02-16 7:16 ` Srivatsa Vaddagiri
2007-02-16 8:12 ` Srivatsa Vaddagiri
2007-02-16 9:29 ` Rafael J. Wysocki
2007-02-16 9:59 ` Srivatsa Vaddagiri
2007-02-16 11:06 ` Rafael J. Wysocki
2007-02-16 19:46 ` Oleg Nesterov
2007-02-17 2:31 ` Srivatsa Vaddagiri
2007-02-17 5:32 ` Gautham R Shenoy
2007-02-17 11:19 ` Gautham R Shenoy
2007-02-16 16:06 ` Oleg Nesterov
2007-02-14 21:43 ` [RFC PATCH(Experimental) 0/4] Freezer based Cpu-hotplug Rafael J. Wysocki
2007-02-15 6:34 ` Gautham R Shenoy
2007-02-15 8:09 ` Rafael J. Wysocki
2007-02-15 12:20 ` Gautham R Shenoy
2007-02-15 13:31 ` Rafael J. Wysocki
2007-02-15 14:25 ` Gautham R Shenoy
2007-02-17 11:24 ` Rafael J. Wysocki
2007-02-17 21:34 ` Oleg Nesterov
2007-02-17 22:24 ` Rafael J. Wysocki
2007-02-17 23:42 ` Oleg Nesterov
2007-02-17 23:47 ` Oleg Nesterov
2007-02-18 10:43 ` Rafael J. Wysocki
2007-02-18 11:31 ` Oleg Nesterov
2007-02-18 12:14 ` Rafael J. Wysocki
2007-02-18 14:52 ` freezer problems Oleg Nesterov
2007-02-18 15:14 ` Rafael J. Wysocki
2007-02-18 16:19 ` Oleg Nesterov
2007-02-18 18:14 ` Rafael J. Wysocki
2007-02-18 18:56 ` Rafael J. Wysocki
2007-02-18 22:01 ` Oleg Nesterov
2007-02-18 23:19 ` Rafael J. Wysocki
2007-02-19 20:23 ` Oleg Nesterov
2007-02-19 21:21 ` Rafael J. Wysocki
2007-02-19 22:41 ` Oleg Nesterov
2007-02-19 23:35 ` Rafael J. Wysocki
2007-02-20 0:12 ` Oleg Nesterov
2007-02-20 0:32 ` Rafael J. Wysocki
2007-02-20 0:50 ` Oleg Nesterov
2007-02-20 18:28 ` Rafael J. Wysocki
2007-02-20 18:29 ` Rafael J. Wysocki
2007-02-21 18:14 ` Paul E. McKenney
2007-02-21 18:13 ` Rafael J. Wysocki
2007-02-21 18:27 ` Paul E. McKenney
2007-02-21 20:03 ` Oleg Nesterov
2007-02-21 20:47 ` Rafael J. Wysocki
2007-02-21 21:06 ` Paul E. McKenney
2007-02-21 23:10 ` Rafael J. Wysocki
2007-02-22 10:47 ` Oleg Nesterov
2007-02-22 11:33 ` Oleg Nesterov
2007-02-22 17:03 ` Rafael J. Wysocki
2007-02-22 17:44 ` Oleg Nesterov
2007-02-22 21:56 ` Rafael J. Wysocki
2007-02-23 18:15 ` Oleg Nesterov
2007-02-23 3:02 ` Gautham R Shenoy
2007-02-18 15:09 ` [RFC PATCH(Experimental) 0/4] Freezer based Cpu-hotplug Rafael J. Wysocki
2007-02-18 16:11 ` Oleg Nesterov
2007-02-18 18:51 ` Rafael J. Wysocki
2007-02-18 10:32 ` Rafael J. Wysocki
2007-02-18 11:32 ` Oleg Nesterov
2007-02-18 12:12 ` Rafael J. Wysocki
2007-02-18 15:06 ` Oleg Nesterov
2007-02-18 12:56 ` Pavel Machek
2007-02-21 14:52 ` Gautham R Shenoy
2007-02-21 19:42 ` Pavel Machek
[not found] ` <200702231041.17136.rjw@sisk.pl>
[not found] ` <20070223100817.GA10973@in.ibm.com>
[not found] ` <200702231115.00718.rjw@sisk.pl>
[not found] ` <20070223104723.GB10973@in.ibm.com>
[not found] ` <20070223110201.GC10973@in.ibm.com>
2007-02-23 19:03 ` freezer problems Gautham R Shenoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070214144229.GA19789@in.ibm.com \
--to=ego@in.ibm.com \
--cc=akpm@osdl.org \
--cc=dipankar@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@tv-sign.ru \
--cc=paulmck@us.ibm.com \
--cc=rjw@sisk.pl \
--cc=vatsa@in.ibm.com \
--cc=venkatesh.pallipadi@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.