diff options
| author | Tejun Heo <tj@kernel.org> | 2010-05-06 12:49:20 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2010-05-06 12:49:20 -0400 |
| commit | 1142d810298e694754498dbb4983fcb6cb7fd884 (patch) | |
| tree | 8c5d23b76f129e23d9d967182aa434795e44af5c /include/linux | |
| parent | 99bd5e2f245d8cd17d040c82d40becdb3efd9b69 (diff) | |
cpu_stop: implement stop_cpu[s]()
Implement a simplistic per-cpu maximum priority cpu monopolization
mechanism. A non-sleeping callback can be scheduled to run on one or
multiple cpus with maximum priority monopolozing those cpus. This is
primarily to replace and unify RT workqueue usage in stop_machine and
scheduler migration_thread which currently is serving multiple
purposes.
Four functions are provided - stop_one_cpu(), stop_one_cpu_nowait(),
stop_cpus() and try_stop_cpus().
This is to allow clean sharing of resources among stop_cpu and all the
migration thread users. One stopper thread per cpu is created which
is currently named "stopper/CPU". This will eventually replace the
migration thread and take on its name.
* This facility was originally named cpuhog and lived in separate
files but Peter Zijlstra nacked the name and thus got renamed to
cpu_stop and moved into stop_machine.c.
* Better reporting of preemption leak as per Peter's suggestion.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Dimitri Sivanich <sivanich@sgi.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/stop_machine.h | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index baba3a23a814..efcbd6c37947 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h | |||
| @@ -1,15 +1,46 @@ | |||
| 1 | #ifndef _LINUX_STOP_MACHINE | 1 | #ifndef _LINUX_STOP_MACHINE |
| 2 | #define _LINUX_STOP_MACHINE | 2 | #define _LINUX_STOP_MACHINE |
| 3 | /* "Bogolock": stop the entire machine, disable interrupts. This is a | 3 | |
| 4 | very heavy lock, which is equivalent to grabbing every spinlock | ||
| 5 | (and more). So the "read" side to such a lock is anything which | ||
| 6 | disables preeempt. */ | ||
| 7 | #include <linux/cpu.h> | 4 | #include <linux/cpu.h> |
| 8 | #include <linux/cpumask.h> | 5 | #include <linux/cpumask.h> |
| 6 | #include <linux/list.h> | ||
| 9 | #include <asm/system.h> | 7 | #include <asm/system.h> |
| 10 | 8 | ||
| 11 | #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP) | 9 | #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP) |
| 12 | 10 | ||
| 11 | /* | ||
| 12 | * stop_cpu[s]() is simplistic per-cpu maximum priority cpu | ||
| 13 | * monopolization mechanism. The caller can specify a non-sleeping | ||
| 14 | * function to be executed on a single or multiple cpus preempting all | ||
| 15 | * other processes and monopolizing those cpus until it finishes. | ||
| 16 | * | ||
| 17 | * Resources for this mechanism are preallocated when a cpu is brought | ||
| 18 | * up and requests are guaranteed to be served as long as the target | ||
| 19 | * cpus are online. | ||
| 20 | */ | ||
| 21 | |||
| 22 | typedef int (*cpu_stop_fn_t)(void *arg); | ||
| 23 | |||
| 24 | struct cpu_stop_work { | ||
| 25 | struct list_head list; /* cpu_stopper->works */ | ||
| 26 | cpu_stop_fn_t fn; | ||
| 27 | void *arg; | ||
| 28 | struct cpu_stop_done *done; | ||
| 29 | }; | ||
| 30 | |||
| 31 | int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg); | ||
| 32 | void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, | ||
| 33 | struct cpu_stop_work *work_buf); | ||
| 34 | int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); | ||
| 35 | int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); | ||
| 36 | |||
| 37 | /* | ||
| 38 | * stop_machine "Bogolock": stop the entire machine, disable | ||
| 39 | * interrupts. This is a very heavy lock, which is equivalent to | ||
| 40 | * grabbing every spinlock (and more). So the "read" side to such a | ||
| 41 | * lock is anything which disables preeempt. | ||
| 42 | */ | ||
| 43 | |||
| 13 | /** | 44 | /** |
| 14 | * stop_machine: freeze the machine on all CPUs and run this function | 45 | * stop_machine: freeze the machine on all CPUs and run this function |
| 15 | * @fn: the function to run | 46 | * @fn: the function to run |
