aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-05-14 05:44:45 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-14 05:44:45 -0700
commitfda94eff9b081a5e498d7d9aabf7d418f5249b0d (patch)
tree3bc75d533ccb2273eb47a1b5ade4a317ba0cf271 /kernel
parent4af52c2390574f7cb34cbf04a159238ee2c873fe (diff)
downloadhistory-fda94eff9b081a5e498d7d9aabf7d418f5249b0d.tar.gz
[PATCH] Revisited: ia64-cpu-hotplug-cpu_present.patch
From: Paul Jackson <pj@sgi.com> With a hotplug capable kernel, there is a requirement to distinguish a possible CPU from one actually present. The set of possible CPU numbers doesn't change during a single system boot, but the set of present CPUs changes as CPUs are physically inserted into or removed from a system. The cpu_possible_map does not change once initialized at boot, but the cpu_present_map changes dynamically as CPUs are inserted or removed. Paul Jackson <pj@sgi.com> provided an expanded explanation: Ashok's cpu hot plug patch adds a cpu_present_map, resulting in the following cpu maps being available. All the following maps are fixed size bitmaps of size NR_CPUS. #ifdef CONFIG_HOTPLUG_CPU cpu_possible_map - map with all NR_CPUS bits set cpu_present_map - map with bit 'cpu' set iff cpu is populated cpu_online_map - map with bit 'cpu' set iff cpu available to scheduler #else cpu_possible_map - map with bit 'cpu' set iff cpu is populated cpu_present_map - copy of cpu_possible_map cpu_online_map - map with bit 'cpu' set iff cpu available to scheduler #endif In either case, NR_CPUS is fixed at compile time, as the static size of these bitmaps. The cpu_possible_map is fixed at boot time, as the set of CPU id's that it is possible might ever be plugged in at anytime during the life of that system boot. The cpu_present_map is dynamic(*), representing which CPUs are currently plugged in. And cpu_online_map is the dynamic subset of cpu_present_map, indicating those CPUs available for scheduling. If HOTPLUG is enabled, then cpu_possible_map is forced to have all NR_CPUS bits set, otherwise it is just the set of CPUs that ACPI reports present at boot. If HOTPLUG is enabled, then cpu_present_map varies dynamically, depending on what ACPI reports as currently plugged in, otherwise cpu_present_map is just a copy of cpu_possible_map. (*) Well, cpu_present_map is dynamic in the hotplug case. If not hotplug, it's the same as cpu_possible_map, hence fixed at boot.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu.c10
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sched.c6
-rw-r--r--kernel/timer.c2
4 files changed, 14 insertions, 6 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index a2e44b4e7df132..72b984c67eb32d 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -20,6 +20,14 @@
DECLARE_MUTEX(cpucontrol);
static struct notifier_block *cpu_chain;
+/*
+ * Represents all cpu's present in the system
+ * In systems capable of hotplug, this map could dynamically grow
+ * as new cpu's are detected in the system via any platform specific
+ * method, such as ACPI for e.g.
+ */
+cpumask_t cpu_present_map;
+EXPORT_SYMBOL(cpu_present_map);
/* Need to know about CPUs going up/down? */
int register_cpu_notifier(struct notifier_block *nb)
@@ -180,7 +188,7 @@ int __devinit cpu_up(unsigned int cpu)
if ((ret = down_interruptible(&cpucontrol)) != 0)
return ret;
- if (cpu_online(cpu)) {
+ if (cpu_online(cpu) || !cpu_present(cpu)) {
ret = -EINVAL;
goto out;
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 0c0f1ffc8932c9..a42ffd46532fd0 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,7 +61,7 @@ int nr_processes(void)
int cpu;
int total = 0;
- for_each_cpu(cpu)
+ for_each_online_cpu(cpu)
total += per_cpu(process_counts, cpu);
return total;
diff --git a/kernel/sched.c b/kernel/sched.c
index af614e52e1b936..fa73c9675abc41 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1079,7 +1079,7 @@ unsigned long nr_uninterruptible(void)
{
unsigned long i, sum = 0;
- for_each_cpu(i)
+ for_each_online_cpu(i)
sum += cpu_rq(i)->nr_uninterruptible;
return sum;
@@ -1089,7 +1089,7 @@ unsigned long long nr_context_switches(void)
{
unsigned long long i, sum = 0;
- for_each_cpu(i)
+ for_each_online_cpu(i)
sum += cpu_rq(i)->nr_switches;
return sum;
@@ -1099,7 +1099,7 @@ unsigned long nr_iowait(void)
{
unsigned long i, sum = 0;
- for_each_cpu(i)
+ for_each_online_cpu(i)
sum += atomic_read(&cpu_rq(i)->nr_iowait);
return sum;
diff --git a/kernel/timer.c b/kernel/timer.c
index 08cec6ae76e375..5bc2d78ba903a9 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -332,7 +332,7 @@ int del_timer_sync(struct timer_list *timer)
del_again:
ret += del_timer(timer);
- for_each_cpu(i) {
+ for_each_online_cpu(i) {
base = &per_cpu(tvec_bases, i);
if (base->running_timer == timer) {
while (base->running_timer == timer) {