From 099b765139929efdcf232f8870804accf8c4cdc5 Mon Sep 17 00:00:00 2001 From: Frank Munzert Date: Thu, 26 Mar 2009 15:23:43 +0100 Subject: [S390] Automatic IPL after dump Provide new shutdown action "dump_reipl" for automatic ipl after dump. Signed-off-by: Frank Munzert Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/smp.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 2d337cbb932..e279d0fbbbe 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -50,12 +50,6 @@ #include #include "entry.h" -/* - * An array with a pointer the lowcore of every CPU. - */ -struct _lowcore *lowcore_ptr[NR_CPUS]; -EXPORT_SYMBOL(lowcore_ptr); - static struct task_struct *current_set[NR_CPUS]; static u8 smp_cpu_type; @@ -82,9 +76,6 @@ void smp_send_stop(void) /* Disable all interrupts/machine checks */ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK); - /* write magic number to zero page (absolute 0) */ - lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; - /* stop all processors */ for_each_online_cpu(cpu) { if (cpu == smp_processor_id()) -- cgit v1.2.3 From 3324e60aafa9aeb1009878d45079b67367a5e2b6 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 26 Mar 2009 15:23:56 +0100 Subject: [S390] lockdep: trace hardirq off in smp_send_stop With lockdep we got the following trace after a panic: Badness at /home/autobuild/BUILD/linux-2.6.28-20090204/kernel/lockdep.c:2878 [...] Call Trace: [<0000000000176334>] lock_acquire+0x54/0xbc [<000000000050b4fe>] __atomic_notifier_call_chain+0x6e/0xdc [<000000000050b59c>] atomic_notifier_call_chain+0x30/0x44 [<0000000000504274>] panic+0xd0/0x1e8 [...] INFO: lockdep is turned off. Last Breaking-Event-Address: [<0000000000170e62>] check_flags+0xae/0x15c possible reason: unannotated irqs-off. lockdep is right. We missed a trace_hardirq_off in our smp_send_stop function and smp_send_stop is called before the panic call chain. Reported-by: Mijo Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index e279d0fbbbe..a8858634dd0 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ void smp_send_stop(void) /* Disable all interrupts/machine checks */ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK); + trace_hardirqs_off(); /* stop all processors */ for_each_online_cpu(cpu) { -- cgit v1.2.3 From 7b4684880dfc6c45bc56039ca5eada771d7643ab Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 26 Mar 2009 15:24:42 +0100 Subject: [S390] eliminate cpuinfo_S390 structure Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a8858634dd0..b167f74d94c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -372,7 +372,7 @@ static void __init smp_detect_cpus(void) c_cpus = 1; s_cpus = 0; - boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; + boot_cpu_addr = __cpu_logical_map[0]; info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) panic("smp_detect_cpus failed to allocate memory\n"); @@ -446,7 +446,7 @@ int __cpuinit start_secondary(void *cpuvoid) /* Switch on interrupts */ local_irq_enable(); /* Print info about this processor */ - print_cpu_info(&S390_lowcore.cpu_data); + print_cpu_info(); /* cpu_idle will call schedule for us */ cpu_idle(); return 0; @@ -564,7 +564,7 @@ int __cpuinit __cpu_up(unsigned int cpu) : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; cpu_lowcore->current_task = (unsigned long) idle; - cpu_lowcore->cpu_data.cpu_nr = cpu; + cpu_lowcore->cpu_nr = cpu; cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce; cpu_lowcore->ipl_device = S390_lowcore.ipl_device; eieio(); @@ -656,7 +656,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* request the 0x1201 emergency signal external interrupt */ if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) panic("Couldn't request external interrupt 0x1201"); - print_cpu_info(&S390_lowcore.cpu_data); + print_cpu_info(); /* Reallocate current lowcore, but keep its contents. */ lc_order = sizeof(long) == 8 ? 1 : 0; -- cgit v1.2.3 From da292bbe1f620221b08c4b589424f370168d642b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 26 Mar 2009 15:24:43 +0100 Subject: [S390] eliminate ipl_device from lowcore Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b167f74d94c..775885772ff 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -566,7 +566,6 @@ int __cpuinit __cpu_up(unsigned int cpu) cpu_lowcore->current_task = (unsigned long) idle; cpu_lowcore->cpu_nr = cpu; cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce; - cpu_lowcore->ipl_device = S390_lowcore.ipl_device; eieio(); while (signal_processor(cpu, sigp_restart) == sigp_busy) -- cgit v1.2.3 From 59f2e69d0f95bc00353628ef33fd534fbb8e3597 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 26 Mar 2009 15:24:46 +0100 Subject: [S390] zfcpdump: Prevent zcore from beeing built as a kernel module. The zcore code switches to real addressing mode when creating a kernel dump. This is not possible, if it is built as a kernel module. With this patch zcore (zfcpdump) can't be built as a kernel module any more. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 775885772ff..bb3d34aa7b8 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -226,7 +226,7 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); */ #define CPU_INIT_NO 1 -#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) +#ifdef CONFIG_ZFCPDUMP /* * zfcpdump_prefix_array holds prefix registers for the following scenario: @@ -267,7 +267,7 @@ EXPORT_SYMBOL_GPL(zfcpdump_save_areas); static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } -#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ +#endif /* CONFIG_ZFCPDUMP */ static int cpu_stopped(int cpu) { -- cgit v1.2.3 From 6d54c5a3fb13d32d66a8383cb0b5fb422a563051 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 26 Mar 2009 15:24:52 +0100 Subject: [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 Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index bb3d34aa7b8..1f4711b60aa 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -508,7 +508,6 @@ out: return -ENOMEM; } -#ifdef CONFIG_HOTPLUG_CPU static void smp_free_lowcore(int cpu) { struct _lowcore *lowcore; @@ -527,7 +526,6 @@ static void smp_free_lowcore(int cpu) free_pages((unsigned long) lowcore, lc_order); lowcore_ptr[cpu] = NULL; } -#endif /* CONFIG_HOTPLUG_CPU */ /* Upping and downing of CPUs */ int __cpuinit __cpu_up(unsigned int cpu) @@ -544,8 +542,10 @@ int __cpuinit __cpu_up(unsigned int cpu) ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), cpu, sigp_set_prefix); - if (ccode) + if (ccode) { + smp_free_lowcore(cpu); return -EIO; + } idle = current_set[cpu]; cpu_lowcore = lowcore_ptr[cpu]; -- cgit v1.2.3 From d0d3cdf4c27fa4ce241616da08138954e02890f7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 26 Mar 2009 15:24:53 +0100 Subject: [S390] smp: perform initial cpu reset before starting a cpu Performing an initial cpu reset makes sure all registers and tlbs of the targeted cpu are initialized and flushed. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1f4711b60aa..fe5f8dc1e6f 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -534,18 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu) struct _lowcore *cpu_lowcore; struct stack_frame *sf; sigp_ccode ccode; + u32 lowcore; if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) return -EIO; if (smp_alloc_lowcore(cpu)) return -ENOMEM; - - ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), - cpu, sigp_set_prefix); - if (ccode) { - smp_free_lowcore(cpu); - return -EIO; - } + do { + ccode = signal_processor(cpu, sigp_initial_cpu_reset); + if (ccode == sigp_busy) + udelay(10); + if (ccode == sigp_not_operational) + goto err_out; + } while (ccode == sigp_busy); + + lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; + while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) + udelay(10); idle = current_set[cpu]; cpu_lowcore = lowcore_ptr[cpu]; @@ -574,6 +579,10 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_online(cpu)) cpu_relax(); return 0; + +err_out: + smp_free_lowcore(cpu); + return -EIO; } static int __init setup_possible_cpus(char *s) -- cgit v1.2.3 From 93632d1bf7447d445c6fc274c8931152f9412b56 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Mar 2009 15:24:59 +0100 Subject: [S390] cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits. Impact: cleanup, futureproof In fact, all cpumask ops will only be valid (in general) for bit numbers < nr_cpu_ids. So use that instead of NR_CPUS in various places (I also updated the immediate sites to use the new cpumask_ operators). This is always safe: no cpu number can be >= nr_cpu_ids, and nr_cpu_ids is initialized to NR_CPUS at boot. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Acked-by: Ingo Molnar Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index fe5f8dc1e6f..13052a4ed71 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -297,8 +297,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) { int cpu_id, logical_cpu; - logical_cpu = first_cpu(avail); - if (logical_cpu == NR_CPUS) + logical_cpu = cpumask_first(&avail); + if (logical_cpu >= nr_cpu_ids) return 0; for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { if (cpu_known(cpu_id)) @@ -309,8 +309,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) continue; cpu_set(logical_cpu, cpu_present_map); smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED; - logical_cpu = next_cpu(logical_cpu, avail); - if (logical_cpu == NR_CPUS) + logical_cpu = cpumask_next(logical_cpu, &avail); + if (logical_cpu >= nr_cpu_ids) break; } return 0; @@ -322,8 +322,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail) int cpu_id, logical_cpu, cpu; int rc; - logical_cpu = first_cpu(avail); - if (logical_cpu == NR_CPUS) + logical_cpu = cpumask_first(&avail); + if (logical_cpu >= nr_cpu_ids) return 0; info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) @@ -344,8 +344,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail) smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; else smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED; - logical_cpu = next_cpu(logical_cpu, avail); - if (logical_cpu == NR_CPUS) + logical_cpu = cpumask_next(logical_cpu, &avail); + if (logical_cpu >= nr_cpu_ids) break; } out: @@ -591,7 +591,7 @@ static int __init setup_possible_cpus(char *s) pcpus = simple_strtoul(s, NULL, 0); cpu_possible_map = cpumask_of_cpu(0); - for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++) + for (cpu = 1; cpu < pcpus && cpu < nr_cpu_ids; cpu++) cpu_set(cpu, cpu_possible_map); return 0; } -- cgit v1.2.3 From def6cfb70bab83c0094bc0cedd27c4eda563043e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Mar 2009 15:25:00 +0100 Subject: [S390] cpumask: Use accessors code. Impact: use new API Use the accessors rather than frobbing bits directly. Most of this is in arch code I haven't even compiled, but is straightforward. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 13052a4ed71..006ed5016eb 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -590,9 +590,8 @@ static int __init setup_possible_cpus(char *s) int pcpus, cpu; pcpus = simple_strtoul(s, NULL, 0); - cpu_possible_map = cpumask_of_cpu(0); - for (cpu = 1; cpu < pcpus && cpu < nr_cpu_ids; cpu++) - cpu_set(cpu, cpu_possible_map); + for (cpu = 0; cpu < pcpus && cpu < nr_cpu_ids; cpu++) + set_cpu_possible(cpu, true); return 0; } early_param("possible_cpus", setup_possible_cpus); -- cgit v1.2.3