2nd batch of s390 patches for 2.6.26
cover 2nd batch of s390 patches for 2.6.26
The usual fixes and one new feature. After Andrew has forwarded Gerald's hugetlbfs cleanup patches we can now add support for large pages. The second interesting patch (well at least for us :-) is Heiko's vmemmap sparsemem patch.
The shortlog:
Cornelia Huck (2):
[S390] cio: Use strict_strtoul() for attributes. [S390] cio: Make isc handling more robust.
Gerald Schaefer (1):
[S390] System z large page support.
Heiko Carstens (11):
[S390] Move show_regs to traps.c.
[S390] Add missing ifndef/define to include/asm-s390/sysinfo.h. [S390] smp: Fix locking order.
[S390] Automatically detect added cpus.
[S390] Add topology_core_siblings to topology.h [S390] cpu topology: Fix possible deadlock.
[S390] uaccess_mvcos: #ifdef config dependent code. [S390] Move stfl to system.h and delete duplicated version. [S390] vmemmap: use clear_table to initialise page tables. [S390] Convert machine feature detection code to C. [S390] Convert to SPARSEMEM & SPARSEMEM_VMEMMAP
Mathieu Desnoyers (1):
[S390] remove -traditional
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/15 cio: Use strict_strtoul() for attributes.
From: Cornelia Huck <[email protected]>
Make parsing of attribute writes handle incorrect input better.
---
drivers/s390/cio/ccwgroup.c | 7 +++++-- drivers/s390/cio/cmf.c | 11 ++++++++--- drivers/s390/cio/css.c | 10 +++++++--- drivers/s390/cio/device.c | 17 +++++++++++------ drivers/s390/cio/qdio.c | 8 ++++---- 5 files changed, 35 insertions(+), 18 deletions(-)
drivers/s390/cio/ccwgroup.c +5 -2
@@ -318,7 +318,7 @@ ccwgroup_online_store (struct device *de {struct ccwgroup_device *gdev;struct ccwgroup_driver *gdrv; -unsigned int value; +unsigned long value;int ret; gdev =to_ccwgroupdev (dev);
@@ -329,7 +329,9 @@ ccwgroup_online_store (struct device *deif (!try_module_get (gdrv->owner))return -EINVAL ; - value =simple_strtoul (buf,NULL ,0 ); + ret =strict_strtoul (buf,0 , &value); +if (ret) + goto out; ret = count;if (value ==1 )ccwgroup_set_online (gdev);
@@ -337,6 +339,7 @@ ccwgroup_online_store (struct device *deccwgroup_set_offline (gdev); else ret = -EINVAL ; +out:module_put (gdrv->owner);return ret; }
drivers/s390/cio/cmf.c +8 -3
@@ -1219,16 +1219,21 @@ static ssize_t cmb_enable_store(struct d {struct ccw_device *cdev;int ret; +unsigned long val; + + ret =strict_strtoul (buf,16 , &val); +if (ret) +return ret; cdev =to_ccwdev (dev); -switch (buf[0 ]) { -case '0' : +switch (val) { +case 0 : ret =disable_cmf (cdev);if (ret)dev_info (&cdev->dev,"disable_cmf failed (%d)\n" , ret);break ; -case '1' : +case 1 : ret =enable_cmf (cdev);if (ret && ret != -EBUSY )dev_info (&cdev->dev,"enable_cmf failed (%d)\n" , ret);
drivers/s390/cio/css.c +7 -3
@@ -705,13 +705,17 @@ css_cm_enable_store(struct device *dev, {struct channel_subsystem *css =to_css (dev);int ret; +unsigned long val; + ret =strict_strtoul (buf,16 , &val); +if (ret) +return ret;mutex_lock (&css->mutex); -switch (buf[0 ]) { -case '0' : +switch (val) { +case 0 : ret = css->cm_enabled ?chsc_secm (css,0 ) :0 ;break ; -case '1' : +case 1 : ret = css->cm_enabled ?0 :chsc_secm (css,1 );break ;default :
drivers/s390/cio/device.c +11 -6
@@ -512,8 +512,8 @@ static ssize_t online_store (struct devi const char *buf, size_t count) {struct ccw_device *cdev =to_ccwdev (dev); -int i, force; -char *tmp; +int force, ret; +unsigned long i;if (atomic_cmpxchg (&cdev->private->onoff,0 ,1 ) !=0 )return -EAGAIN ;
@@ -525,25 +525,30 @@ static ssize_t online_store (struct deviif (!strncmp (buf,"force\n" , count)) { force =1 ; i =1 ; + ret =0 ; }else { force =0 ; - i =simple_strtoul (buf, &tmp,16 ); + ret =strict_strtoul (buf,16 , &i); } - +if (ret) + goto out;switch (i) {case 0 :online_store_handle_offline (cdev); + ret = count;break ;case 1 :online_store_handle_online (cdev, force); + ret = count;break ;default : - count = -EINVAL ; + ret = -EINVAL ; } +out:if (cdev->drv)module_put (cdev->drv->owner);atomic_set (&cdev->private->onoff,0 ); -return count; +return ret; } static ssize_t
drivers/s390/cio/qdio.c +4 -4
@@ -3663,11 +3663,11 @@ qdio_performance_stats_show(struct bus_tstatic ssize_t qdio_performance_stats_store (struct bus_type *bus,const char *buf,size_t count) { -char *tmp; -int i; +unsigned long i; +int ret; - i =simple_strtoul (buf, &tmp,16 ); -if ((i ==0 ) || (i ==1 )) { + ret =strict_strtoul (buf,16 , &i); +if (!ret && ((i ==0 ) || (i ==1 ))) {if (i == qdio_performance_stats)return count; qdio_performance_stats = i;
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/15 Move show_regs to traps.c.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
This is where it should be and we can get rid of some externs and a static inline function.
---
arch/s390/kernel/process.c | 18 ------------------ arch/s390/kernel/traps.c | 26 ++++++++++++++++++++++---- include/asm-s390/processor.h | 9 --------- 3 files changed, 22 insertions(+), 31 deletions(-)
arch/s390/kernel/process.c +0 -18
@@ -180,24 +180,6 @@ void cpu_idle(void) } } -void show_regs (struct pt_regs *regs) -{ -print_modules (); -printk ("CPU: %d %s %s %.*s\n" , -task_thread_info (current)->cpu,print_tainted (), -init_utsname ()->release, - (int )strcspn (init_utsname ()->version," " ), -init_utsname ()->version); -printk ("Process %s (pid: %d, task: %p, ksp: %p)\n" , - current->comm, current->pid, current, - (void *) current->thread.ksp); -show_registers (regs); -/* Show stack backtrace if pt_regs is from kernel mode */ -if (!(regs->psw.mask &PSW_MASK_PSTATE )) -show_trace (NULL , (unsigned long *) regs->gprs[15 ]); -show_last_breaking_event (regs); -} -extern void kernel_thread_starter (void ); asm(
arch/s390/kernel/traps.c +22 -4
@@ -113,7 +113,7 @@ __show_trace(unsigned long sp, unsigned } } -void show_trace (struct task_struct *task,unsigned long *stack) +static void show_trace (struct task_struct *task,unsigned long *stack) { registerunsigned long __r15 asm ("15" );unsigned long sp;
@@ -161,14 +161,14 @@ void show_stack(struct task_struct *taskshow_trace (task, sp); } -#ifdef CONFIG_64BIT -void show_last_breaking_event (struct pt_regs *regs) +static void show_last_breaking_event (struct pt_regs *regs) { +#ifdef CONFIG_64BIT printk ("Last Breaking-Event-Address:\n" );printk (" [<%016lx>] " , regs->args[0 ] &PSW_ADDR_INSN );print_symbol ("%s\n" , regs->args[0 ] &PSW_ADDR_INSN ); -}#endif +}/* * The architecture-independent dump_stack generator
@@ -223,6 +223,24 @@ void show_registers(struct pt_regs *regsshow_code (regs); } +void show_regs (struct pt_regs *regs) +{ +print_modules (); +printk ("CPU: %d %s %s %.*s\n" , +task_thread_info (current)->cpu,print_tainted (), +init_utsname ()->release, + (int )strcspn (init_utsname ()->version," " ), +init_utsname ()->version); +printk ("Process %s (pid: %d, task: %p, ksp: %p)\n" , + current->comm, current->pid, current, + (void *) current->thread.ksp); +show_registers (regs); +/* Show stack backtrace if pt_regs is from kernel mode */ +if (!(regs->psw.mask &PSW_MASK_PSTATE )) +show_trace (NULL , (unsigned long *) regs->gprs[15 ]); +show_last_breaking_event (regs); +} +/* This is called from fs/proc/array.c */ void task_show_regs (struct seq_file *m,struct task_struct *task) {
include/asm-s390/processor.h +0 -9
@@ -172,16 +172,7 @@ extern unsigned long thread_saved_pc(str*/ extern void task_show_regs (struct seq_file *m,struct task_struct *task); -extern void show_registers (struct pt_regs *regs);extern void show_code (struct pt_regs *regs); -extern void show_trace (struct task_struct *task,unsigned long *sp); -#ifdef CONFIG_64BIT -extern void show_last_breaking_event (struct pt_regs *regs); -#else -static inline void show_last_breaking_event (struct pt_regs *regs) -{ -} -#endif unsigned long get_wchan (struct task_struct *p);#define task_pt_regs (tsk) ((struct pt_regs *) \
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/15 Add missing ifndef/define to include/asm-s390/sysinfo.h.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
In order to protect against compile breakage in case the header file gets included twice.
---
include/asm-s390/sysinfo.h | 5 +++++ 1 file changed, 5 insertions(+)
include/asm-s390/sysinfo.h +5 -0
@@ -11,6 +11,9 @@* Christian Borntraeger <[email protected]> */ +#ifndef __ASM_S390_SYSINFO_H +#define __ASM_S390_SYSINFO_H + struct sysinfo_1_1_1 { char reserved_0[32]; char manufacturer[16];
@@ -114,3 +117,5 @@ static inline int stsi(void *sysinfo, in : "cc", "memory"); return r0; } + +#endif /* __ASM_S390_SYSINFO_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 4/15 smp: Fix locking order.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
On some smp sysfs store attributes get_online_cpus() may block on cpu_hotplug.lock, but we hold already smp_cpu_state_mutex. Since the locking order on cpu hotplug via arch_update_cpu_topology is inverse this might lead to deadlocks.
So make sure locking order is always the same.
---
arch/s390/kernel/smp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/s390/kernel/smp.c +6 -6
@@ -890,8 +890,8 @@ static ssize_t cpu_configure_store(strucif (val !=0 && val !=1 )return -EINVAL ; -mutex_lock (&smp_cpu_state_mutex);get_online_cpus (); +mutex_lock (&smp_cpu_state_mutex); rc = -EBUSY ;if (cpu_online (cpu)) goto out;
@@ -919,8 +919,8 @@ static ssize_t cpu_configure_store(strucbreak ; } out: -put_online_cpus ();mutex_unlock (&smp_cpu_state_mutex); +put_online_cpus ();return rc ? rc : count; } static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
@@ -1095,8 +1095,8 @@ static ssize_t __ref rescan_store(structint cpu;int rc; -mutex_lock (&smp_cpu_state_mutex);get_online_cpus (); +mutex_lock (&smp_cpu_state_mutex); newcpus = cpu_present_map; rc =smp_rescan_cpus ();if (rc)
@@ -1109,8 +1109,8 @@ static ssize_t __ref rescan_store(struct } rc =0 ; out: -put_online_cpus ();mutex_unlock (&smp_cpu_state_mutex); +put_online_cpus ();if (!cpus_empty (newcpus))topology_schedule_update ();return rc ? rc : count;
@@ -1139,16 +1139,16 @@ static ssize_t dispatching_store(structif (val !=0 && val !=1 )return -EINVAL ; rc =0 ; -mutex_lock (&smp_cpu_state_mutex);get_online_cpus (); +mutex_lock (&smp_cpu_state_mutex);if (cpu_management == val) goto out; rc =topology_set_cpu_management (val);if (!rc) cpu_management = val; out: -put_online_cpus ();mutex_unlock (&smp_cpu_state_mutex); +put_online_cpus ();return rc ? rc : count; } static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 5/15 Automatically detect added cpus.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
---
arch/s390/kernel/smp.c | 19 ++++++++++++++----- drivers/s390/char/sclp_config.c | 17 ++++++++++++++++- include/asm-s390/smp.h | 6 ++++++ 3 files changed, 36 insertions(+), 6 deletions(-)
arch/s390/kernel/smp.c +14 -5
@@ -505,7 +505,7 @@ out:return rc; } -static int smp_rescan_cpus (void ) +static int __smp_rescan_cpus (void ) {cpumask_t avail;
@@ -570,7 +570,7 @@ out:kfree (info);printk (KERN_INFO "CPUs: %d configured, %d standby\n" , c_cpus, s_cpus);get_online_cpus (); -smp_rescan_cpus (); +__smp_rescan_cpus ();put_online_cpus (); }
@@ -1088,8 +1088,8 @@ out: }#ifdef CONFIG_HOTPLUG_CPU -static ssize_t __ref rescan_store (struct sys_device *dev, -const char *buf,size_t count) + +int smp_rescan_cpus (void ) {cpumask_t newcpus;int cpu;
@@ -1098,7 +1098,7 @@ static ssize_t __ref rescan_store(structget_online_cpus ();mutex_lock (&smp_cpu_state_mutex); newcpus = cpu_present_map; - rc =smp_rescan_cpus (); + rc =__smp_rescan_cpus ();if (rc) goto out;cpus_andnot (newcpus, cpu_present_map, newcpus);
@@ -1113,6 +1113,15 @@ out:put_online_cpus ();if (!cpus_empty (newcpus))topology_schedule_update (); +return rc; +} + +static ssize_t __ref rescan_store (struct sys_device *dev,const char *buf, +size_t count) +{ +int rc; + + rc =smp_rescan_cpus ();return rc ? rc : count; } static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
drivers/s390/char/sclp_config.c +16 -1
@@ -10,6 +10,7 @@#include <linux/cpu.h> #include <linux/sysdev.h> #include <linux/workqueue.h> +#include <asm/smp.h> #include "sclp.h" #define TAG "sclp_config: "
@@ -19,9 +20,11 @@ struct conf_mgm_data {u8 ev_qualifier; } __attribute__((packed)); +#define EV_QUAL_CPU_CHANGE 1#define EV_QUAL_CAP_CHANGE 3static struct work_struct sclp_cpu_capability_work; +static struct work_struct sclp_cpu_change_work;static void sclp_cpu_capability_notify (struct work_struct *work) {
@@ -37,13 +40,24 @@ static void sclp_cpu_capability_notify(sput_online_cpus (); } +static void sclp_cpu_change_notify (struct work_struct *work) +{ +smp_rescan_cpus (); +} +static void sclp_conf_receiver_fn (struct evbuf_header *evbuf) {struct conf_mgm_data *cdata; cdata = (struct conf_mgm_data *)(evbuf +1 ); -if (cdata->ev_qualifier ==EV_QUAL_CAP_CHANGE ) +switch (cdata->ev_qualifier) { +case EV_QUAL_CPU_CHANGE : +schedule_work (&sclp_cpu_change_work); +break ; +case EV_QUAL_CAP_CHANGE :schedule_work (&sclp_cpu_capability_work); +break ; + } } static struct sclp_register sclp_conf_register =
@@ -57,6 +71,7 @@ static int __init sclp_conf_init(void)int rc;INIT_WORK (&sclp_cpu_capability_work, sclp_cpu_capability_notify); +INIT_WORK (&sclp_cpu_change_work, sclp_cpu_change_notify); rc =sclp_register (&sclp_conf_register);if (rc) {
include/asm-s390/smp.h +6 -0
@@ -108,5 +108,11 @@ static inline void smp_send_stop(void)#define smp_cpu_not_running (cpu) 1#endif +#ifdef CONFIG_HOTPLUG_CPU +extern int smp_rescan_cpus (void ); +#else +static inline int smp_rescan_cpus (void ) {return 0 ; } +#endif +extern union save_area *zfcpdump_save_areas[NR_CPUS +1 ];#endif
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/15 remove -traditional
In reply to Martin SchwidefskyFrom: Mathieu Desnoyers <[email protected]>
---
arch/s390/kernel/Makefile | 2 -- arch/s390/lib/Makefile | 2 -- arch/s390/math-emu/Makefile | 1 - 3 files changed, 5 deletions(-)
arch/s390/kernel/Makefile +0 -2
@@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -EXTRA_AFLAGS := -traditional - # # Passing null pointers is ok for smp code, since we access the lowcore here. #
arch/s390/lib/Makefile +0 -2
@@ -2,8 +2,6 @@ # Makefile for s390-specific library files.. # -EXTRA_AFLAGS := -traditional - lib-y += delay.o string.o uaccess_std.o uaccess_pt.o obj-$(CONFIG_32BIT) += div64.o qrnnd.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o
arch/s390/math-emu/Makefile +0 -1
@@ -5,4 +5,3 @@ obj-$(CONFIG_MATHEMU) := math.o EXTRA_CFLAGS := -I$(src) -Iinclude/math-emu -w -EXTRA_AFLAGS := -traditional
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 7/15 cio: Make isc handling more robust.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Introduce an ->isc field in the subchannel to store the desired interruption subclass, since sch->schib.pmcw.isc may be overwritten by the hardware on stsch() after machine checks.
---
drivers/s390/cio/cio.c | 9 ++++----- drivers/s390/cio/cio.h | 3 ++- drivers/s390/cio/device_fsm.c | 10 +++------- drivers/s390/cio/device_ops.c | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-)
drivers/s390/cio/cio.c +4 -5
@@ -407,8 +407,7 @@ cio_modify (struct subchannel *sch)/* * Enable subchannel. */ -int cio_enable_subchannel (struct subchannel *sch,unsigned int isc, -u32 intparm) +int cio_enable_subchannel (struct subchannel *sch,u32 intparm) {char dbf_txt[15 ];int ccode;
@@ -426,7 +425,7 @@ int cio_enable_subchannel(struct subchanfor (retry =5 , ret =0 ; retry >0 ; retry--) { sch->schib.pmcw.ena =1 ; - sch->schib.pmcw.isc = isc; + sch->schib.pmcw.isc = sch->isc; sch->schib.pmcw.intparm = intparm; ret =cio_modify (sch);if (ret == -ENODEV )
@@ -600,6 +599,7 @@ cio_validate_subchannel (struct subchannelse sch->opm =chp_get_sch_opm (sch); sch->lpm = sch->schib.pmcw.pam & sch->opm; + sch->isc =3 ;CIO_DEBUG (KERN_INFO ,0 , "Detected device %04x on subchannel 0.%x.%04X"
@@ -610,13 +610,11 @@ cio_validate_subchannel (struct subchann/* * We now have to initially ... -* ... set "interruption subclass" * ... enable "concurrent sense" * ... enable "multipath mode" if more than one * CHPID is available. This is done regardless * whether multiple paths are available for us. */ - sch->schib.pmcw.isc =3 ;/* could be smth. else */ sch->schib.pmcw.csense =1 ;/* concurrent sense */ sch->schib.pmcw.ena =0 ;if ((sch->lpm & (sch->lpm -1 )) !=0 )
@@ -812,6 +810,7 @@ cio_probe_console(void)* enable console I/O-interrupt subclass 7 */ ctl_set_bit (6 ,24 ); + console_subchannel.isc =7 ; console_subchannel.schib.pmcw.isc =7 ; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel;
drivers/s390/cio/cio.h +2 -1
@@ -74,6 +74,7 @@ struct subchannel {__u8 lpm;/* logical path mask */ __u8 opm;/* operational path mask */ struct schib schib;/* subchannel information block */ +int isc;/* desired interruption subclass */ struct chsc_ssd_info ssd_info;/* subchannel description */ struct device dev;/* entry in device tree */ struct css_driver *driver;
@@ -85,7 +86,7 @@ struct subchannel {#define to_subchannel (n) container_of(n, struct subchannel, dev)extern int cio_validate_subchannel (struct subchannel *,struct subchannel_id ); -extern int cio_enable_subchannel (struct subchannel *,unsigned int ,u32 ); +extern int cio_enable_subchannel (struct subchannel *,u32 );extern int cio_disable_subchannel (struct subchannel *);extern int cio_cancel (struct subchannel *);extern int cio_clear (struct subchannel *);
drivers/s390/cio/device_fsm.c +3 -7
@@ -555,8 +555,7 @@ ccw_device_recognition(struct ccw_device (cdev->private->state != DEV_STATE_BOXED))return -EINVAL ; sch =to_subchannel (cdev->dev.parent); - ret =cio_enable_subchannel (sch, sch->schib.pmcw.isc, - (u32 )(addr_t )sch); + ret =cio_enable_subchannel (sch, (u32 )(addr_t )sch);if (ret !=0 )/* Couldn't enable the subchannel for i/o. Sick device. */ return ret;
@@ -667,8 +666,7 @@ ccw_device_online(struct ccw_device *cde sch =to_subchannel (cdev->dev.parent);if (css_init_done && !get_device (&cdev->dev))return -ENODEV ; - ret =cio_enable_subchannel (sch, sch->schib.pmcw.isc, - (u32 )(addr_t )sch); + ret =cio_enable_subchannel (sch, (u32 )(addr_t )sch);if (ret !=0 ) {/* Couldn't enable the subchannel for i/o. Sick device. */ if (ret == -ENODEV )
@@ -1048,8 +1046,7 @@ ccw_device_start_id(struct ccw_device *cstruct subchannel *sch; sch =to_subchannel (cdev->dev.parent); -if (cio_enable_subchannel (sch, sch->schib.pmcw.isc, - (u32 )(addr_t )sch) !=0 ) +if (cio_enable_subchannel (sch, (u32 )(addr_t )sch) !=0 )/* Couldn't enable the subchannel for i/o. Sick device. */ return ;
@@ -1082,7 +1079,6 @@ device_trigger_reprobe(struct subchannel*/ sch->lpm = sch->schib.pmcw.pam & sch->opm;/* Re-set some bits in the pmcw that were lost. */ - sch->schib.pmcw.isc =3 ; sch->schib.pmcw.csense =1 ; sch->schib.pmcw.ena =0 ;if ((sch->lpm & (sch->lpm -1 )) !=0 )
drivers/s390/cio/device_ops.c +1 -1
@@ -508,7 +508,7 @@ ccw_device_stlck(struct ccw_device *cdevreturn -ENOMEM ; }spin_lock_irqsave (sch->lock, flags); - ret =cio_enable_subchannel (sch,3 , (u32 )(addr_t )sch); + ret =cio_enable_subchannel (sch, (u32 )(addr_t )sch);if (ret) goto out_unlock;/*
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/15 Add topology_core_siblings to topology.h
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
This exposes the core siblings to user space via sysfs.
---
arch/s390/kernel/topology.c | 21 ++++++++++++++++++--- include/asm-s390/topology.h | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-)
arch/s390/kernel/topology.c +18 -3
@@ -66,6 +66,8 @@ static struct timer_list topology_timer;static void set_topology_timer (void ); static DECLARE_WORK(topology_work, topology_work_fn); +cpumask_t cpu_core_map[NR_CPUS ]; +cpumask_t cpu_coregroup_map (unsigned int cpu) {struct core_info *core = &core_info;
@@ -199,6 +201,14 @@ int topology_set_cpu_management(int fc)return rc; } +static void update_cpu_core_map (void ) +{ +int cpu; + +for_each_present_cpu (cpu) + cpu_core_map[cpu] =cpu_coregroup_map (cpu); +} +void arch_update_cpu_topology (void ) {struct tl_info *info = tl_info;
@@ -206,11 +216,13 @@ void arch_update_cpu_topology(void)int cpu;if (!machine_has_topology) { +update_cpu_core_map ();topology_update_polarization_simple ();return ; }stsi (info,15 ,1 ,2 );tl_to_cores (info); +update_cpu_core_map ();for_each_online_cpu (cpu) { sysdev =get_cpu_sysdev (cpu);kobject_uevent (&sysdev->kobj,KOBJ_CHANGE );
@@ -251,20 +263,23 @@ static int __init init_topology_update(v {int rc; + rc =0 ;if (!machine_has_topology) {topology_update_polarization_simple (); -return 0 ; + goto out; }init_timer_deferrable (&topology_timer);if (machine_has_topology_irq) { rc =register_external_interrupt (0x2005 , topology_interrupt);if (rc) -return rc; + goto out;ctl_set_bit (0 ,8 ); }else set_topology_timer (); -return 0 ; +out: +update_cpu_core_map (); +return rc; }__initcall (init_topology_update);
include/asm-s390/topology.h +4 -0
@@ -7,6 +7,10 @@cpumask_t cpu_coregroup_map (unsigned int cpu); +extern cpumask_t cpu_core_map[NR_CPUS ]; + +#define topology_core_siblings (cpu) (cpu_core_map[cpu]) +int topology_set_cpu_management (int fc);void topology_schedule_update (void );
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/15 cpu topology: Fix possible deadlock.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
When we get a notification that cpu topology changed, we schedule a work struct which just calls arch_reinit_sched_domains. This function in turn calls get_online_cpus() which results int the lockdep warning below.
After all it turnded out that it's not legal to call get_online_cpus() from the context of a multi-threaded work queue.
It could deadlock this way:
process 0 (events/cpu-x):
-> run_workqueue
-> removes my work_struct from the work queue
-> calls work_struct->fn
-> get_online_cpus()
-> locks on cpu_hotplug.lock since process 1 below is doing cpu hotplug
process 1:
-> cpu_down (for cpu-x)
-> cpu_hotplug_begin (holds cpu_hotplug.lock now)
-> cpu-x dead
-> notifier_call_chain with CPU_DEAD
-> cleanup_workqueue_thread
-> flush_cpu_workqueue (succeeds)
-> kthread_stop for events/cpu-x
-> now kthread_stop waits for my work_struct to complete from within
process 0. -> dead.
A single threaded workqueue wouldn't have such problems, however there is no such common queue available and it's not worth to create one for the very rare calls to arch_reinit_sched_domains.
So we just create a kernel thread from our work struct which calls arch_reinit_sched_domains and are done with it.
Thanks to Oleg Nesterov and Peter Zijlstra for helping me figuring out that this isn't a false positive lockdep warning:
=======================================================
[ INFO: possible circular locking dependency detected ] 2.6.25-03562-g3dc5063-dirty #12
-------------------------------------------------------
events/3/14 is trying to acquire lock:
(&cpu_hotplug.lock){--..}, at: [<0000000000076094>] get_online_cpus+0x50/0x78
but task is already holding lock:
(topology_work){--..}, at: [<0000000000059cde>] run_workqueue+0x106/0x278
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (topology_work){--..}:
[<000000000006fc74>] __lock_acquire+0x1010/0x111c
[<000000000006fe40>] lock_acquire+0xc0/0xf8
[<0000000000059d48>] run_workqueue+0x170/0x278
[<0000000000059edc>] worker_thread+0x8c/0xf0
[<000000000005f5bc>] kthread+0x68/0xa0
[<000000000001a33e>] kernel_thread_starter+0x6/0xc
[<000000000001a338>] kernel_thread_starter+0x0/0xc-> #1 (events){--..}:
[<000000000006fc74>] __lock_acquire+0x1010/0x111c
[<000000000006fe40>] lock_acquire+0xc0/0xf8
[<000000000005a23c>] cleanup_workqueue_thread+0x60/0xa8
[<00000000003b2ab8>] workqueue_cpu_callback+0xbc/0x170
[<00000000003bba80>] notifier_call_chain+0x5c/0xa4
[<00000000000655a2>] __raw_notifier_call_chain+0x26/0x38
[<00000000000655e2>] raw_notifier_call_chain+0x2e/0x40
[<0000000000075e00>] cpu_down+0x228/0x31c
[<00000000003b1dd8>] store_online+0x64/0xb8
[<00000000001e7128>] sysdev_store+0x48/0x58
[<0000000000121cd2>] sysfs_write_file+0x126/0x1c0
[<00000000000c1944>] vfs_write+0xb0/0x15c
[<00000000000c20e6>] sys_write+0x56/0x88
[<0000000000027a68>] sys32_write+0x34/0x4c
[<0000000000023f70>] sysc_noemu+0x10/0x16
[<0000000077f3f186>] 0x77f3f186-> #0 (&cpu_hotplug.lock){--..}:
[<000000000006fa84>] __lock_acquire+0xe20/0x111c
[<000000000006fe40>] lock_acquire+0xc0/0xf8
[<00000000003b701c>] mutex_lock_nested+0xd0/0x364
[<0000000000076094>] get_online_cpus+0x50/0x78
[<000000000003a03e>] arch_reinit_sched_domains+0x26/0x58
[<000000000002700e>] topology_work_fn+0x26/0x34
[<0000000000059d4e>] run_workqueue+0x176/0x278
[<0000000000059edc>] worker_thread+0x8c/0xf0
[<000000000005f5bc>] kthread+0x68/0xa0
[<000000000001a33e>] kernel_thread_starter+0x6/0xc
[<000000000001a338>] kernel_thread_starter+0x0/0xcother info that might help us debug this:
2 locks held by events/3/14:
#0: (events){--..}, at: [<0000000000059cde>] run_workqueue+0x106/0x278 #1: (topology_work){--..}, at: [<0000000000059cde>] run_workqueue+0x106/0x278
stack backtrace:
CPU: 3 Not tainted 2.6.25-03562-g3dc5063-dirty #12
Process events/3 (pid: 14, task: 000000002fb04038, ksp: 000000002fb0bd70)
0400000000000000 000000002fb0ba40 0000000000000002 0000000000000000
000000002fb0bae0 000000002fb0ba58 000000002fb0ba58 0000000000016488
0000000000000000 000000002fb0bd70 0000000000000000 0000000000000000
000000002fb0ba40 000000000000000c 000000002fb0ba40 000000002fb0bab0
00000000003c99e0 0000000000016488 000000002fb0ba40 000000002fb0ba90
Call Trace:
([<00000000000163fc>] show_trace+0x138/0x158)
[<00000000000164e2>] show_stack+0xc6/0xf8
[<0000000000016624>] dump_stack+0xb0/0xc0
[<000000000006cd36>] print_circular_bug_tail+0xa2/0xb4
[<000000000006fa84>] __lock_acquire+0xe20/0x111c
[<000000000006fe40>] lock_acquire+0xc0/0xf8
[<00000000003b701c>] mutex_lock_nested+0xd0/0x364
[<0000000000076094>] get_online_cpus+0x50/0x78
[<000000000003a03e>] arch_reinit_sched_domains+0x26/0x58
[<000000000002700e>] topology_work_fn+0x26/0x34
[<0000000000059d4e>] run_workqueue+0x176/0x278
[<0000000000059edc>] worker_thread+0x8c/0xf0
[<000000000005f5bc>] kthread+0x68/0xa0
[<000000000001a33e>] kernel_thread_starter+0x6/0xc
[<000000000001a338>] kernel_thread_starter+0x0/0xcINFO: lockdep is turned off.
---
arch/s390/kernel/topology.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
arch/s390/kernel/topology.c +13 -1
@@ -9,6 +9,7 @@#include <linux/device.h> #include <linux/bootmem.h> #include <linux/sched.h> +#include <linux/kthread.h> #include <linux/workqueue.h> #include <linux/cpu.h> #include <linux/smp.h>
@@ -229,9 +230,20 @@ void arch_update_cpu_topology(void) } } -static void topology_work_fn (struct work_struct *work) +static int topology_kthread (void *data) {arch_reinit_sched_domains (); +return 0 ; +} + +static void topology_work_fn (struct work_struct *work) +{ +/* We can't call arch_reinit_sched_domains() from a multi-threaded +* workqueue context since it may deadlock in case of cpu hotplug. +* So we have to create a kernel thread in order to call +* arch_reinit_sched_domains(). +*/ +kthread_run (topology_kthread,NULL ,"topology_update" ); }void topology_schedule_update (void )
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 10/15 uaccess_mvcos: #ifdef config dependent code.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
arch/s390/lib/uaccess_mvcos.c:166:
warning: 'strnlen_user_mvcos' defined but not usedarch/s390/lib/uaccess_mvcos.c:186:
warning: 'strncpy_from_user_mvcos' defined but not used
---
arch/s390/lib/uaccess_mvcos.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/lib/uaccess_mvcos.c +2 -0
@@ -162,6 +162,7 @@ static size_t clear_user_mvcos(size_t sireturn size; } +#ifdef CONFIG_S390_SWITCH_AMODE static size_t strnlen_user_mvcos (size_t count,const char __user *src) {char buf[256 ];
@@ -199,6 +200,7 @@ static size_t strncpy_from_user_mvcos(si } while ((len_str == len) && (done < count));return done; } +#endif /* CONFIG_S390_SWITCH_AMODE */ struct uaccess_ops uaccess_mvcos = { .copy_from_user = copy_from_user_mvcos_check,
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 11/15 Move stfl to system.h and delete duplicated version.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
---
arch/s390/kernel/setup.c | 9 --------- arch/s390/kvm/priv.c | 11 +---------- include/asm-s390/system.h | 10 ++++++++++ 3 files changed, 11 insertions(+), 19 deletions(-)
arch/s390/kernel/setup.c +0 -9
@@ -683,15 +683,6 @@ setup_memory(void)#endif } -static __init unsigned int stfl (void ) -{ - asmvolatile ( -" .insn s,0xb2b10000,0(0)\n" /* stfl */ -"0:\n" - EX_TABLE(0b,0b)); -return S390_lowcore.stfl_fac_list; -} -static int __init __stfle (unsigned long long *list,int doublewords) {typedef struct {unsigned long long _[doublewords]; }addrtype ;
arch/s390/kvm/priv.c +1 -10
@@ -151,18 +151,9 @@ static int handle_chsc(struct kvm_vcpu *return 0 ; } -static unsigned int kvm_stfl (void ) -{ - asmvolatile ( -" .insn s,0xb2b10000,0(0)\n" /* stfl */ -"0:\n" - EX_TABLE(0b, 0b)); -return S390_lowcore.stfl_fac_list; -} -static int handle_stfl (struct kvm_vcpu *vcpu) { -unsigned int facility_list =kvm_stfl (); +unsigned int facility_list =stfl ();int rc; vcpu->stat.instruction_stfl++;
include/asm-s390/system.h +10 -0
@@ -16,6 +16,7 @@#include <asm/ptrace.h> #include <asm/setup.h> #include <asm/processor.h> +#include <asm/lowcore.h> #ifdef __KERNEL__
@@ -422,6 +423,15 @@ extern void smp_ctl_clear_bit(int cr, in#endif /* CONFIG_SMP */ +static inline unsigned int stfl (void ) +{ + asmvolatile ( +" .insn s,0xb2b10000,0(0)\n" /* stfl */ +"0:\n" + EX_TABLE(0b,0b)); +return S390_lowcore.stfl_fac_list; +} +extern void (*_machine_restart)(char *command);extern void (*_machine_halt)(void );extern void (*_machine_power_off)(void );
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 12/15 vmemmap: use clear_table to initialise page tables.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Always use clear_table to initialise page tables. The overlapping memcpy is just a leftover of a previous version that wasn't fully converted to clear_table.
---
arch/s390/mm/vmem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
arch/s390/mm/vmem.c +2 -3
@@ -77,8 +77,7 @@ static inline pud_t *vmem_pud_alloc(void pud =vmem_alloc_pages (2 );if (!pud)return NULL ; -pud_val (*pud) = _REGION3_ENTRY_EMPTY; -memcpy (pud +1 , pud, (PTRS_PER_PUD -1 )*sizeof (pud_t)); +clear_table ((unsigned long *) pud, _REGION3_ENTRY_EMPTY,PAGE_SIZE *4 );#endif return pud; }
@@ -91,7 +90,7 @@ static inline pmd_t *vmem_pmd_alloc(void pmd =vmem_alloc_pages (2 );if (!pmd)return NULL ; -clear_table ((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY,PAGE_SIZE *4 ); +clear_table ((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY,PAGE_SIZE *4 );#endif return pmd; }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 13/15 Convert machine feature detection code to C.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
From: Carsten Otte <[email protected]>
This lets us use defines for the magic bits in machine flags instead of using plain numbers all over the place.
In addition on newer machines features/facilities are indicated by the result of the stfl instruction. So we use these bits instead of trying to execute new instructions and check wether we get an exception or not.
Also the mvpg instruction is always available when in zArch mode, whereas the idte instruction is only available in zArch mode. This results in some minor optimizations.
---
arch/s390/kernel/early.c | 109 ++++++++++++++++++++++++++++++++++++++++++++-- arch/s390/kernel/head31.S | 61 ------------------------- arch/s390/kernel/head64.S | 62 -------------------------- arch/s390/kernel/setup.c | 2 include/asm-s390/setup.h | 33 +++++++++---- include/asm-s390/smp.h | 6 -- include/asm-s390/system.h | 8 +++ 7 files changed, 140 insertions(+), 141 deletions(-)
arch/s390/kernel/early.c +106 -3
@@ -139,15 +139,15 @@ static noinline __init void detect_machi/* Running under z/VM ? */ if (cpuinfo->cpu_id.version ==0xff ) - machine_flags |=1 ; + machine_flags |=MACHINE_FLAG_VM ;/* Running on a P/390 ? */ if (cpuinfo->cpu_id.machine ==0x7490 ) - machine_flags |=4 ; + machine_flags |=MACHINE_FLAG_P390 ;/* Running under KVM ? */ if (cpuinfo->cpu_id.version ==0xfe ) - machine_flags |=64 ; + machine_flags |=MACHINE_FLAG_KVM ; }#ifdef CONFIG_64BIT
@@ -268,6 +268,103 @@ static noinline __init void setup_lowcor s390_base_pgm_handler_fn = early_pgm_check_handler; } +static __init void detect_mvpg (void ) +{ +#ifndef CONFIG_64BIT +int rc; + + asm volatile( + " la 0,0\n" + " mvpg %2,%2\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); +if (!rc) + machine_flags |=MACHINE_FLAG_MVPG ; +#endif +} + +static __init void detect_ieee (void ) +{ +#ifndef CONFIG_64BIT +int rc, tmp; + + asm volatile( + " efpc %1,0\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); +if (!rc) + machine_flags |=MACHINE_FLAG_IEEE ; +#endif +} + +static __init void detect_csp (void ) +{ +#ifndef CONFIG_64BIT +int rc; + + asmvolatile ( +" la 0,0\n" +" la 1,0\n" +" la 2,4\n" +" csp 0,2\n" +"0: la %0,0\n" +"1:\n" + EX_TABLE(0b,1b) + : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); +if (!rc) + machine_flags |=MACHINE_FLAG_CSP ; +#endif +} + +static __init void detect_diag9c (void ) +{ +unsigned int cpu_address; +int rc; + + cpu_address =stap (); + asm volatile( + " diag %2,0,0x9c\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); + if (!rc) + machine_flags |=MACHINE_FLAG_DIAG9C ; +} + +static __init void detect_diag44 (void ) +{ +#ifdef CONFIG_64BIT +int rc; + + asm volatile( + " diag 0,0,0x44\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); +if (!rc) + machine_flags |=MACHINE_FLAG_DIAG44 ; +#endif +} + +static __init void detect_machine_facilities (void ) +{ +#ifdef CONFIG_64BIT +unsigned int facilities; + + facilities =stfl (); +if (facilities & (1 <<28 )) + machine_flags |=MACHINE_FLAG_IDTE ; +if (facilities & (1 <<4 )) + machine_flags |=MACHINE_FLAG_MVCOS ; +#endif +} +/* * Save ipl parameters, clear bss memory, initialize storage keys * and create a kernel NSS at startup if the SAVESYS= parm is defined
@@ -285,6 +382,12 @@ void __init startup_init(void)create_kernel_nss ();sort_main_extable ();setup_lowcore_early (); +detect_mvpg (); +detect_ieee (); +detect_csp (); +detect_diag9c (); +detect_diag44 (); +detect_machine_facilities ();sclp_read_info_early ();sclp_facilities_detect (); memsize =sclp_memory_detect ();
arch/s390/kernel/head31.S +0 -61
74 lines not on this page · raw message
arch/s390/kernel/head64.S +0 -62
68 lines not on this page · raw message
arch/s390/kernel/setup.c +1 -1
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(uaccess);unsigned int console_mode =0 ;unsigned int console_devno =-1 ;unsigned int console_irq =-1 ; -unsigned long machine_flags =0 ; +unsigned long machine_flags;unsigned long elf_hwcap =0 ;char elf_platform[ELF_PLATFORM_SIZE ];
include/asm-s390/setup.h +23 -10
@@ -59,23 +59,36 @@ extern unsigned int s390_noexec;*/ extern unsigned long machine_flags; -#define MACHINE_IS_VM (machine_flags & 1) -#define MACHINE_IS_P390 (machine_flags & 4) -#define MACHINE_HAS_MVPG (machine_flags & 16) -#define MACHINE_IS_KVM (machine_flags & 64) -#define MACHINE_HAS_IDTE (machine_flags & 128) -#define MACHINE_HAS_DIAG9C (machine_flags & 256) +#define MACHINE_FLAG_VM (1UL << 0) +#define MACHINE_FLAG_IEEE (1UL << 1) +#define MACHINE_FLAG_P390 (1UL << 2) +#define MACHINE_FLAG_CSP (1UL << 3) +#define MACHINE_FLAG_MVPG (1UL << 4) +#define MACHINE_FLAG_DIAG44 (1UL << 5) +#define MACHINE_FLAG_IDTE (1UL << 6) +#define MACHINE_FLAG_DIAG9C (1UL << 7) +#define MACHINE_FLAG_MVCOS (1UL << 8) +#define MACHINE_FLAG_KVM (1UL << 9) + +#define MACHINE_IS_VM (machine_flags & MACHINE_FLAG_VM) +#define MACHINE_IS_KVM (machine_flags & MACHINE_FLAG_KVM) +#define MACHINE_IS_P390 (machine_flags & MACHINE_FLAG_P390) +#define MACHINE_HAS_DIAG9C (machine_flags & MACHINE_FLAG_DIAG9C)#ifndef __s390x__ -#define MACHINE_HAS_IEEE (machine_flags & 2) -#define MACHINE_HAS_CSP (machine_flags & 8) +#define MACHINE_HAS_IEEE (machine_flags & MACHINE_FLAG_IEEE) +#define MACHINE_HAS_CSP (machine_flags & MACHINE_FLAG_CSP) +#define MACHINE_HAS_IDTE (0)#define MACHINE_HAS_DIAG44 (1) +#define MACHINE_HAS_MVPG (machine_flags & MACHINE_FLAG_MVPG)#define MACHINE_HAS_MVCOS (0)#else /* __s390x__ */ #define MACHINE_HAS_IEEE (1)#define MACHINE_HAS_CSP (1) -#define MACHINE_HAS_DIAG44 (machine_flags & 32) -#define MACHINE_HAS_MVCOS (machine_flags & 512) +#define MACHINE_HAS_IDTE (machine_flags & MACHINE_FLAG_IDTE) +#define MACHINE_HAS_DIAG44 (machine_flags & MACHINE_FLAG_DIAG44) +#define MACHINE_HAS_MVPG (1) +#define MACHINE_HAS_MVCOS (machine_flags & MACHINE_FLAG_MVCOS)#endif /* __s390x__ */ #define MACHINE_HAS_SCLP (!MACHINE_IS_P390)
include/asm-s390/smp.h +2 -4
@@ -19,6 +19,7 @@#include <asm/lowcore.h> #include <asm/sigp.h> #include <asm/ptrace.h> +#include <asm/system.h> /* s390 specific smp.c headers
@@ -53,10 +54,7 @@ extern void machine_power_off_smp(void);static inline __u16 hard_smp_processor_id (void ) { -__u16 cpu_address; - - asmvolatile ("stap %0" :"=m" (cpu_address)); -return cpu_address; +return stap (); }/*
include/asm-s390/system.h +8 -0
@@ -432,6 +432,14 @@ static inline unsigned int stfl(void)return S390_lowcore.stfl_fac_list; } +static inline unsigned short stap (void ) +{ +unsigned short cpu_address; + + asmvolatile ("stap %0" :"=m" (cpu_address)); +return cpu_address; +} +extern void (*_machine_restart)(char *command);extern void (*_machine_halt)(void );extern void (*_machine_power_off)(void );
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 14/15 System z large page support.
In reply to Martin SchwidefskyFrom: Gerald Schaefer <[email protected]>
This adds hugetlbfs support on System z, using both hardware large page support if available and software large page emulation on older hardware. Shared (large) page tables are implemented in software emulation mode, by using page->index of the first tail page from a compound large page to store page table information.
---
arch/s390/kernel/early.c | 16 +++ arch/s390/kernel/head64.S | 2 arch/s390/kernel/setup.c | 10 +- arch/s390/mm/Makefile | 2 arch/s390/mm/fault.c | 3 arch/s390/mm/hugetlbpage.c | 134 ++++++++++++++++++++++++++++++++ arch/s390/mm/init.c | 23 ----- arch/s390/mm/vmem.c | 55 +++++++++++-- fs/Kconfig | 3 include/asm-s390/hugetlb.h | 183 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-s390/page.h | 29 +++++- include/asm-s390/pgtable.h | 12 ++ include/asm-s390/setup.h | 6 + include/asm-s390/tlbflush.h | 1 14 files changed, 437 insertions(+), 42 deletions(-)
arch/s390/kernel/early.c +16 -0
@@ -268,6 +268,19 @@ static noinline __init void setup_lowcor s390_base_pgm_handler_fn = early_pgm_check_handler; } +static noinline __init void setup_hpage(void) +{ +#ifndef CONFIG_DEBUG_PAGEALLOC +unsigned int facilities; + + facilities =stfl (); +if (!(facilities & (1UL <<23 )) || !(facilities & (1UL <<29 ))) +return ; + machine_flags |=MACHINE_FLAG_HPAGE ; +__ctl_set_bit (0 ,23 ); +#endif +} +static __init void detect_mvpg (void ) {#ifndef CONFIG_64BIT
@@ -360,6 +373,8 @@ static __init void detect_machine_facili facilities =stfl ();if (facilities & (1 <<28 )) machine_flags |=MACHINE_FLAG_IDTE ; +if (facilities & (1 <<23 )) + machine_flags |=MACHINE_FLAG_PFMF ;if (facilities & (1 <<4 )) machine_flags |=MACHINE_FLAG_MVCOS ;#endif
@@ -388,6 +403,7 @@ void __init startup_init(void)detect_diag9c ();detect_diag44 ();detect_machine_facilities (); +setup_hpage ();sclp_read_info_early ();sclp_facilities_detect (); memsize =sclp_memory_detect ();
arch/s390/kernel/head64.S +1 -1
@@ -129,7 +129,7 @@ startup_continue: # virtual and never return ... .align 16 .Lentry:.quad 0x0000000180000000,_stext -.Lctl: .quad 0x04b50002 # cr0: various things +.Lctl: .quad 0x04350002 # cr0: various things .quad 0 # cr1: primary space segment table .quad .Lduct # cr2: dispatchable unit control table .quad 0 # cr3: instruction authorization
arch/s390/kernel/setup.c +7 -3
@@ -749,6 +749,9 @@ static void __init setup_hwcaps(void) elf_hwcap |=1UL <<6 ; } +if (MACHINE_HAS_HPAGE ) + elf_hwcap |=1UL <<7 ; +switch (cpuinfo->cpu_id.machine) {case 0x9672 :#if !defined(CONFIG_64BIT )
@@ -872,8 +875,9 @@ void __cpuinit print_cpu_info(struct cpustatic int show_cpuinfo (struct seq_file *m,void *v) { -static const char *hwcap_str[7 ] = { -"esan3" ,"zarch" ,"stfle" ,"msa" ,"ldisp" ,"eimm" ,"dfp" +static const char *hwcap_str[8 ] = { +"esan3" ,"zarch" ,"stfle" ,"msa" ,"ldisp" ,"eimm" ,"dfp" , +"edat" };struct cpuinfo_S390 *cpuinfo;unsigned long n = (unsigned long ) v -1 ;
@@ -888,7 +892,7 @@ static int show_cpuinfo(struct seq_filenum_online_cpus (), loops_per_jiffy/(500000 /HZ ), (loops_per_jiffy/(5000/HZ))%100);seq_puts (m,"features\t: " ); -for (i =0 ; i <7 ; i++) +for (i =0 ; i <8 ; i++)if (hwcap_str[i] && (elf_hwcap & (1UL << i)))seq_printf (m,"%s " , hwcap_str[i]);seq_puts (m,"\n" );
arch/s390/mm/fault.c +3 -0
@@ -28,6 +28,7 @@#include <linux/hardirq.h> #include <linux/kprobes.h> #include <linux/uaccess.h> +#include <linux/hugetlb.h> #include <asm/system.h> #include <asm/pgtable.h> #include <asm/s390_ext.h>
@@ -367,6 +368,8 @@ good_area: } survive: +if (is_vm_hugetlb_page (vma)) + address &=HPAGE_MASK ;/* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo
arch/s390/mm/hugetlbpage.c new file +134 -0
134 lines not on this page · raw message
arch/s390/mm/init.c +0 -23
@@ -77,28 +77,6 @@ void show_mem(void)printk ("%lu pages pagetables\n" ,global_page_state (NR_PAGETABLE )); } -static void __init setup_ro_region (void ) -{ -pgd_t *pgd; -pud_t *pud; -pmd_t *pmd; -pte_t *pte; -pte_t new_pte; -unsigned long address, end; - - address = ((unsigned long )&_stext) &PAGE_MASK ; - end =PFN_ALIGN ((unsigned long )&_eshared); - -for (; address < end; address +=PAGE_SIZE ) { - pgd =pgd_offset_k (address); - pud =pud_offset (pgd, address); - pmd =pmd_offset (pud, address); - pte =pte_offset_kernel (pmd, address); - new_pte =mk_pte_phys (address,__pgprot (_PAGE_RO)); - *pte = new_pte; - } -} -/* * paging_init() sets up the page tables */
@@ -121,7 +99,6 @@ void __init paging_init(void)clear_table ((unsigned long *) init_mm.pgd, pgd_type,sizeof (unsigned long )*2048 );vmem_map_init (); -setup_ro_region ();/* enable virtual mapping in kernel mode */ __ctl_load (S390_lowcore.kernel_asce,1 ,1 );
arch/s390/mm/Makefile +1 -1
@@ -4,4 +4,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o obj-$(CONFIG_CMM) += cmm.o - +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
arch/s390/mm/vmem.c +48 -7
120 lines not on this page · raw message
fs/Kconfig +2 -1
@@ -1005,7 +1005,8 @@ config TMPFS_POSIX_ACL config HUGETLBFS bool "HugeTLB file system support" - depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || BROKEN + depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \ + (S390 && 64BIT) || BROKEN help hugetlbfs is a filesystem backing for HugeTLB pages, based on ramfs. For architectures that support it, say Y here and read
include/asm-s390/hugetlb.h new file +183 -0
183 lines not on this page · raw message
include/asm-s390/page.h +23 -6
@@ -19,17 +19,34 @@#define PAGE_DEFAULT_ACC 0#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) +#define HPAGE_SHIFT 20 +#define HPAGE_SIZE (1UL << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) + +#define ARCH_HAS_SETCLEAR_HUGE_PTE +#define ARCH_HAS_HUGE_PTE_TYPE +#define ARCH_HAS_PREPARE_HUGEPAGE +#define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH +#include <asm/setup.h> #ifndef __ASSEMBLY__static inline void clear_page (void *page) { - register unsigned long reg1 asm ("1") = 0; - register void *reg2 asm ("2") = page; - register unsigned long reg3 asm ("3") = 4096; - asmvolatile ( -" mvcl 2,0" - :"+d" (reg2),"+d" (reg3) :"d" (reg1) :"memory" ,"cc" ); +if (MACHINE_HAS_PFMF ) { + asmvolatile ( +" .insn rre,0xb9af0000,%0,%1" + : :"d" (0x10000 ),"a" (page) :"memory" ,"cc" ); + }else { + register unsigned long reg1 asm ("1") = 0; + register void *reg2 asm ("2") = page; + register unsigned long reg3 asm ("3") = 4096; + asmvolatile ( +" mvcl 2,0" + :"+d" (reg2),"+d" (reg3) :"d" (reg1) + :"memory" ,"cc" ); + } }static inline void copy_page (void *to,void *from)
include/asm-s390/pgtable.h +12 -0
@@ -234,6 +234,15 @@ extern char empty_zero_page[PAGE_SIZE];#define _PAGE_TYPE_EX_RW 0x002/* +* Only four types for huge pages, using the invalid bit and protection bit +* of a segment table entry. +*/ +#define _HPAGE_TYPE_EMPTY 0x020/* _SEGMENT_ENTRY_INV */ +#define _HPAGE_TYPE_NONE 0x220 +#define _HPAGE_TYPE_RO 0x200/* _SEGMENT_ENTRY_RO */ +#define _HPAGE_TYPE_RW 0x000 + +/* * PTE type bits are rather complicated. handle_pte_fault uses pte_present, * pte_none and pte_file to find out the pte type WITHOUT holding the page * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to
@@ -325,6 +334,9 @@ extern char empty_zero_page[PAGE_SIZE];#define _SEGMENT_ENTRY (0)#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) +#define _SEGMENT_ENTRY_LARGE 0x400/* STE-format control, large page */ +#define _SEGMENT_ENTRY_CO 0x100/* change-recording override */ +#endif /* __s390x__ */ /*
include/asm-s390/setup.h +6 -0
@@ -69,6 +69,8 @@ extern unsigned long machine_flags;#define MACHINE_FLAG_DIAG9C (1UL << 7)#define MACHINE_FLAG_MVCOS (1UL << 8)#define MACHINE_FLAG_KVM (1UL << 9) +#define MACHINE_FLAG_HPAGE (1UL << 10) +#define MACHINE_FLAG_PFMF (1UL << 11)#define MACHINE_IS_VM (machine_flags & MACHINE_FLAG_VM)#define MACHINE_IS_KVM (machine_flags & MACHINE_FLAG_KVM)
@@ -82,6 +84,8 @@ extern unsigned long machine_flags;#define MACHINE_HAS_DIAG44 (1)#define MACHINE_HAS_MVPG (machine_flags & MACHINE_FLAG_MVPG)#define MACHINE_HAS_MVCOS (0) +#define MACHINE_HAS_HPAGE (0) +#define MACHINE_HAS_PFMF (0)#else /* __s390x__ */ #define MACHINE_HAS_IEEE (1)#define MACHINE_HAS_CSP (1)
@@ -89,6 +93,8 @@ extern unsigned long machine_flags;#define MACHINE_HAS_DIAG44 (machine_flags & MACHINE_FLAG_DIAG44)#define MACHINE_HAS_MVPG (1)#define MACHINE_HAS_MVCOS (machine_flags & MACHINE_FLAG_MVCOS) +#define MACHINE_HAS_HPAGE (machine_flags & MACHINE_FLAG_HPAGE) +#define MACHINE_HAS_PFMF (machine_flags & MACHINE_FLAG_PFMF)#endif /* __s390x__ */ #define MACHINE_HAS_SCLP (!MACHINE_IS_P390)
include/asm-s390/tlbflush.h +1 -0
@@ -2,6 +2,7 @@#define _S390_TLBFLUSH_H#include <linux/mm.h> +#include <linux/sched.h> #include <asm/processor.h> #include <asm/pgalloc.h>
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 15/15 Convert to SPARSEMEM & SPARSEMEM_VMEMMAP
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Convert s390 to SPARSEMEM and SPARSEMEM_VMEMMAP. We do a select of SPARSEMEM_VMEMMAP since it is configurable. This is because SPARSEMEM without SPARSEMEM_VMEMMAP gives us a hell of broken include dependencies that I don't want to fix.
---
arch/s390/Kconfig | 8 ++++ arch/s390/mm/extmem.c | 8 ++-- arch/s390/mm/init.c | 2 + arch/s390/mm/vmem.c | 81 +++--------------------------------------- drivers/s390/kvm/kvm_virtio.c | 23 ++++++----- include/asm-s390/page.h | 20 ---------- include/asm-s390/pgtable.h | 9 +--- include/asm-s390/sparsemem.h | 18 +++++++++ 8 files changed, 53 insertions(+), 116 deletions(-)
arch/s390/Kconfig +8 -0
@@ -300,6 +300,14 @@ comment "Kernel preemption" source "kernel/Kconfig.preempt" +config ARCH_SPARSEMEM_ENABLE + def_bool y + select SPARSEMEM_VMEMMAP_ENABLE + select SPARSEMEM_VMEMMAP + +config ARCH_SPARSEMEM_DEFAULT + def_bool y + source "mm/Kconfig" comment "I/O subsystem configuration"
arch/s390/mm/extmem.c +4 -4
@@ -287,7 +287,7 @@ __segment_load (char *name, int do_nonshif (rc <0 ) goto out_free; - rc =add_shared_memory (seg->start_addr, seg->end - seg->start_addr +1 ); + rc =vmem_add_mapping (seg->start_addr, seg->end - seg->start_addr +1 );if (rc) goto out_free;
@@ -351,7 +351,7 @@ __segment_load (char *name, int do_nonshrelease_resource (seg->res);kfree (seg->res); out_shared: -remove_shared_memory (seg->start_addr, seg->end - seg->start_addr +1 ); +vmem_remove_mapping (seg->start_addr, seg->end - seg->start_addr +1 ); out_free:kfree (seg); out:
@@ -474,7 +474,7 @@ segment_modify_shared (char *name, int d rc =0 ; goto out_unlock; out_del: -remove_shared_memory (seg->start_addr, seg->end - seg->start_addr +1 ); +vmem_remove_mapping (seg->start_addr, seg->end - seg->start_addr +1 );list_del (&seg->list);dcss_diag (DCSS_PURGESEG , seg->dcss_name, &dummy, &dummy);kfree (seg);
@@ -508,7 +508,7 @@ segment_unload(char *name) goto out_unlock;release_resource (seg->res);kfree (seg->res); -remove_shared_memory (seg->start_addr, seg->end - seg->start_addr +1 ); +vmem_remove_mapping (seg->start_addr, seg->end - seg->start_addr +1 );list_del (&seg->list);dcss_diag (DCSS_PURGESEG , seg->dcss_name, &dummy, &dummy);kfree (seg);
arch/s390/mm/init.c +2 -0
@@ -106,6 +106,8 @@ void __init paging_init(void)__ctl_load (S390_lowcore.kernel_asce,13 ,13 );__raw_local_irq_ssm (ssm_mask); +sparse_memory_present_with_active_regions (MAX_NUMNODES ); +sparse_init ();memset (max_zone_pfns,0 ,sizeof (max_zone_pfns));#ifdef CONFIG_ZONE_DMA max_zone_pfns[ZONE_DMA ] =PFN_DOWN (MAX_DMA_ADDRESS );
arch/s390/mm/vmem.c +6 -75
139 lines not on this page · raw message
drivers/s390/kvm/kvm_virtio.c +12 -11
@@ -17,6 +17,7 @@#include <linux/virtio_config.h> #include <linux/interrupt.h> #include <linux/virtio_ring.h> +#include <linux/pfn.h> #include <asm/io.h> #include <asm/kvm_para.h> #include <asm/kvm_virtio.h>
@@ -180,11 +181,10 @@ static struct virtqueue *kvm_find_vq(str config =kvm_vq_config (kdev->desc)+index; -if (add_shared_memory (config->address, -vring_size (config->num,PAGE_SIZE ))) { - err = -ENOMEM ; + err =vmem_add_mapping (config->address, +vring_size (config->num,PAGE_SIZE )); +if (err) goto out; - } vq =vring_new_virtqueue (config->num, vdev, (void *) config->address, kvm_notify, callback);
@@ -202,8 +202,8 @@ static struct virtqueue *kvm_find_vq(str vq->priv = config;return vq; unmap: -remove_shared_memory (config->address,vring_size (config->num, -PAGE_SIZE )); +vmem_remove_mapping (config->address, +vring_size (config->num,PAGE_SIZE )); out:return ERR_PTR (err); }
@@ -213,8 +213,8 @@ static void kvm_del_vq(struct virtqueuestruct kvm_vqconfig *config = vq->priv;vring_del_virtqueue (vq); -remove_shared_memory (config->address, -vring_size (config->num,PAGE_SIZE )); +vmem_remove_mapping (config->address, +vring_size (config->num,PAGE_SIZE )); }/*
@@ -318,12 +318,13 @@ static int __init kvm_devices_init(void)return rc; } -if (add_shared_memory ((max_pfn) <<PAGE_SHIFT ,PAGE_SIZE )) { + rc =vmem_add_mapping (PFN_PHYS (max_pfn),PAGE_SIZE ); +if (rc) {device_unregister (&kvm_root); -return -ENOMEM ; +return rc; } - kvm_devices = (void *) (max_pfn <<PAGE_SHIFT ); + kvm_devices = (void *)PFN_PHYS (max_pfn);ctl_set_bit (0 ,9 );register_external_interrupt (0x2603 , kvm_extint_handler);
include/asm-s390/page.h +0 -20
@@ -125,26 +125,6 @@ page_get_storage_key(unsigned long addr) return skey; } -extern unsigned long max_pfn; - -static inline int pfn_valid (unsigned long pfn) -{ -unsigned long dummy; -int ccode; - -if (pfn >= max_pfn) -return 0 ; - - asmvolatile ( -" lra %0,0(%2)\n" -" ipm %1\n" -" srl %1,28\n" - :"=d" (dummy),"=d" (ccode) - :"a" (pfn <<PAGE_SHIFT ) - :"cc" ); -return !ccode; -} -#endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */
include/asm-s390/pgtable.h +3 -6
@@ -129,7 +129,7 @@ extern char empty_zero_page[PAGE_SIZE];#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page))#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES)#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1)) -#define VMEM_MAP ((struct page *) VMALLOC_END) +#define vmemmap ((struct page *) VMALLOC_END)/* * A 31 bit pagetable entry of S390 has following format:
@@ -1075,8 +1075,8 @@ static inline pte_t mk_swap_pte(unsigned#define kern_addr_valid (addr) (1) -extern int add_shared_memory (unsigned long start,unsigned long size); -extern int remove_shared_memory (unsigned long start,unsigned long size); +extern int vmem_add_mapping (unsigned long start,unsigned long size); +extern int vmem_remove_mapping (unsigned long start,unsigned long size);extern int s390_enable_sie (void );/*
@@ -1084,9 +1084,6 @@ extern int s390_enable_sie(void);*/ #define pgtable_cache_init () do { } while (0) -#define __HAVE_ARCH_MEMMAP_INIT -extern void memmap_init (unsigned long ,int ,unsigned long ,unsigned long ); -#include <asm-generic/pgtable.h> #endif /* _S390_PAGE_H */
include/asm-s390/sparsemem.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef _ASM_S390_SPARSEMEM_H +#define _ASM_S390_SPARSEMEM_H + +#define SECTION_SIZE_BITS 25 + +#ifdef CONFIG_64BIT + +#define MAX_PHYSADDR_BITS 42 +#define MAX_PHYSMEM_BITS 42 + +#else + +#define MAX_PHYSADDR_BITS 31 +#define MAX_PHYSMEM_BITS 31 + +#endif /* CONFIG_64BIT */ + +#endif /* _ASM_S390_SPARSEMEM_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.