* Cleanup cpumask_t usages in smp_call_function_mask to remove stack overflow problem when NR_CPUS=4096. This removes over 1000 bytes from the stack with NR_CPUS=4096. Based on 2.6.27-rc5-git6. Applies to linux-2.6.tip/master (with FUZZ). Signed-off-by: Mike Travis --- kernel/smp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) --- linux-2.6.orig/kernel/smp.c +++ linux-2.6/kernel/smp.c @@ -303,7 +303,7 @@ static int check_stack_overflow(void) * If a faster scheme can be made, we could go back to preferring stack based * data -- the data allocation/free is non-zero cost. */ -static void smp_call_function_mask_quiesce_stack(cpumask_t mask) +static void smp_call_function_mask_quiesce_stack(const cpumask_t *mask) { struct call_single_data data; int cpu; @@ -311,7 +311,7 @@ static void smp_call_function_mask_quies data.func = quiesce_dummy; data.info = NULL; - for_each_cpu_mask(cpu, mask) { + for_each_cpu_mask_nr(cpu, *mask) { data.flags = CSD_FLAG_WAIT; generic_exec_single(cpu, &data); } @@ -339,7 +339,6 @@ int smp_call_function_mask(cpumask_t mas { struct call_function_data d; struct call_function_data *data = NULL; - cpumask_t allbutself; unsigned long flags; int cpu, num_cpus; int slowpath = 0; @@ -353,9 +352,8 @@ dump_stack(); WARN_ON(irqs_disabled()); cpu = smp_processor_id(); - allbutself = cpu_online_map; - cpu_clear(cpu, allbutself); - cpus_and(mask, mask, allbutself); + cpus_and(mask, mask, cpu_online_map); + cpu_clear(cpu, mask); num_cpus = cpus_weight(mask); /* @@ -398,7 +396,7 @@ dump_stack(); if (wait) { csd_flag_wait(&data->csd); if (unlikely(slowpath)) - smp_call_function_mask_quiesce_stack(mask); + smp_call_function_mask_quiesce_stack(&mask); } return 0;