diff options
author | cpw@sgi.com <cpw@sgi.com> | 2011-06-21 07:21:31 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-06-21 14:50:33 +0200 |
commit | 442d3924926c62741912d8a930220af253922007 (patch) | |
tree | 7ea9f7c0e8133037d36e31e7c4f033fae95abcca /arch | |
parent | a456eaab87461e33d94e748565eabd474283a475 (diff) | |
download | op-kernel-dev-442d3924926c62741912d8a930220af253922007.zip op-kernel-dev-442d3924926c62741912d8a930220af253922007.tar.gz |
x86, UV: Remove cpumask_t from the stack
Remove the large stack-resident cpumask_t from
reset_with_ipi()'s stack by allocating one per uvhub.
Due to the limited size of the stack the potentially huge cpumask_t may
cause stack overrun. We haven't seen it happen yet, but we need to make it
a practice not to push such structures onto the stack.
Signed-off-by: Cliff Wickman <cpw@sgi.com>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Link: http://lkml.kernel.org/r/20110621122242.832589130@sgi.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 1 | ||||
-rw-r--r-- | arch/x86/platform/uv/tlb_uv.c | 19 |
2 files changed, 16 insertions, 4 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index fa6a48e..16ce58c 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -488,6 +488,7 @@ struct bau_control { struct bau_control *uvhub_master; struct bau_control *socket_master; struct ptc_stats *statp; + cpumask_t *cpumask; unsigned long timeout_interval; unsigned long set_bau_on_time; atomic_t active_descriptor_count; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 191ef28..5265842 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -375,13 +375,13 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp) int pnode; int apnode; int maskbits; - cpumask_t mask; int sender = bcp->cpu; + cpumask_t *mask = bcp->uvhub_master->cpumask; struct bau_control *smaster = bcp->socket_master; struct reset_args reset_args; reset_args.sender = sender; - cpus_clear(mask); + cpus_clear(*mask); /* find a single cpu for each uvhub in this distribution mask */ maskbits = sizeof(struct pnmask) * BITSPERBYTE; /* each bit is a pnode relative to the partition base pnode */ @@ -391,11 +391,11 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp) continue; apnode = pnode + bcp->partition_base_pnode; cpu = pnode_to_first_cpu(apnode, smaster); - cpu_set(cpu, mask); + cpu_set(cpu, *mask); } /* IPI all cpus; preemption is already disabled */ - smp_call_function_many(&mask, do_reset, (void *)&reset_args, 1); + smp_call_function_many(mask, do_reset, (void *)&reset_args, 1); return; } @@ -1696,6 +1696,16 @@ static void make_per_cpu_thp(struct bau_control *smaster) } /* + * Each uvhub is to get a local cpumask. + */ +static void make_per_hub_cpumask(struct bau_control *hmaster) +{ + int sz = sizeof(cpumask_t); + + hmaster->cpumask = kzalloc_node(sz, GFP_KERNEL, hmaster->osnode); +} + +/* * Initialize all the per_cpu information for the cpu's on a given socket, * given what has been gathered into the socket_desc struct. * And reports the chosen hub and socket masters back to the caller. @@ -1765,6 +1775,7 @@ static int __init summarize_uvhub_sockets(int nuvhubs, socket++; socket_mask = (socket_mask >> 1); } + make_per_hub_cpumask(hmaster); } return 0; } |