diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-21 04:14:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-21 04:14:17 -0500 |
commit | 3eb3963fd1974c63e9bb3cfe774abc3e1995e479 (patch) | |
tree | c00d6c2e8484793ab6bd0644db59bbdf5e9429c5 | |
parent | ae2b56b92bd33b416528986528e0732c98c7a285 (diff) | |
parent | 5766b842b23c6b40935a5f3bd435b2bcdaff2143 (diff) |
Merge branch 'cpus4096' into core/percpu
Conflicts:
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/tlb_32.c
Merge it here because both the cpumask changes and the ongoing percpu
work is touching the TLB code. The percpu changes take precedence, as
they eliminate tlb_32.c altogether.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/ia64/include/asm/topology.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/topology.h | 17 | ||||
-rw-r--r-- | arch/x86/kernel/apic.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 33 | ||||
-rw-r--r-- | kernel/workqueue.c | 20 |
5 files changed, 43 insertions, 34 deletions
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index 32f3af1641c5..3193f4417e16 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h | |||
@@ -84,7 +84,7 @@ void build_cpu_to_node_map(void); | |||
84 | .child = NULL, \ | 84 | .child = NULL, \ |
85 | .groups = NULL, \ | 85 | .groups = NULL, \ |
86 | .min_interval = 8, \ | 86 | .min_interval = 8, \ |
87 | .max_interval = 8*(min(num_online_cpus(), 32)), \ | 87 | .max_interval = 8*(min(num_online_cpus(), 32U)), \ |
88 | .busy_factor = 64, \ | 88 | .busy_factor = 64, \ |
89 | .imbalance_pct = 125, \ | 89 | .imbalance_pct = 125, \ |
90 | .cache_nice_tries = 2, \ | 90 | .cache_nice_tries = 2, \ |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index ffea1fe03a99..10022ed3a4b6 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -190,9 +190,20 @@ extern int __node_distance(int, int); | |||
190 | 190 | ||
191 | #else /* !CONFIG_NUMA */ | 191 | #else /* !CONFIG_NUMA */ |
192 | 192 | ||
193 | #define numa_node_id() 0 | 193 | static inline int numa_node_id(void) |
194 | #define cpu_to_node(cpu) 0 | 194 | { |
195 | #define early_cpu_to_node(cpu) 0 | 195 | return 0; |
196 | } | ||
197 | |||
198 | static inline int cpu_to_node(int cpu) | ||
199 | { | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static inline int early_cpu_to_node(int cpu) | ||
204 | { | ||
205 | return 0; | ||
206 | } | ||
196 | 207 | ||
197 | static inline const cpumask_t *cpumask_of_node(int node) | 208 | static inline const cpumask_t *cpumask_of_node(int node) |
198 | { | 209 | { |
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 9ca12af6c876..1df341a528a1 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c | |||
@@ -1844,6 +1844,11 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1844 | num_processors++; | 1844 | num_processors++; |
1845 | cpu = cpumask_next_zero(-1, cpu_present_mask); | 1845 | cpu = cpumask_next_zero(-1, cpu_present_mask); |
1846 | 1846 | ||
1847 | if (version != apic_version[boot_cpu_physical_apicid]) | ||
1848 | WARN_ONCE(1, | ||
1849 | "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n", | ||
1850 | apic_version[boot_cpu_physical_apicid], cpu, version); | ||
1851 | |||
1847 | physid_set(apicid, phys_cpu_present_map); | 1852 | physid_set(apicid, phys_cpu_present_map); |
1848 | if (apicid == boot_cpu_physical_apicid) { | 1853 | if (apicid == boot_cpu_physical_apicid) { |
1849 | /* | 1854 | /* |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8f3c95c7e61f..4b1c319d30c3 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -145,13 +145,14 @@ typedef union { | |||
145 | 145 | ||
146 | struct drv_cmd { | 146 | struct drv_cmd { |
147 | unsigned int type; | 147 | unsigned int type; |
148 | cpumask_var_t mask; | 148 | const struct cpumask *mask; |
149 | drv_addr_union addr; | 149 | drv_addr_union addr; |
150 | u32 val; | 150 | u32 val; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static void do_drv_read(struct drv_cmd *cmd) | 153 | static long do_drv_read(void *_cmd) |
154 | { | 154 | { |
155 | struct drv_cmd *cmd = _cmd; | ||
155 | u32 h; | 156 | u32 h; |
156 | 157 | ||
157 | switch (cmd->type) { | 158 | switch (cmd->type) { |
@@ -166,10 +167,12 @@ static void do_drv_read(struct drv_cmd *cmd) | |||
166 | default: | 167 | default: |
167 | break; | 168 | break; |
168 | } | 169 | } |
170 | return 0; | ||
169 | } | 171 | } |
170 | 172 | ||
171 | static void do_drv_write(struct drv_cmd *cmd) | 173 | static long do_drv_write(void *_cmd) |
172 | { | 174 | { |
175 | struct drv_cmd *cmd = _cmd; | ||
173 | u32 lo, hi; | 176 | u32 lo, hi; |
174 | 177 | ||
175 | switch (cmd->type) { | 178 | switch (cmd->type) { |
@@ -186,30 +189,23 @@ static void do_drv_write(struct drv_cmd *cmd) | |||
186 | default: | 189 | default: |
187 | break; | 190 | break; |
188 | } | 191 | } |
192 | return 0; | ||
189 | } | 193 | } |
190 | 194 | ||
191 | static void drv_read(struct drv_cmd *cmd) | 195 | static void drv_read(struct drv_cmd *cmd) |
192 | { | 196 | { |
193 | cpumask_t saved_mask = current->cpus_allowed; | ||
194 | cmd->val = 0; | 197 | cmd->val = 0; |
195 | 198 | ||
196 | set_cpus_allowed_ptr(current, cmd->mask); | 199 | work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); |
197 | do_drv_read(cmd); | ||
198 | set_cpus_allowed_ptr(current, &saved_mask); | ||
199 | } | 200 | } |
200 | 201 | ||
201 | static void drv_write(struct drv_cmd *cmd) | 202 | static void drv_write(struct drv_cmd *cmd) |
202 | { | 203 | { |
203 | cpumask_t saved_mask = current->cpus_allowed; | ||
204 | unsigned int i; | 204 | unsigned int i; |
205 | 205 | ||
206 | for_each_cpu(i, cmd->mask) { | 206 | for_each_cpu(i, cmd->mask) { |
207 | set_cpus_allowed_ptr(current, cpumask_of(i)); | 207 | work_on_cpu(i, do_drv_write, cmd); |
208 | do_drv_write(cmd); | ||
209 | } | 208 | } |
210 | |||
211 | set_cpus_allowed_ptr(current, &saved_mask); | ||
212 | return; | ||
213 | } | 209 | } |
214 | 210 | ||
215 | static u32 get_cur_val(const struct cpumask *mask) | 211 | static u32 get_cur_val(const struct cpumask *mask) |
@@ -235,6 +231,7 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
235 | return 0; | 231 | return 0; |
236 | } | 232 | } |
237 | 233 | ||
234 | cmd.mask = mask; | ||
238 | drv_read(&cmd); | 235 | drv_read(&cmd); |
239 | 236 | ||
240 | dprintk("get_cur_val = %u\n", cmd.val); | 237 | dprintk("get_cur_val = %u\n", cmd.val); |
@@ -366,7 +363,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | |||
366 | return freq; | 363 | return freq; |
367 | } | 364 | } |
368 | 365 | ||
369 | static unsigned int check_freqs(const cpumask_t *mask, unsigned int freq, | 366 | static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, |
370 | struct acpi_cpufreq_data *data) | 367 | struct acpi_cpufreq_data *data) |
371 | { | 368 | { |
372 | unsigned int cur_freq; | 369 | unsigned int cur_freq; |
@@ -401,9 +398,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
401 | return -ENODEV; | 398 | return -ENODEV; |
402 | } | 399 | } |
403 | 400 | ||
404 | if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL))) | ||
405 | return -ENOMEM; | ||
406 | |||
407 | perf = data->acpi_data; | 401 | perf = data->acpi_data; |
408 | result = cpufreq_frequency_table_target(policy, | 402 | result = cpufreq_frequency_table_target(policy, |
409 | data->freq_table, | 403 | data->freq_table, |
@@ -448,9 +442,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
448 | 442 | ||
449 | /* cpufreq holds the hotplug lock, so we are safe from here on */ | 443 | /* cpufreq holds the hotplug lock, so we are safe from here on */ |
450 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) | 444 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) |
451 | cpumask_and(cmd.mask, cpu_online_mask, policy->cpus); | 445 | cmd.mask = policy->cpus; |
452 | else | 446 | else |
453 | cpumask_copy(cmd.mask, cpumask_of(policy->cpu)); | 447 | cmd.mask = cpumask_of(policy->cpu); |
454 | 448 | ||
455 | freqs.old = perf->states[perf->state].core_frequency * 1000; | 449 | freqs.old = perf->states[perf->state].core_frequency * 1000; |
456 | freqs.new = data->freq_table[next_state].frequency; | 450 | freqs.new = data->freq_table[next_state].frequency; |
@@ -477,7 +471,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
477 | perf->state = next_perf_state; | 471 | perf->state = next_perf_state; |
478 | 472 | ||
479 | out: | 473 | out: |
480 | free_cpumask_var(cmd.mask); | ||
481 | return result; | 474 | return result; |
482 | } | 475 | } |
483 | 476 | ||
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2f445833ae37..1f0c509b40d3 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -971,6 +971,8 @@ undo: | |||
971 | } | 971 | } |
972 | 972 | ||
973 | #ifdef CONFIG_SMP | 973 | #ifdef CONFIG_SMP |
974 | static struct workqueue_struct *work_on_cpu_wq __read_mostly; | ||
975 | |||
974 | struct work_for_cpu { | 976 | struct work_for_cpu { |
975 | struct work_struct work; | 977 | struct work_struct work; |
976 | long (*fn)(void *); | 978 | long (*fn)(void *); |
@@ -991,8 +993,8 @@ static void do_work_for_cpu(struct work_struct *w) | |||
991 | * @fn: the function to run | 993 | * @fn: the function to run |
992 | * @arg: the function arg | 994 | * @arg: the function arg |
993 | * | 995 | * |
994 | * This will return -EINVAL in the cpu is not online, or the return value | 996 | * This will return the value @fn returns. |
995 | * of @fn otherwise. | 997 | * It is up to the caller to ensure that the cpu doesn't go offline. |
996 | */ | 998 | */ |
997 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) | 999 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) |
998 | { | 1000 | { |
@@ -1001,14 +1003,8 @@ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) | |||
1001 | INIT_WORK(&wfc.work, do_work_for_cpu); | 1003 | INIT_WORK(&wfc.work, do_work_for_cpu); |
1002 | wfc.fn = fn; | 1004 | wfc.fn = fn; |
1003 | wfc.arg = arg; | 1005 | wfc.arg = arg; |
1004 | get_online_cpus(); | 1006 | queue_work_on(cpu, work_on_cpu_wq, &wfc.work); |
1005 | if (unlikely(!cpu_online(cpu))) | 1007 | flush_work(&wfc.work); |
1006 | wfc.ret = -EINVAL; | ||
1007 | else { | ||
1008 | schedule_work_on(cpu, &wfc.work); | ||
1009 | flush_work(&wfc.work); | ||
1010 | } | ||
1011 | put_online_cpus(); | ||
1012 | 1008 | ||
1013 | return wfc.ret; | 1009 | return wfc.ret; |
1014 | } | 1010 | } |
@@ -1025,4 +1021,8 @@ void __init init_workqueues(void) | |||
1025 | hotcpu_notifier(workqueue_cpu_callback, 0); | 1021 | hotcpu_notifier(workqueue_cpu_callback, 0); |
1026 | keventd_wq = create_workqueue("events"); | 1022 | keventd_wq = create_workqueue("events"); |
1027 | BUG_ON(!keventd_wq); | 1023 | BUG_ON(!keventd_wq); |
1024 | #ifdef CONFIG_SMP | ||
1025 | work_on_cpu_wq = create_workqueue("work_on_cpu"); | ||
1026 | BUG_ON(!work_on_cpu_wq); | ||
1027 | #endif | ||
1028 | } | 1028 | } |