From 3f6813b9a5e0aaec162a10037c203771a1b2c110 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 1 Apr 2016 15:42:15 +0200 Subject: s390/fpu: allocate 'struct fpu' with the task_struct Analog to git commit 0c8c0f03e3a292e031596484275c14cf39c0ab7a "x86/fpu, sched: Dynamically allocate 'struct fpu'" move the struct fpu to the end of the struct thread_struct, set CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT and add the setup_task_size() function to calculate the correct size fo the task struct. For the performance_defconfig this increases the size of struct task_struct from 7424 bytes to 7936 bytes (MACHINE_HAS_VX==1) or 7552 bytes (MACHINE_HAS_VX==0). The dynamic allocation of the struct fpu is removed. The slab cache uses an 8KB block for the task struct in all cases, there is enough room for the struct fpu. For MACHINE_HAS_VX==1 each task now needs 512 bytes less memory. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/process.c | 23 ++--------------------- arch/s390/kernel/setup.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2bba7df..adb346b 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -37,9 +37,6 @@ asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); -/* FPU save area for the init task */ -__vector128 init_task_fpu_regs[__NUM_VXRS] __init_task_data; - /* * Return saved PC of a blocked thread. used in kernel/sched. * resume in entry.S does not create a new stack frame, it @@ -85,35 +82,19 @@ void release_thread(struct task_struct *dead_task) void arch_release_task_struct(struct task_struct *tsk) { - /* Free either the floating-point or the vector register save area */ - kfree(tsk->thread.fpu.regs); } int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { - size_t fpu_regs_size; - - *dst = *src; - - /* - * If the vector extension is available, it is enabled for all tasks, - * and, thus, the FPU register save area must be allocated accordingly. - */ - fpu_regs_size = MACHINE_HAS_VX ? sizeof(__vector128) * __NUM_VXRS - : sizeof(freg_t) * __NUM_FPRS; - dst->thread.fpu.regs = kzalloc(fpu_regs_size, GFP_KERNEL|__GFP_REPEAT); - if (!dst->thread.fpu.regs) - return -ENOMEM; - /* * Save the floating-point or vector register state of the current * task and set the CIF_FPU flag to lazy restore the FPU register * state when returning to user space. */ save_fpu_regs(); - dst->thread.fpu.fpc = current->thread.fpu.fpc; - memcpy(dst->thread.fpu.regs, current->thread.fpu.regs, fpu_regs_size); + memcpy(dst, src, arch_task_struct_size); + dst->thread.fpu.regs = dst->thread.fpu.fprs; return 0; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d3f9688..f319391 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -809,6 +809,22 @@ static void __init setup_randomness(void) } /* + * Find the correct size for the task_struct. This depends on + * the size of the struct fpu at the end of the thread_struct + * which is embedded in the task_struct. + */ +static void __init setup_task_size(void) +{ + int task_size = sizeof(struct task_struct); + + if (!MACHINE_HAS_VX) { + task_size -= sizeof(__vector128) * __NUM_VXRS; + task_size += sizeof(freg_t) * __NUM_FPRS; + } + arch_task_struct_size = task_size; +} + +/* * Setup function called from init/main.c just after the banner * was printed. */ @@ -846,6 +862,7 @@ void __init setup_arch(char **cmdline_p) os_info_init(); setup_ipl(); + setup_task_size(); /* Do some memory reservations *before* memory is added to memblock */ reserve_memory_end(); -- cgit v1.1 From 5bc73539013e93fc44e4d8b1d3557d0ec78df704 Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Mon, 2 May 2016 10:59:32 +0200 Subject: s390/cpum_cf: Remove superfluous SMP function call Since commit 3b9d6da67e11 ("cpu/hotplug: Fix rollback during error-out in __cpu_disable()") it is ensured that callbacks of CPU_ONLINE and CPU_DOWN_PREPARE are processed on the hotplugged CPU. Due to this SMP function calls are no longer required. Replace smp_call_function_single() with a direct call of setup_pmc_cpu(). To keep the calling convention, interrupts are explicitly disabled around the call. Cc: linux-s390@vger.kernel.org Signed-off-by: Anna-Maria Gleixner Acked-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_cpum_cf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 62f066b..59215c5 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -665,18 +665,21 @@ static struct pmu cpumf_pmu = { static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { - unsigned int cpu = (long) hcpu; int flags; switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: case CPU_DOWN_FAILED: flags = PMC_INIT; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; case CPU_DOWN_PREPARE: flags = PMC_RELEASE; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; default: break; -- cgit v1.1 From e18eb2d1eb03fa06ccb7823a44d7ceea621e2bbb Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Mon, 2 May 2016 11:00:12 +0200 Subject: s390/cpum_sf: Remove superfluous SMP function call Since commit 3b9d6da67e11 ("cpu/hotplug: Fix rollback during error-out in __cpu_disable()") it is ensured that callbacks of CPU_ONLINE and CPU_DOWN_PREPARE are processed on the hotplugged CPU. Due to this SMP function calls are no longer required. Replace smp_call_function_single() with a direct call of setup_pmc_cpu(). To keep the calling convention, interrupts are explicitly disabled around the call. Cc: linux-s390@vger.kernel.org Signed-off-by: Anna-Maria Gleixner Acked-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_cpum_sf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index eaab9a7..a8e8321 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1510,7 +1510,6 @@ static void cpumf_measurement_alert(struct ext_code ext_code, static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { - unsigned int cpu = (long) hcpu; int flags; /* Ignore the notification if no events are scheduled on the PMU. @@ -1523,11 +1522,15 @@ static int cpumf_pmu_notifier(struct notifier_block *self, case CPU_ONLINE: case CPU_DOWN_FAILED: flags = PMC_INIT; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; case CPU_DOWN_PREPARE: flags = PMC_RELEASE; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; default: break; -- cgit v1.1 From 5606330627ab680f5e6b7549d14ec3ffdae58c15 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 2 May 2016 14:38:29 +0200 Subject: s390/dumpstack: implement and use return_address() Implement return_address() and use it instead of __builtin_return_address(n). __builtin_return_address(n) is not guaranteed to work for n > 0, therefore implement a private return_address() function which walks the stack frames and returns the proper return address. This way we get also rid of a compile warning which gcc 6.1 emits and look like all other architectures. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/dumpstack.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 1b6081c..69f9908 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -89,6 +89,30 @@ void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task, } EXPORT_SYMBOL_GPL(dump_trace); +struct return_address_data { + unsigned long address; + int depth; +}; + +static int __return_address(void *data, unsigned long address) +{ + struct return_address_data *rd = data; + + if (rd->depth--) + return 0; + rd->address = address; + return 1; +} + +unsigned long return_address(int depth) +{ + struct return_address_data rd = { .depth = depth + 2 }; + + dump_trace(__return_address, &rd, NULL, current_stack_pointer()); + return rd.address; +} +EXPORT_SYMBOL_GPL(return_address); + static int show_address(void *data, unsigned long address) { printk("([<%016lx>] %pSR)\n", address, (void *)address); -- cgit v1.1 From 281eaa8cb67c27e56da1e7fd6b55c6cd3e8c4638 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 13 Apr 2016 14:49:12 +0200 Subject: s390/cpuinfo: simplify locking and skip offline cpus early Move the get_online_cpus() and put_online_cpus() to the start and stop operation of the seqfile ops. This way there is no need to lock cpu hotplug again and again for each single cpu. This way we can also skip offline cpus early if we simply use cpumask_next() within the next operation. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/processor.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 647128d..90a418d 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -84,7 +84,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_puts(m, "\n"); show_cacheinfo(m); } - get_online_cpus(); if (cpu_online(n)) { struct cpuid *id = &per_cpu(cpu_id, n); seq_printf(m, "processor %li: " @@ -93,23 +92,31 @@ static int show_cpuinfo(struct seq_file *m, void *v) "machine = %04X\n", n, id->version, id->ident, id->machine); } - put_online_cpus(); return 0; } +static inline void *c_update(loff_t *pos) +{ + if (*pos) + *pos = cpumask_next(*pos - 1, cpu_online_mask); + return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; +} + static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; + get_online_cpus(); + return c_update(pos); } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { ++*pos; - return c_start(m, pos); + return c_update(pos); } static void c_stop(struct seq_file *m, void *v) { + put_online_cpus(); } const struct seq_operations cpuinfo_op = { -- cgit v1.1 From 4c07a399f98278f2a784cdf71053c85a4082f4db Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 May 2016 10:57:33 +0200 Subject: s390/cache: remove superfluous locking With "s390/cpuinfo: simplify locking and skip offline cpus early" we prevent already that cpus will go away. The additional get_online_cpus() / put_online_cpus() within show_cacheinfo() is not needed anymore. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/cache.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c index 8ba3243..77a84bd 100644 --- a/arch/s390/kernel/cache.c +++ b/arch/s390/kernel/cache.c @@ -72,7 +72,6 @@ void show_cacheinfo(struct seq_file *m) if (!test_facility(34)) return; - get_online_cpus(); this_cpu_ci = get_cpu_cacheinfo(cpumask_any(cpu_online_mask)); for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { cache = this_cpu_ci->info_list + idx; @@ -86,7 +85,6 @@ void show_cacheinfo(struct seq_file *m) seq_printf(m, "associativity=%d", cache->ways_of_associativity); seq_puts(m, "\n"); } - put_online_cpus(); } static inline enum cache_type get_cache_type(struct cache_info *ci, int level) -- cgit v1.1 From f70a34c57602f5791a63869db95f3b97276cd1d2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 7 May 2016 12:14:29 +0200 Subject: s390: make couple of variables and functions static copy_oldmem_user() and ap_jumptable are private to the files they are being used in. Therefore make them static. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/crash_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 3986c9f..29df8484 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -173,7 +173,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count) /* * Copy memory of the old, dumped system to a user space virtual address */ -int copy_oldmem_user(void __user *dst, void *src, size_t count) +static int copy_oldmem_user(void __user *dst, void *src, size_t count) { unsigned long from, len; int rc; -- cgit v1.1 From 521b00cd7a6491fbec7d1ede5b6b33f106a6addc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 7 May 2016 12:15:21 +0200 Subject: s390: add missing declarations arch_dup_task_struct and the per cpu variable mt_cycles are globally visible, but do not have any header file with a declaration. Therefore add it so we have proper type checking in place. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry.h | 4 ++++ arch/s390/kernel/vtime.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index b7019ab..bedd2f5 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -1,6 +1,7 @@ #ifndef _ENTRY_H #define _ENTRY_H +#include #include #include #include @@ -75,4 +76,7 @@ long sys_s390_personality(unsigned int personality); long sys_s390_runtime_instr(int command, int signum); long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); + +DECLARE_PER_CPU(u64, mt_cycles[8]); + #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index dafc44f..856e30d 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -18,6 +18,8 @@ #include #include +#include "entry.h" + static void virt_timer_expire(void); static LIST_HEAD(virt_timer_list); -- cgit v1.1 From ca21872e43e82c2a5c2e056ee4aea40a921720b1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 7 May 2016 12:15:34 +0200 Subject: s390: add missing include statements arch_mmap_rnd, cpu_have_feature, and arch_randomize_brk are all defined as globally visible variables. However the files they are defined in do not include the header files with the declaration. To avoid a possible mismatch add the missing include statements so we have proper type checking in place. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/process.c | 1 + arch/s390/kernel/processor.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index adb346b..481d7a83 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -7,6 +7,7 @@ * Denis Joseph Barrow, */ +#include #include #include #include diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 90a418d..de74510 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -6,6 +6,7 @@ #define KMSG_COMPONENT "cpu" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include #include #include #include -- cgit v1.1