diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-03-26 10:24:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:30 -0400 |
commit | 6d54c5a3fb13d32d66a8383cb0b5fb422a563051 (patch) | |
tree | d5d0ca7d73db6201c0b92e74bba789d144d5a97f /arch/s390 | |
parent | 008d2d112cb8a743a87dfe41a67e11c0a4c73aa4 (diff) |
[S390] smp: fix memory leak on __cpu_up
If sigp_set_prefix fails on __cpu_up we leak the lowcore structures
and async+panic stacks for the failed cpu.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/vdso.c | 2 |
2 files changed, 3 insertions, 5 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index bb3d34aa7b85..1f4711b60aab 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -508,7 +508,6 @@ out: | |||
508 | return -ENOMEM; | 508 | return -ENOMEM; |
509 | } | 509 | } |
510 | 510 | ||
511 | #ifdef CONFIG_HOTPLUG_CPU | ||
512 | static void smp_free_lowcore(int cpu) | 511 | static void smp_free_lowcore(int cpu) |
513 | { | 512 | { |
514 | struct _lowcore *lowcore; | 513 | struct _lowcore *lowcore; |
@@ -527,7 +526,6 @@ static void smp_free_lowcore(int cpu) | |||
527 | free_pages((unsigned long) lowcore, lc_order); | 526 | free_pages((unsigned long) lowcore, lc_order); |
528 | lowcore_ptr[cpu] = NULL; | 527 | lowcore_ptr[cpu] = NULL; |
529 | } | 528 | } |
530 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
531 | 529 | ||
532 | /* Upping and downing of CPUs */ | 530 | /* Upping and downing of CPUs */ |
533 | int __cpuinit __cpu_up(unsigned int cpu) | 531 | int __cpuinit __cpu_up(unsigned int cpu) |
@@ -544,8 +542,10 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
544 | 542 | ||
545 | ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), | 543 | ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), |
546 | cpu, sigp_set_prefix); | 544 | cpu, sigp_set_prefix); |
547 | if (ccode) | 545 | if (ccode) { |
546 | smp_free_lowcore(cpu); | ||
548 | return -EIO; | 547 | return -EIO; |
548 | } | ||
549 | 549 | ||
550 | idle = current_set[cpu]; | 550 | idle = current_set[cpu]; |
551 | cpu_lowcore = lowcore_ptr[cpu]; | 551 | cpu_lowcore = lowcore_ptr[cpu]; |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 690e17819686..89b2e7f1b7a9 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -144,7 +144,6 @@ out: | |||
144 | return -ENOMEM; | 144 | return -ENOMEM; |
145 | } | 145 | } |
146 | 146 | ||
147 | #ifdef CONFIG_HOTPLUG_CPU | ||
148 | void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore) | 147 | void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore) |
149 | { | 148 | { |
150 | unsigned long segment_table, page_table, page_frame; | 149 | unsigned long segment_table, page_table, page_frame; |
@@ -163,7 +162,6 @@ void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore) | |||
163 | free_page(page_table); | 162 | free_page(page_table); |
164 | free_pages(segment_table, SEGMENT_ORDER); | 163 | free_pages(segment_table, SEGMENT_ORDER); |
165 | } | 164 | } |
166 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
167 | 165 | ||
168 | static void __vdso_init_cr5(void *dummy) | 166 | static void __vdso_init_cr5(void *dummy) |
169 | { | 167 | { |