From: Martin Schwidefsky s390 core changes: - Add -msoft-float to CFLAGS. - Remove experimantal tag from cpu hotplug. - Allow more than 4GB swap on a single device for 64 bit. - Fix race in machine_restart to make sure all cpus entered stopped state before reipl. - Cleanup: use for_each_online_cpu macro where possible. - Add argument brackets to __FD_SET/__FD_CLEAR/__FD_ZERO. - Reset cpu_present in smp startup to avoid long delays if only one cpu is defined. - Regenerate default configuration. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton --- 25-akpm/arch/s390/Kconfig | 6 +- 25-akpm/arch/s390/Makefile | 2 25-akpm/arch/s390/defconfig | 11 +++- 25-akpm/arch/s390/kernel/irq.c | 10 +--- 25-akpm/arch/s390/kernel/smp.c | 74 ++++++++++++++++--------------- 25-akpm/drivers/s390/char/sclp_quiesce.c | 25 ++-------- 25-akpm/include/asm-s390/pgtable.h | 8 ++- 25-akpm/include/asm-s390/posix_types.h | 8 +-- 25-akpm/include/asm-s390/smp.h | 25 ++++++++++ 9 files changed, 96 insertions(+), 73 deletions(-) diff -puN arch/s390/defconfig~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug arch/s390/defconfig --- 25/arch/s390/defconfig~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/arch/s390/defconfig 2005-03-02 17:55:17.000000000 -0800 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc2 -# Mon Jan 31 16:27:12 2005 +# Linux kernel version: 2.6.11 +# Wed Mar 2 16:57:55 2005 # CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y @@ -54,6 +54,7 @@ CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y # # Base setup @@ -67,7 +68,7 @@ CONFIG_KMOD=y CONFIG_ARCH_S390_31=y CONFIG_SMP=y CONFIG_NR_CPUS=32 -# CONFIG_HOTPLUG_CPU is not set +CONFIG_HOTPLUG_CPU=y CONFIG_MATHEMU=y # @@ -419,6 +420,10 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set diff -puN arch/s390/Kconfig~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug arch/s390/Kconfig --- 25/arch/s390/Kconfig~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/arch/s390/Kconfig 2005-03-02 17:55:17.000000000 -0800 @@ -84,12 +84,12 @@ config NR_CPUS approximately sixteen kilobytes to the kernel image. config HOTPLUG_CPU - bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" - depends on SMP && EXPERIMENTAL + bool "Support for hot-pluggable CPUs" + depends on SMP select HOTPLUG default n help - Say Y here to experiment with turning CPUs off and on. CPUs + Say Y here to be able to turn CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. diff -puN arch/s390/kernel/irq.c~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug arch/s390/kernel/irq.c --- 25/arch/s390/kernel/irq.c~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/arch/s390/kernel/irq.c 2005-03-02 17:55:17.000000000 -0800 @@ -25,9 +25,8 @@ int show_interrupts(struct seq_file *p, if (i == 0) { seq_puts(p, " "); - for (j=0; jext_call_fast); - while (signal_processor(i, sigp_external_call) == sigp_busy) + set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); + while (signal_processor(cpu, sigp_external_call) == sigp_busy) udelay(10); } } @@ -497,7 +501,6 @@ __init smp_check_cpus(unsigned int max_c */ boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; - __cpu_logical_map[0] = boot_cpu_addr; current_thread_info()->cpu = 0; num_cpus = 1; for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) { @@ -725,7 +728,7 @@ void __cpu_die(unsigned int cpu) { /* Wait until target cpu is down */ - while (!cpu_stopped(cpu)) + while (!smp_cpu_not_running(cpu)) cpu_relax(); printk("Processor %d spun down\n", cpu); } @@ -790,6 +793,7 @@ void __devinit smp_prepare_boot_cpu(void BUG_ON(smp_processor_id() != 0); cpu_set(0, cpu_online_map); + cpu_set(0, cpu_present_map); cpu_set(0, cpu_possible_map); S390_lowcore.percpu_offset = __per_cpu_offset[0]; current_set[0] = current; diff -puN arch/s390/Makefile~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug arch/s390/Makefile --- 25/arch/s390/Makefile~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/arch/s390/Makefile 2005-03-02 17:55:17.000000000 -0800 @@ -66,7 +66,7 @@ cflags-$(CONFIG_WARN_STACK) += -mwarn-dy cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE) endif -CFLAGS += -mbackchain $(cflags-y) +CFLAGS += -mbackchain -msoft-float $(cflags-y) CFLAGS += $(call cc-option,-finline-limit=10000) CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare AFLAGS += $(aflags-y) diff -puN drivers/s390/char/sclp_quiesce.c~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug drivers/s390/char/sclp_quiesce.c --- 25/drivers/s390/char/sclp_quiesce.c~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/drivers/s390/char/sclp_quiesce.c 2005-03-02 17:55:17.000000000 -0800 @@ -30,31 +30,16 @@ do_load_quiesce_psw(void * __unused) { static atomic_t cpuid = ATOMIC_INIT(-1); psw_t quiesce_psw; - __u32 status; - int i; + int cpu; if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) signal_processor(smp_processor_id(), sigp_stop); /* Wait for all other cpus to enter stopped state */ - i = 1; - while (i < NR_CPUS) { - if (!cpu_online(i)) { - i++; + for_each_online_cpu(cpu) { + if (cpu == smp_processor_id()) continue; - } - switch (signal_processor_ps(&status, 0, i, sigp_sense)) { - case sigp_order_code_accepted: - case sigp_status_stored: - /* Check for stopped and check stop state */ - if (status & 0x50) - i++; - break; - case sigp_busy: - break; - case sigp_not_operational: - i++; - break; - } + while(!smp_cpu_not_running(cpu)) + cpu_relax(); } /* Quiesce the last cpu with the special psw */ quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; diff -puN include/asm-s390/pgtable.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug include/asm-s390/pgtable.h --- 25/include/asm-s390/pgtable.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/include/asm-s390/pgtable.h 2005-03-02 17:55:17.000000000 -0800 @@ -756,11 +756,17 @@ extern inline pmd_t * pmd_offset(pgd_t * * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 */ +#ifndef __s390x__ +#define __SWP_OFFSET_MASK (~0UL >> 12) +#else +#define __SWP_OFFSET_MASK (~0UL >> 11) +#endif extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) { pte_t pte; + offset &= __SWP_OFFSET_MASK; pte_val(pte) = _PAGE_INVALID_SWAP | ((type & 0x1f) << 2) | - ((offset & 1) << 7) | ((offset & 0xffffe) << 11); + ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); return pte; } diff -puN include/asm-s390/posix_types.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug include/asm-s390/posix_types.h --- 25/include/asm-s390/posix_types.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/include/asm-s390/posix_types.h 2005-03-02 17:55:17.000000000 -0800 @@ -83,16 +83,16 @@ typedef struct { #endif #undef __FD_SET -#define __FD_SET(fd,fdsetp) set_bit(fd,fdsetp->fds_bits) +#define __FD_SET(fd,fdsetp) set_bit((fd),(fdsetp)->fds_bits) #undef __FD_CLR -#define __FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp->fds_bits) +#define __FD_CLR(fd,fdsetp) clear_bit((fd),(fdsetp)->fds_bits) #undef __FD_ISSET -#define __FD_ISSET(fd,fdsetp) test_bit(fd,fdsetp->fds_bits) +#define __FD_ISSET(fd,fdsetp) test_bit((fd),(fdsetp)->fds_bits) #undef __FD_ZERO -#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) +#define __FD_ZERO(fdsetp) (memset ((fdsetp), 0, sizeof(*(fd_set *)(fdsetp)))) #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)*/ diff -puN include/asm-s390/smp.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug include/asm-s390/smp.h --- 25/include/asm-s390/smp.h~s390-soft-float-4gb-swap-bug-smp-clean-cpu-hotplug 2005-03-02 17:55:17.000000000 -0800 +++ 25-akpm/include/asm-s390/smp.h 2005-03-02 17:55:17.000000000 -0800 @@ -18,6 +18,7 @@ #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__) #include +#include /* s390 specific smp.c headers @@ -59,6 +60,30 @@ extern __inline__ __u16 hard_smp_process return cpu_address; } +/* + * returns 1 if cpu is in stopped/check stopped state or not operational + * returns 0 otherwise + */ +static inline int +smp_cpu_not_running(int cpu) +{ + __u32 status; + + switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { + case sigp_order_code_accepted: + case sigp_status_stored: + /* Check for stopped and check stop state */ + if (status & 0x50) + return 1; + break; + case sigp_not_operational: + return 1; + default: + break; + } + return 0; +} + #define cpu_logical_map(cpu) (cpu) extern int __cpu_disable (void); _