diff options
author | Andreas Herrmann <andreas.herrmann3@amd.com> | 2008-08-06 04:29:37 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-06 14:48:16 -0400 |
commit | 23952a96ae738277f3139b63d622e22984589031 (patch) | |
tree | 00e3401cc15bf4220b071a6391228e21e086e68f /arch/x86 | |
parent | d04ec773d7ca1bbc05a2768be95c1cebe2b07757 (diff) |
x86: cpu_init(): fix memory leak when using CPU hotplug
Exception stacks are allocated each time a CPU is set online.
But the allocated space is never freed. Thus with one CPU hotplug
offline/online cycle there is a memory leak of 24K (6 pages) for
a CPU.
Fix is to allocate exception stacks only once -- when the CPU is
set online for the first time.
Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Cc: akpm@linux-foundation.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/common_64.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index 4f2eeb5652ea..a11f5d4477cd 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c | |||
@@ -640,19 +640,22 @@ void __cpuinit cpu_init(void) | |||
640 | /* | 640 | /* |
641 | * set up and load the per-CPU TSS | 641 | * set up and load the per-CPU TSS |
642 | */ | 642 | */ |
643 | for (v = 0; v < N_EXCEPTION_STACKS; v++) { | 643 | if (!orig_ist->ist[0]) { |
644 | static const unsigned int order[N_EXCEPTION_STACKS] = { | 644 | static const unsigned int order[N_EXCEPTION_STACKS] = { |
645 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, | 645 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, |
646 | [DEBUG_STACK - 1] = DEBUG_STACK_ORDER | 646 | [DEBUG_STACK - 1] = DEBUG_STACK_ORDER |
647 | }; | 647 | }; |
648 | if (cpu) { | 648 | for (v = 0; v < N_EXCEPTION_STACKS; v++) { |
649 | estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); | 649 | if (cpu) { |
650 | if (!estacks) | 650 | estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); |
651 | panic("Cannot allocate exception stack %ld %d\n", | 651 | if (!estacks) |
652 | v, cpu); | 652 | panic("Cannot allocate exception " |
653 | "stack %ld %d\n", v, cpu); | ||
654 | } | ||
655 | estacks += PAGE_SIZE << order[v]; | ||
656 | orig_ist->ist[v] = t->x86_tss.ist[v] = | ||
657 | (unsigned long)estacks; | ||
653 | } | 658 | } |
654 | estacks += PAGE_SIZE << order[v]; | ||
655 | orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; | ||
656 | } | 659 | } |
657 | 660 | ||
658 | t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); | 661 | t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); |