System z10 patches.
Subsystems (7)
cover System z10 patches.
Greetings,
two weeks ago System z10 has been announced. This patchset adds support for some of the new features of this machine. The two main features are large page support (1MB pages) and cpu topology supporty. There are some common code dependencies for these two, see patches #3, #4, #5, #8 and #9. Most notably we found that we need to add a new tlb flush for the copy-on-write of a large page (patch #8). We think that this is a bug, but obviously one that hasn't shown up so far on any of the other large page architectures.
The patches are queued in the features/for-andrew branches of git390 and will be included linux-next and -mm (keeping fingers crossed that we don't create any rejects).
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/10 Add new fields for System z10 to /proc/sysinfo
From: Martin Schwidefsky <[email protected]>
Add permanent and temporary model capacity and the corresponding capacity value fields for the three capacity identifiers to the output of /proc/sysinfo.
---
drivers/s390/sysinfo.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/s390/sysinfo.c +19 -2
@@ -26,6 +26,11 @@ struct sysinfo_1_1_1 {char sequence[16 ];char plant[4 ];char model[16 ]; +char model_perm_cap[16 ]; +char model_temp_cap[16 ]; +char model_cap_rating[4 ]; +char model_perm_cap_rating[4 ]; +char model_temp_cap_rating[4 ]; };struct sysinfo_1_2_1 {
@@ -133,6 +138,8 @@ static int stsi_1_1_1(struct sysinfo_1_1EBCASC (info->sequence,sizeof (info->sequence));EBCASC (info->plant,sizeof (info->plant));EBCASC (info->model_capacity,sizeof (info->model_capacity)); +EBCASC (info->model_perm_cap,sizeof (info->model_perm_cap)); +EBCASC (info->model_temp_cap,sizeof (info->model_temp_cap)); len +=sprintf (page + len,"Manufacturer: %-16.16s\n" , info->manufacturer); len += sprintf(page + len, "Type: %-4.4s\n",
@@ -155,8 +162,18 @@ static int stsi_1_1_1(struct sysinfo_1_1 info->sequence); len +=sprintf (page + len,"Plant: %-4.4s\n" , info->plant); - len +=sprintf (page + len,"Model Capacity: %-16.16s\n" , - info->model_capacity); + len +=sprintf (page + len,"Model Capacity: %-16.16s %08u\n" , + info->model_capacity, *(u32 *) info->model_cap_rating); +if (info->model_perm_cap[0 ] !='\0' ) + len +=sprintf (page + len, +"Model Perm. Capacity: %-16.16s %08u\n" , + info->model_perm_cap, + *(u32 *) info->model_perm_cap_rating); +if (info->model_temp_cap[0 ] !='\0' ) + len +=sprintf (page + len, +"Model Temp. Capacity: %-16.16s %08u\n" , + info->model_temp_cap, + *(u32 *) info->model_temp_cap_rating);return len; }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [patch 01/10] Add new fields for System z10 to /proc/sysinfo
Quoted 17 lines · Martin Schwidefsky
From: Martin Schwidefsky <[email protected]>
Add permanent and temporary model capacity and the corresponding capacity value fields for the three capacity identifiers to the output of
/proc/sysinfo.Signed-off-by Martin Schwidefsky <[email protected]>---
drivers/s390/sysinfo.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)Index:
quilt-2.6/drivers/s390/sysinfo.c
===================================================================
drivers/s390/sysinfo.c struct sysinfo_1_1_1 { · line 34
Quoted 9 lines
drivers/s390/sysinfo.c +5
-0@@ -26,6 +26,11 @@ struct sysinfo_1_1_1 {char sequence[16 ];char plant[4 ];char model[16 ]; +char model_perm_cap[16 ]; +char model_temp_cap[16 ]; +char model_cap_rating[4 ]; +char model_perm_cap_rating[4 ]; +char model_temp_cap_rating[4 ]; };
I'd try to be safer, and make the struct __attribute__((packed))...
Josef 'Jeff' Sipek.
Signature · 2 lines
I'm somewhere between geek and normal. - Linus Torvalds
Re: [patch 01/10] Add new fields for System z10 to /proc/sysinfo
Quoted 8 lines · Josef 'Jeff' Sipek
Quoted 8 lines
Index:
quilt-2.6/drivers/s390/sysinfo.c
===================================================================drivers/s390/sysinfo.c +0
-0@@ -26,6 +26,11 @@ struct sysinfo_1_1_1 {char sequence[16 ];char plant[4 ];char model[16 ];
Quoted 8 lines
drivers/s390/sysinfo.c struct sysinfo_1_1_1 { · line 34
Quoted 6 lines
drivers/s390/sysinfo.c +5
-0+char model_perm_cap[16 ]; +char model_temp_cap[16 ]; +char model_cap_rating[4 ]; +char model_perm_cap_rating[4 ]; +char model_temp_cap_rating[4 ]; };I'd try to be safer, and make the struct __attribute__((packed))...
Hmm, that would be true for all sysinfo typedefs. The automatic alignment does the right thing though. Don't know if its worth the effort - at least until you get bitten for the first time ;-)
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/10 Export stfle.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Make stfle visible so other code can call this.
---
arch/s390/kernel/setup.c | 11 +++++++++-- include/asm-s390/system.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-)
arch/s390/kernel/setup.c +9 -2
@@ -687,7 +687,7 @@ static __init unsigned int stfl(void)return S390_lowcore.stfl_fac_list; } -static __init int stfle (unsigned long long *list,int doublewords) +static int __init __stfle (unsigned long long *list,int doublewords) {typedef struct {unsigned long long _[doublewords]; }addrtype ; register unsigned long __nr asm("0") = doublewords - 1;
@@ -697,6 +697,13 @@ static __init int stfle(unsigned long loreturn __nr +1 ; } +int __init stfle (unsigned long long *list,int doublewords) +{ +if (!(stfl () & (1UL <<24 ))) +return -EOPNOTSUPP ; +return __stfle (list, doublewords); +} +/* * Setup hardware capabilities. */
@@ -741,7 +748,7 @@ static void __init setup_hwcaps(void)* HWCAP_S390_DFP bit 6. */ if ((elf_hwcap & (1UL <<2 )) && -stfle (&facility_list_extended,1 ) >0 ) { +__stfle (&facility_list_extended,1 ) >0 ) {if (facility_list_extended & (1ULL << (64 -43 ))) elf_hwcap |=1UL <<6 ; }
include/asm-s390/system.h +2 -0
@@ -406,6 +406,8 @@ __set_psw_mask(unsigned long mask)#define local_mcck_enable () __set_psw_mask(psw_kernel_bits)#define local_mcck_disable () __set_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK) +int stfle (unsigned long long *list,int doublewords); +#ifdef CONFIG_SMP extern void smp_ctl_set_bit (int cr,int bit);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/10 sched: add exported arch_reinit_sched_domains() to header file.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Needed so it can be called from outside of sched.c.
---
include/linux/sched.h | 4 ++++ kernel/sched.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
include/linux/sched.h +4 -0
@@ -791,6 +791,10 @@ struct sched_domain {extern void partition_sched_domains (int ndoms_new,cpumask_t *doms_new); +#if defined(CONFIG_SCHED_MC ) || defined(CONFIG_SCHED_SMT ) +extern int arch_reinit_sched_domains (void ); +#endif +#endif /* CONFIG_SMP */ /*
kernel/sched.c +1 -1
@@ -6917,7 +6917,7 @@ match2: }#if defined(CONFIG_SCHED_MC ) || defined(CONFIG_SCHED_SMT ) -static int arch_reinit_sched_domains (void ) +int arch_reinit_sched_domains (void ) {int err;
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Andrew Morton
maintainerRe: [patch 03/10] sched: add exported arch_reinit_sched_domains() to header file.
include/linux/sched.h struct sched_domain { · line 796
Quoted 3 lines · On Wed, 12 Mar 2008 18:31:58 +0100 Martin Schwidefsky <[email protected]>…
include/linux/sched.h +3
-0+#if defined(CONFIG_SCHED_MC ) || defined(CONFIG_SCHED_SMT ) +extern int arch_reinit_sched_domains (void ); +#endif
I tend to recommend that the ifdefs be omitted here.
It has the downside that the build will then fail at link-time rather than at compile-time, but I haven't seen anyone complain about that.
Re: [patch 03/10] sched: add exported arch_reinit_sched_domains() to header file.
Quoted 8 lines · Andrew Morton
include/linux/sched.h struct sched_domain { · line 796
Quoted 3 lines
include/linux/sched.h +3
-0+#if defined(CONFIG_SCHED_MC ) || defined(CONFIG_SCHED_SMT ) +extern int arch_reinit_sched_domains (void ); +#endif I tend to recommend that the ifdefs be omitted here.
It has the downside that the build will then fail at link-time rather than at compile-time, but I haven't seen anyone complain about that.
Ok, I've removed the #if.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Ingo Molnar
AppliedRe: [patch 03/10] sched: add exported arch_reinit_sched_domains() to header file.
In reply to Martin SchwidefskyQuoted 1 line · Martin Schwidefsky
Needed so it can be called from outside of
sched.c.
thanks, applied.
include/linux/sched.h struct sched_domain { · line 796
Quoted 3 lines
include/linux/sched.h +3
-0+#if defined(CONFIG_SCHED_MC ) || defined(CONFIG_SCHED_SMT ) +extern int arch_reinit_sched_domains (void ); +#endif
i removed the #ifdefs around this.
Ingo
PATCH 4/10 sched: Add arch_update_cpu_topology hook.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Will be called each time the scheduling domains are rebuild. Needed for architectures that don't have a static cpu topology.
---
include/linux/topology.h | 2 ++ kernel/sched.c | 5 +++++ 2 files changed, 7 insertions(+)
include/linux/topology.h +2 -0
@@ -50,6 +50,8 @@ for_each_online_node(node) \ if (nr_cpus_node(node)) +void arch_update_cpu_topology(void); +/* Conform to ACPI 2.0 SLIT distance definitions */ #define LOCAL_DISTANCE 10#define REMOTE_DISTANCE 20
kernel/sched.c +5 -0
@@ -6804,6 +6804,10 @@ static int ndoms_cur; /* number of sche*/ static cpumask_t fallback_doms; +void __attribute__((weak))arch_update_cpu_topology (void ) +{ +} +/* * Set up scheduler domains and groups. Callers must hold the hotplug lock. * For now this just excludes isolated cpus, but could be used to
@@ -6813,6 +6817,7 @@ static int arch_init_sched_domains(const {int err; +arch_update_cpu_topology (); ndoms_cur =1 ; doms_cur =kmalloc (sizeof (cpumask_t),GFP_KERNEL );if (!doms_cur)
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Ingo Molnar
AppliedRe: [patch 04/10] sched: Add arch_update_cpu_topology hook.
Quoted 2 lines · Martin Schwidefsky
Will be called each time the scheduling domains are rebuild. Needed for architectures that don't have a static cpu topology.
thanks, applied.
Ingo
PATCH 5/10 cpu topology: convert siblings_show macro to accept non-lvalues.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
The sibling cpu masks on s390 can change because of dynamic cpu reconfiguration. Therefore accesses to these masks are protected with a lock so there aren't concurrent read and write accesses at the same time. cpumask_scnprint in define_siblings_show_func expects an lvalue for the cpu mask which would make the locking down in the s390 arch code pointless. To solve this change the topology code to save a snapshot of the sibling cpu mask and use that for output purposes.
---
drivers/base/topology.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/base/topology.c +10 -7
@@ -40,13 +40,16 @@ static ssize_t show_##name(struct sys_de return sprintf(buf, "%d\n", topology_##name(cpu)); \ } -#define define_siblings_show_func (name) \ -static ssize_t show_##name(struct sys_device *dev, char *buf) \ -{ \ - ssize_t len = -1; \ - unsigned int cpu = dev->id; \ - len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu)); \ - return (len + sprintf(buf + len, "\n")); \ +#define define_siblings_show_func (name) \ +static ssize_t show_##name(struct sys_device *dev, char *buf) \ +{ \ + ssize_t len = -1; \ + unsigned int cpu = dev->id; \ + cpumask_t mask; \ + \ + mask = topology_##name(cpu); \ + len = cpumask_scnprintf(buf, NR_CPUS + 1, mask); \ + return len + sprintf(buf + len, "\n"); \ }#ifdef topology_physical_package_id
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/10 cpu topology support for s390.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Add s390 backend so we can give the scheduler some hints about the cpu topology.
---
arch/s390/Kconfig | 4 arch/s390/defconfig | 1 arch/s390/kernel/Makefile | 2 arch/s390/kernel/setup.c | 2 arch/s390/kernel/smp.c | 4 arch/s390/kernel/topology.c | 271 ++++++++++++++++++++++++++++++++++++++++++++ drivers/s390/sysinfo.c | 2 include/asm-s390/smp.h | 2 include/asm-s390/system.h | 1 include/asm-s390/topology.h | 16 ++ 10 files changed, 300 insertions(+), 5 deletions(-)
arch/s390/defconfig +1 -0
@@ -3,6 +3,7 @@ # Linux kernel version: 2.6.25-rc5 # Wed Mar 12 14:10:52 2008 # +CONFIG_SCHED_MC=y CONFIG_MMU=y CONFIG_ZONE_DMA=y CONFIG_LOCKDEP_SUPPORT=y
arch/s390/Kconfig +4 -0
@@ -3,6 +3,10 @@ # see Documentation/kbuild/kconfig-language.txt. # +config SCHED_MC + def_bool y + depends on SMP + config MMU def_bool y
arch/s390/kernel/Makefile +1 -1
@@ -19,7 +19,7 @@ obj-y += $(if $(CONFIG_64BIT),reipl64.o, extra-y += head.o init_task.o vmlinux.lds obj-$(CONFIG_MODULES) += s390_ksyms.o module.o -obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SMP) += smp.o topology.o obj-$(CONFIG_AUDIT) += audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o
arch/s390/kernel/setup.c +2 -0
@@ -39,6 +39,7 @@#include <linux/pfn.h> #include <linux/ctype.h> #include <linux/reboot.h> +#include <linux/topology.h> #include <asm/ipl.h> #include <asm/uaccess.h>
@@ -830,6 +831,7 @@ setup_arch(char **cmdline_p)cpu_init (); __cpu_logical_map[0 ] = S390_lowcore.cpu_data.cpu_addr; +s390_init_cpu_topology ();/* * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).
arch/s390/kernel/smp.c +1 -3
@@ -67,9 +67,7 @@ enum s390_cpu_state {CPU_STATE_CONFIGURED , }; -#ifdef CONFIG_HOTPLUG_CPU -static DEFINE_MUTEX (smp_cpu_state_mutex); -#endif +DEFINE_MUTEX (smp_cpu_state_mutex);static int smp_cpu_state[NR_CPUS ]; static DEFINE_PER_CPU(struct cpu, cpu_devices);
arch/s390/kernel/topology.c new file +271 -0
271 lines not on this page · raw message
drivers/s390/sysinfo.c +1 -1
@@ -105,7 +105,7 @@ struct sysinfo_3_2_2 { } vm[8 ]; }; -static inline int stsi (void *sysinfo,int fc,int sel1,int sel2) +int stsi (void *sysinfo,int fc,int sel1,int sel2) { register int r0 asm("0") = (fc << 28) | sel1; register int r1 asm("1") = sel2;
include/asm-s390/smp.h +2 -0
@@ -90,6 +90,8 @@ extern void __cpu_die (unsigned int cpu)extern void cpu_die (void ) __attribute__ ((noreturn));extern int __cpu_up (unsigned int cpu); +extern struct mutex smp_cpu_state_mutex; +extern int smp_call_function_mask (cpumask_t mask,void (*func)(void *),void *info,int wait);#endif
include/asm-s390/system.h +1 -0
@@ -406,6 +406,7 @@ __set_psw_mask(unsigned long mask)#define local_mcck_enable () __set_psw_mask(psw_kernel_bits)#define local_mcck_disable () __set_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK) +int stsi (void *sysinfo,int fc,int sel1,int sel2);int stfle (unsigned long long *list,int doublewords);#ifdef CONFIG_SMP
include/asm-s390/topology.h +16 -0
@@ -1,6 +1,22 @@#ifndef _ASM_S390_TOPOLOGY_H#define _ASM_S390_TOPOLOGY_H +#include <linux/cpumask.h> + +#define mc_capable () (1) + +cpumask_t cpu_coregroup_map (unsigned int cpu); + +#define topology_core_siblings (cpu) (cpu_coregroup_map(cpu)) + +#ifdef CONFIG_SMP +void s390_init_cpu_topology (void ); +#else +static inline void s390_init_cpu_topology (void ) +{ +}; +#endif +#include <asm-generic/topology.h> #endif /* _ASM_S390_TOPOLOGY_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Andrew Morton
maintainerRe: [patch 06/10] cpu topology support for s390.
Quoted 25 lines · On Wed, 12 Mar 2008 18:32:01 +0100 Martin Schwidefsky <[email protected]>…
From: Heiko Carstens <[email protected]>
Add s390 backend so we can give the scheduler some hints about the cpu topology.
===================================================================
arch/s390/kernel/topology.c new file +16
-0@@ -0,0 +1,271 @@ +/* +* arch/s390/kernel/topology.c +* +* Copyright IBM Corp. 2007 +* Author(s): Heiko Carstens <[email protected]> +*/ + +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/bootmem.h> +#include <linux/sched.h> +#include <linux/workqueue.h> +#include <linux/cpu.h> +#include <linux/smp.h>
arch/s390/kernel/topology.c line 26
Quoted 10 lines
arch/s390/kernel/topology.c new file +10
-0+#include <asm/delay.h> +#include <asm/s390_ext.h> + +#define CPU_BITS 64 + +struct tl_cpu { +unsigned char reserved[6 ]; +unsigned short origin; +unsigned long mask[CPU_BITS /BITS_PER_LONG ]; +};
mask[] will be too small for CPU_BITS=65 ;)
arch/s390/kernel/topology.c line 120
Quoted 9 lines
...
arch/s390/kernel/topology.c new file +7
-0+static union tl_entry *next_tle (union tl_entry *tle) +{ +if (tle->nl) +return (union tl_entry *)((struct tl_container *)tle +1 ); +else +return (union tl_entry *)((struct tl_cpu *)tle +1 ); +}
omg.
arch/s390/kernel/topology.c line 129
Quoted 8 lines
arch/s390/kernel/topology.c new file +8
-0+static void tl_to_cores (struct tl_info *info) +{ +union tl_entry *tle, *end; +struct core_info *core = &core_info; + +mutex_lock (&smp_cpu_state_mutex); +clear_cores (); + tle = (union tl_entry *)&info->tle;
and this cast was unneeded!
arch/s390/kernel/topology.c line 130
Quoted 1 line
arch/s390/kernel/topology.c new file +1
-0+ end = (union tl_entry *)((unsigned long )info + info->length);
I'd suggest that you take a look at all the pointer arith games which are being played in this code and see if it can be done better with a more appropriate use of the C type system. Before someone dies.
Re: [patch 06/10] cpu topology support for s390.
Quoted 4 lines · Andrew Morton
Quoted 4 lines
arch/s390/kernel/topology.c new file +4
-0+#include <asm/delay.h> +#include <asm/s390_ext.h> + +#define CPU_BITS 64
Quoted 8 lines
arch/s390/kernel/topology.c line 26
Quoted 6 lines
arch/s390/kernel/topology.c new file +6
-0+ +struct tl_cpu { +unsigned char reserved[6 ]; +unsigned short origin; +unsigned long mask[CPU_BITS /BITS_PER_LONG ]; +};mask[] will be too small for CPU_BITS=65 ;)
We could add the +(BITS_PER_LONG - 1) logic but what for? The CPU_BITS is defined right above and it will be increased in steps of 64.
Quoted 11 lines
arch/s390/kernel/topology.c line 120
Quoted 9 lines
...
arch/s390/kernel/topology.c new file +7
-0+static union tl_entry *next_tle (union tl_entry *tle) +{ +if (tle->nl) +return (union tl_entry *)((struct tl_container *)tle +1 ); +else +return (union tl_entry *)((struct tl_cpu *)tle +1 ); +}omg.
The length of the current tle depends on the type, the next type is located behind the current one. Expect for the typecasting and the union trick this is what needs to be done.
Quoted 11 lines
arch/s390/kernel/topology.c line 129
Quoted 8 lines
arch/s390/kernel/topology.c new file +8
-0+static void tl_to_cores (struct tl_info *info) +{ +union tl_entry *tle, *end; +struct core_info *core = &core_info; + +mutex_lock (&smp_cpu_state_mutex); +clear_cores (); + tle = (union tl_entry *)&info->tle;and this cast was unneeded!
Quoted 5 lines
arch/s390/kernel/topology.c line 130
Quoted 1 line
arch/s390/kernel/topology.c new file +1
-0+ end = (union tl_entry *)((unsigned long )info + info->length);I'd suggest that you take a look at all the pointer arith games which are being played in this code and see if it can be done better with a more appropriate use of the C type system. Before someone dies.
The only thing that I can see that we could do is to get rid of the unions and do the pointer arithmetic with the tl_cpu / tl_container structs by hand. The data stored by ptf is structured in a way that makes it rather hard to write decent C code.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [patch 06/10] cpu topology support for s390.
Quoted 11 lines · Martin Schwidefsky
Quoted 9 lines · Andrew Morton
arch/s390/kernel/topology.c line 26
Quoted 7 lines
arch/s390/kernel/topology.c new file +7
-0+#define CPU_BITS 64 + +struct tl_cpu { +unsigned char reserved[6 ]; +unsigned short origin; +unsigned long mask[CPU_BITS /BITS_PER_LONG ]; +};mask[] will be too small for CPU_BITS=65 ;)
Quoted 2 lines
We could add the +(BITS_PER_LONG - 1) logic but what for? The
CPU_BITSis defined right above and it will be increased in steps of 64.
It will always be 64 and won't be increased. For more than 64 cpus "origin" in the hardware structure above will be > 0 and each bit in the mask would represent cpu "origin + bit number".
Quoted 10 lines
Quoted 5 lines
arch/s390/kernel/topology.c line 130
Quoted 1 line
arch/s390/kernel/topology.c new file +1
-0+ end = (union tl_entry *)((unsigned long )info + info->length);I'd suggest that you take a look at all the pointer arith games which are being played in this code and see if it can be done better with a more appropriate use of the C type system. Before someone dies.
The only thing that I can see that we could do is to get rid of the unions and do the pointer arithmetic with the
tl_cpu/tl_containerstructs by hand. The data stored by ptf is structured in a way that makes it rather hard to write decent C code.
Please leave as is. I did have a few different implementations but they all looked even worse than this one. If you read the hardware specs then the current code should be rather easily understandable.
And since the whole documentation is publically availabe in the meantime I could even add some comments ;)
PATCH 7/10 Vertical cpu management.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
---
arch/s390/kernel/smp.c | 83 ++++++++++++++++++++++++++++++++++++++++++-- arch/s390/kernel/topology.c | 66 +++++++++++++++++++++++++++++----- include/asm-s390/smp.h | 1 include/asm-s390/topology.h | 9 ++++ 4 files changed, 146 insertions(+), 13 deletions(-)
arch/s390/kernel/smp.c +81 -2
@@ -68,7 +68,9 @@ enum s390_cpu_state { };DEFINE_MUTEX (smp_cpu_state_mutex); +int smp_cpu_polarization[NR_CPUS ];static int smp_cpu_state[NR_CPUS ]; +static int cpu_management; static DEFINE_PER_CPU(struct cpu, cpu_devices);DEFINE_PER_CPU (struct s390_idle_data , s390_idle);
@@ -454,6 +456,7 @@ static int smp_rescan_cpus_sigp(cpumask_if (cpu_known (cpu_id))continue ; __cpu_logical_map[logical_cpu] = cpu_id; + smp_cpu_polarization[logical_cpu] =POLARIZATION_UNKNWN ;if (!cpu_stopped (logical_cpu))continue ;cpu_set (logical_cpu, cpu_present_map);
@@ -487,6 +490,7 @@ static int smp_rescan_cpus_sclp(cpumask_if (cpu_known (cpu_id))continue ; __cpu_logical_map[logical_cpu] = cpu_id; + smp_cpu_polarization[logical_cpu] =POLARIZATION_UNKNWN ;cpu_set (logical_cpu, cpu_present_map);if (cpu >= info->configured) smp_cpu_state[logical_cpu] =CPU_STATE_STANDBY ;
@@ -844,6 +848,7 @@ void __init smp_prepare_boot_cpu(void) S390_lowcore.percpu_offset = __per_cpu_offset[0 ]; current_set[0 ] = current; smp_cpu_state[0 ] =CPU_STATE_CONFIGURED ; + smp_cpu_polarization[0 ] =POLARIZATION_UNKNWN ;spin_lock_init (&(&__get_cpu_var (s390_idle))->lock); }
@@ -895,15 +900,19 @@ static ssize_t cpu_configure_store(struccase 0 :if (smp_cpu_state[cpu] ==CPU_STATE_CONFIGURED ) { rc =sclp_cpu_deconfigure (__cpu_logical_map[cpu]); -if (!rc) +if (!rc) { smp_cpu_state[cpu] =CPU_STATE_STANDBY ; + smp_cpu_polarization[cpu] =POLARIZATION_UNKNWN ; + } }break ;case 1 :if (smp_cpu_state[cpu] ==CPU_STATE_STANDBY ) { rc =sclp_cpu_configure (__cpu_logical_map[cpu]); -if (!rc) +if (!rc) { smp_cpu_state[cpu] =CPU_STATE_CONFIGURED ; + smp_cpu_polarization[cpu] =POLARIZATION_UNKNWN ; + } }break ;default :
@@ -917,6 +926,34 @@ out: static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);#endif /* CONFIG_HOTPLUG_CPU */ +static ssize_t cpu_polarization_show (struct sys_device *dev,char *buf) +{ +int cpu = dev->id; +ssize_t count; + +mutex_lock (&smp_cpu_state_mutex); +switch (smp_cpu_polarization[cpu]) { +case POLARIZATION_HRZ : + count =sprintf (buf,"horizontal\n" ); +break ; +case POLARIZATION_VL : + count =sprintf (buf,"vertical:low\n" ); +break ; +case POLARIZATION_VM : + count =sprintf (buf,"vertical:medium\n" ); +break ; +case POLARIZATION_VH : + count =sprintf (buf,"vertical:high\n" ); +break ; +default : + count =sprintf (buf,"unknown\n" ); +break ; + } +mutex_unlock (&smp_cpu_state_mutex); +return count; +} +static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL); +static ssize_t show_cpu_address (struct sys_device *dev,char *buf) {return sprintf (buf,"%d\n" , __cpu_logical_map[dev->id]);
@@ -929,6 +966,7 @@ static struct attribute *cpu_common_attr &attr_configure.attr, #endif &attr_address.attr, + &attr_polarization.attr, NULL, };
@@ -1073,11 +1111,48 @@ static ssize_t __ref rescan_store(struct out:put_online_cpus ();mutex_unlock (&smp_cpu_state_mutex); +if (!cpus_empty (newcpus)) +topology_schedule_update ();return rc ? rc : count; } static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);#endif /* CONFIG_HOTPLUG_CPU */ +static ssize_t dispatching_show (struct sys_device *dev,char *buf) +{ +ssize_t count; + +mutex_lock (&smp_cpu_state_mutex); + count =sprintf (buf,"%d\n" , cpu_management); +mutex_unlock (&smp_cpu_state_mutex); +return count; +} + +static ssize_t dispatching_store (struct sys_device *dev,const char *buf, +size_t count) +{ +int val, rc; +char delim; + +if (sscanf (buf,"%d %c" , &val, &delim) !=1 ) +return -EINVAL ; +if (val !=0 && val !=1 ) +return -EINVAL ; + rc =0 ; +mutex_lock (&smp_cpu_state_mutex); +get_online_cpus (); +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); +return rc ? rc : count; +} +static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store); +static int __init topology_init (void ) {int cpu;
@@ -1091,6 +1166,10 @@ static int __init topology_init(void)if (rc)return rc;#endif + rc =sysfs_create_file (&cpu_sysdev_class.kset.kobj, + &attr_dispatching.attr); +if (rc) +return rc;for_each_present_cpu (cpu) { rc =smp_add_present_cpu (cpu);if (rc)
arch/s390/kernel/topology.c +55 -11
121 lines not on this page · raw message
include/asm-s390/smp.h +1 -0
@@ -91,6 +91,7 @@ extern void cpu_die (void) __attribute__extern int __cpu_up (unsigned int cpu);extern struct mutex smp_cpu_state_mutex; +extern int smp_cpu_polarization[];extern int smp_call_function_mask (cpumask_t mask,void (*func)(void *),void *info,int wait);
include/asm-s390/topology.h +9 -0
@@ -9,6 +9,15 @@ cpumask_t cpu_coregroup_map(unsigned int#define topology_core_siblings (cpu) (cpu_coregroup_map(cpu)) +int topology_set_cpu_management (int fc); +void topology_schedule_update (void ); + +#define POLARIZATION_UNKNWN (-1) +#define POLARIZATION_HRZ (0) +#define POLARIZATION_VL (1) +#define POLARIZATION_VM (2) +#define POLARIZATION_VH (3) +#ifdef CONFIG_SMP void s390_init_cpu_topology (void );#else
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/10 Add missing TLB flush to hugetlb_cow().
In reply to Martin SchwidefskyFrom: Gerald Schaefer <[email protected]>
A cow break on a hugetlbfs page with page_count > 1 will set a new pte with set_huge_pte_at(), w/o any tlb flush operation. The old pte will remain in the tlb and subsequent write access to the page will result in a page fault loop, for as long as it may take until the tlb is flushed from somewhere else.
This patch introduces an architecture-specific huge_ptep_clear_flush() function, which is called before the the set_huge_pte_at() in hugetlb_cow().
---
include/linux/hugetlb.h | 4 ++++ mm/hugetlb.c | 1 + 2 files changed, 5 insertions(+)
include/linux/hugetlb.h +4 -0
@@ -80,6 +80,10 @@ static inline int prepare_hugepage_rangeint prepare_hugepage_range (unsigned long addr,unsigned long len);#endif +#ifndef ARCH_HAS_HUGEPAGE_CLEAR_FLUSH +#define huge_ptep_clear_flush (vma, addr, ptep) do { } while (0) +#endif +#ifndef ARCH_HAS_SETCLEAR_HUGE_PTE #define set_huge_pte_at (mm, addr, ptep, pte) set_pte_at(mm, addr, ptep, pte)#define huge_ptep_get_and_clear (mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep)
mm/hugetlb.c +1 -0
@@ -864,6 +864,7 @@ static int hugetlb_cow(struct mm_struct ptep =huge_pte_offset (mm, address &HPAGE_MASK );if (likely (pte_same (*ptep, pte))) {/* Break COW */ +huge_ptep_clear_flush (vma, address, ptep);set_huge_pte_at (mm, address, ptep,make_huge_pte (vma, new_page,1 ));/* Make the old page be freed below */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/10 Hugetlb common code update for System z.
In reply to Martin SchwidefskyFrom: Gerald Schaefer <[email protected]>
Huge ptes have a special type on s390 and cannot be handled with the standard pte functions in certain cases. This patch adds some new architecture-specific definitions and functions to hugetlb common code, as a prerequisite for the System z large page support. They won't affect other architectures.
---
include/linux/hugetlb.h | 18 ++++++++++++++++++ mm/hugetlb.c | 36 +++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 15 deletions(-)
include/linux/hugetlb.h +18 -0
@@ -80,6 +80,24 @@ static inline int prepare_hugepage_rangeint prepare_hugepage_range (unsigned long addr,unsigned long len);#endif +#ifndef ARCH_HAS_HUGE_PTE_TYPE +#define huge_pte_none (pte) pte_none(pte) +#define huge_pte_wrprotect (pte) pte_wrprotect(pte) +#define huge_ptep_set_wrprotect (mm, addr, ptep) \ + ptep_set_wrprotect(mm, addr, ptep) +#define huge_ptep_set_access_flags (vma, addr, ptep, pte, dirty) \ + ptep_set_access_flags(vma, addr, ptep, pte, dirty) +#define huge_ptep_get (ptep) (*ptep) +#endif + +#ifndef ARCH_HAS_PREPARE_HUGEPAGE +#define arch_prepare_hugepage (page) 0 +#define arch_release_hugepage (page) do { } while (0) +#else +int arch_prepare_hugepage (struct page *page); +void arch_release_hugepage (struct page *page); +#endif +#ifndef ARCH_HAS_HUGEPAGE_CLEAR_FLUSH #define huge_ptep_clear_flush (vma, addr, ptep) do { } while (0)#endif
mm/hugetlb.c +21 -15
@@ -129,6 +129,7 @@ static void update_and_free_page(struct }set_compound_page_dtor (page,NULL );set_page_refcounted (page); +arch_release_hugepage (page);__free_pages (page,HUGETLB_PAGE_ORDER ); }
@@ -198,6 +199,10 @@ static struct page *alloc_fresh_huge_pag htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE|__GFP_NOWARN, HUGETLB_PAGE_ORDER);if (page) { +if (arch_prepare_hugepage (page)) { +__free_pages (page,HUGETLB_PAGE_ORDER ); +return 0 ; + }set_compound_page_dtor (page, free_huge_page);spin_lock (&hugetlb_lock); nr_huge_pages++;
@@ -707,7 +712,7 @@ static pte_t make_huge_pte(struct vm_are entry =pte_mkwrite (pte_mkdirty (mk_pte (page, vma->vm_page_prot))); }else { - entry =pte_wrprotect (mk_pte (page, vma->vm_page_prot)); + entry =huge_pte_wrprotect (mk_pte (page, vma->vm_page_prot)); } entry =pte_mkyoung (entry); entry =pte_mkhuge (entry);
@@ -720,8 +725,8 @@ static void set_huge_ptep_writable(struc {pte_t entry; - entry =pte_mkwrite (pte_mkdirty (*ptep)); -if (ptep_set_access_flags (vma, address, ptep, entry,1 )) { + entry =pte_mkwrite (pte_mkdirty (huge_ptep_get (ptep))); +if (huge_ptep_set_access_flags (vma, address, ptep, entry,1 )) {update_mmu_cache (vma, address, entry); } }
@@ -751,10 +756,10 @@ int copy_hugetlb_page_range(struct mm_stspin_lock (&dst->page_table_lock);spin_lock (&src->page_table_lock); -if (!pte_none (*src_pte)) { +if (!huge_pte_none (huge_ptep_get (src_pte))) {if (cow) -ptep_set_wrprotect (src, addr, src_pte); - entry = *src_pte; +huge_ptep_set_wrprotect (src, addr, src_pte); + entry =huge_ptep_get (src_pte); ptepage =pte_page (entry);get_page (ptepage);set_huge_pte_at (dst, addr, dst_pte, entry);
@@ -798,7 +803,7 @@ void __unmap_hugepage_range(struct vm_arcontinue ; pte =huge_ptep_get_and_clear (mm, address, ptep); -if (pte_none (pte)) +if (huge_pte_none (pte))continue ; page =pte_page (pte);
@@ -862,7 +867,7 @@ static int hugetlb_cow(struct mm_structspin_lock (&mm->page_table_lock); ptep =huge_pte_offset (mm, address &HPAGE_MASK ); -if (likely (pte_same (*ptep, pte))) { +if (likely (pte_same (huge_ptep_get (ptep), pte))) {/* Break COW */ huge_ptep_clear_flush (vma, address, ptep); set_huge_pte_at(mm, address, ptep,
@@ -932,7 +937,7 @@ retry: goto backout; ret =0 ; -if (!pte_none (*ptep)) +if (!huge_pte_none (huge_ptep_get (ptep))) goto backout; new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE)
@@ -974,8 +979,8 @@ int hugetlb_fault(struct mm_struct *mm,* the same page in the page cache. */ mutex_lock (&hugetlb_instantiation_mutex); - entry = *ptep; -if (pte_none (entry)) { + entry =huge_ptep_get (ptep); +if (huge_pte_none (entry)) { ret =hugetlb_no_page (mm, vma, address, ptep, write_access);mutex_unlock (&hugetlb_instantiation_mutex);return ret;
@@ -985,7 +990,7 @@ int hugetlb_fault(struct mm_struct *mm,spin_lock (&mm->page_table_lock);/* Check for a racing update before calling hugetlb_cow */ -if (likely (pte_same (entry, *ptep))) +if (likely (pte_same (entry,huge_ptep_get (ptep))))if (write_access && !pte_write (entry)) ret =hugetlb_cow (mm, vma, address, ptep, entry);spin_unlock (&mm->page_table_lock);
@@ -1015,7 +1020,8 @@ int follow_hugetlb_page(struct mm_struct*/ pte =huge_pte_offset (mm, vaddr &HPAGE_MASK ); -if (!pte ||pte_none (*pte) || (write && !pte_write (*pte))) { +if (!pte ||huge_pte_none (huge_ptep_get (pte)) || + (write && !pte_write (huge_ptep_get (pte)))) {int ret;spin_unlock (&mm->page_table_lock);
@@ -1031,7 +1037,7 @@ int follow_hugetlb_page(struct mm_struct } pfn_offset = (vaddr & ~HPAGE_MASK ) >>PAGE_SHIFT ; - page =pte_page (*pte); + page =pte_page (huge_ptep_get (pte)); same_page:if (pages) {get_page (page);
@@ -1080,7 +1086,7 @@ void hugetlb_change_protection(struct vmcontinue ;if (huge_pmd_unshare (mm, &address, ptep))continue ; -if (!pte_none (*ptep)) { +if (!huge_pte_none (huge_ptep_get (ptep))) { pte =huge_ptep_get_and_clear (mm, address, ptep); pte =pte_mkhuge (pte_modify (pte, newprot));set_huge_pte_at (mm, address, ptep, pte);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [patch 09/10] Hugetlb common code update for System z.
include/linux/hugetlb.h static inline int prepare_hugepage_range · line 93
Quoted 11 lines · Martin Schwidefsky
include/linux/hugetlb.h +11
-0+#ifndef ARCH_HAS_HUGE_PTE_TYPE +#define huge_pte_none (pte) pte_none(pte) +#define huge_pte_wrprotect (pte) pte_wrprotect(pte) +#define huge_ptep_set_wrprotect (mm, addr, ptep) \ + ptep_set_wrprotect(mm, addr, ptep) +#define huge_ptep_set_access_flags (vma, addr, ptep, pte, dirty) \ + ptep_set_access_flags(vma, addr, ptep, pte, dirty) +#define huge_ptep_get (ptep) (*ptep) +#endif + +#ifndef ARCH_HAS_PREPARE_HUGEPAGE
Can you guys please do these defines in Kconfig instead of headers? I find them much easier to track down when I have one place to look, rather than a mess of 14 other #includes in a arch-specific header. :)
I'm also a little concerned that you just #ifdef'd in about 44 new ptep functions in here. Have you carefully considered doing this in a way that would fit in better with the other architectures?
Quoted 2 lines
Huge ptes have a special type on s390 and cannot be handled with the standard pte functions in certain cases.
Can you elaborate a bit more on that?
-- Dave
Re: [patch 09/10] Hugetlb common code update for System z.
Quoted 7 lines · Dave Hansen
Quoted 7 lines
include/linux/hugetlb.h +7
-0+#ifndef ARCH_HAS_HUGE_PTE_TYPE +#define huge_pte_none (pte) pte_none(pte) +#define huge_pte_wrprotect (pte) pte_wrprotect(pte) +#define huge_ptep_set_wrprotect (mm, addr, ptep) \ + ptep_set_wrprotect(mm, addr, ptep) +#define huge_ptep_set_access_flags (vma, addr, ptep, pte, dirty) \ + ptep_set_access_flags(vma, addr, ptep, pte, dirty)
Quoted 8 lines
include/linux/hugetlb.h static inline int prepare_hugepage_range · line 93
Quoted 4 lines
include/linux/hugetlb.h +4
-0+#define huge_ptep_get (ptep) (*ptep) +#endif + +#ifndef ARCH_HAS_PREPARE_HUGEPAGE Can you guys please do these defines in
Kconfiginstead of headers? I find them much easier to track down when I have one place to look, rather than a mess of 14 other #includes in a arch-specific header. :)
There are already several ARCH_HAS_xxx defines which are being used in inlude/linux/hugetlb.h. All of them are defined in include/asm-<arch>/page.h for every architecture that needs them (with the exception of powerpc, where it is include/asm-powerpc/page_64.h). So there is already one place to look for them, and so we put our defines into include/asm-s390/page.h.
Quoted 3 lines
I'm also a little concerned that you just #ifdef'd in about 44 new ptep functions in here. Have you carefully considered doing this in a way that would fit in better with the other architectures?
Other architectures should not be affected at all. Because of the #ifdef, the new ptep functions are either a nop for them or just the same as they were before our patch.
Quoted 4 lines
Quoted 2 lines
Huge ptes have a special type on s390 and cannot be handled with the standard pte functions in certain cases.
Can you elaborate a bit more on that?
Large ptes are not really ptes but segment table entries (pmd entries), in our case. This is similar to other architectures with hardware large page support, because there simply is no page table level (and thus no ptes) anymore. Unfortunately, the hugetlbfs common code does not consider that discrepancy and just uses a standard pte_t and standard pte functions, probably because it did not really make a difference on other architectures.
On s390, a segment table entry (pmd) type is different from a pte type mainly in the location of its invalid bit. This means that we cannot use pte_none(), pte_wrprotect() and similar functions for large ptes, which was the reason for the new huge_pte functions that we introduced.
--
Gerald Schaefer
Andrew Morton
maintainerRe: [patch 09/10] Hugetlb common code update for System z.
Quoted 17 lines · On Thu, 13 Mar 2008 00:18:57 +0100 Gerald Schaefer…
Quoted 7 lines · Dave Hansen
Quoted 7 lines
include/linux/hugetlb.h +7
-0+#ifndef ARCH_HAS_HUGE_PTE_TYPE +#define huge_pte_none (pte) pte_none(pte) +#define huge_pte_wrprotect (pte) pte_wrprotect(pte) +#define huge_ptep_set_wrprotect (mm, addr, ptep) \ + ptep_set_wrprotect(mm, addr, ptep) +#define huge_ptep_set_access_flags (vma, addr, ptep, pte, dirty) \ + ptep_set_access_flags(vma, addr, ptep, pte, dirty)Quoted 8 lines
include/linux/hugetlb.h static inline int prepare_hugepage_range · line 93
Quoted 4 lines
include/linux/hugetlb.h +4
-0+#define huge_ptep_get (ptep) (*ptep) +#endif + +#ifndef ARCH_HAS_PREPARE_HUGEPAGE Can you guys please do these defines in
Kconfiginstead of headers? I find them much easier to track down when I have one place to look, rather than a mess of 14 other #includes in a arch-specific header. :)
Quoted 4 lines
There are already several
ARCH_HAS_xxxdefines which are being used ininlude/linux/hugetlb.h. All of them are defined in include/asm-<arch>/page.h for every architecture that needs them (with the exception of powerpc, where it isinclude/asm-powerpc/page_64.h).
Yes, but that's fugly and it would be better to put in place the infrastructure for cleaning it up, rather than worsening it.
So...
Put this:
+#define huge_pte_none(pte) pte_none(pte)
+#define huge_pte_wrprotect(pte) pte_wrprotect(pte)
+#define huge_ptep_set_wrprotect(mm, addr, ptep) \
+ ptep_set_wrprotect(mm, addr, ptep)
+#define huge_ptep_set_access_flags(vma, addr, ptep, pte, dirty) \
+ ptep_set_access_flags(vma, addr, ptep, pte, dirty)
+#define huge_ptep_get(ptep) (*ptep)
into include/asm-generic/hugetlb.h
then for each architecture except s390 add an include/asm-foo/hugetlb.h which does
#include <asm-generic/hugetlb.h>
then in include/linux/hugetlb.h add
#include <asm/hugetlb.h>
and then in include/asm-s390/hugetlb.h, add your s390-specific versions of huge_pte_none() and friends.
later, someone can hopefully use this new infrastructure to rid us of ARCH_HAS_HUGEPAGE_ONLY_RANGE, ARCH_HAS_HUGETLB_FREE_PGD_RANGE, ARCH_HAS_PREPARE_HUGEPAGE_RANGE, ARCH_HAS_SETCLEAR_HUGE_PTE and ARCH_HAS_HUGETLB_PREFAULT_HOOK.
Re: [patch 09/10] Hugetlb common code update for System z.
Quoted 4 lines · Andrew Morton
Yes, but that's fugly and it would be better to put in place the infrastructure for cleaning it up, rather than worsening it.
So...
OK, we'll start the clean-up, thanks for the detailed suggestions.
--
Gerald Schaefer
Re: [patch 09/10] Hugetlb common code update for System z.
In reply to Andrew MortonQuoted 31 lines · Andrew Morton
Quoted 4 lines
There are already several
ARCH_HAS_xxxdefines which are being used ininlude/linux/hugetlb.h. All of them are defined in include/asm-<arch>/page.h for every architecture that needs them (with the exception of powerpc, where it isinclude/asm-powerpc/page_64.h).Yes, but that's fugly and it would be better to put in place the infrastructure for cleaning it up, rather than worsening it.
So...
Put this:
(quoted diff) +7
-0+#define huge_pte_none(pte) pte_none(pte) +#define huge_pte_wrprotect(pte) pte_wrprotect(pte) +#define huge_ptep_set_wrprotect(mm, addr, ptep) \ + ptep_set_wrprotect(mm, addr, ptep) +#define huge_ptep_set_access_flags(vma, addr, ptep, pte, dirty) \ + ptep_set_access_flags(vma, addr, ptep, pte, dirty) +#define huge_ptep_get(ptep) (*ptep)into
include/asm-generic/hugetlb.hthen for each architecture except s390 add an
include/asm-foo/hugetlb.hwhich does#include <
asm-generic/hugetlb.h>then in
include/linux/hugetlb.hadd#include <
asm/hugetlb.h>
Quoted 7 lines
and then in
include/asm-s390/hugetlb.h, add your s390-specific versions ofhuge_pte_none()and friends.later, someone can hopefully use this new infrastructure to rid us of
ARCH_HAS_HUGEPAGE_ONLY_RANGE,ARCH_HAS_HUGETLB_FREE_PGD_RANGE,ARCH_HAS_PREPARE_HUGEPAGE_RANGE,ARCH_HAS_SETCLEAR_HUGE_PTEandARCH_HAS_HUGETLB_PREFAULT_HOOK.
This patch moves all architecture functions for hugetlb to architecture header files (include/asm-foo/hugetlb.h). It also removes (!) ARCH_HAS_HUGEPAGE_ONLY_RANGE, ARCH_HAS_HUGETLB_FREE_PGD_RANGE, ARCH_HAS_PREPARE_HUGEPAGE_RANGE, ARCH_HAS_SETCLEAR_HUGE_PTE and ARCH_HAS_HUGETLB_PREFAULT_HOOK.
Cross-Compile tests on the affected architectures (and one unaffected) worked fine, but I had no cross-compiler for sh.
If this patch is accepted, we will resend the s390 large page patches so that they will use/extend this new infrastructure.
--
Gerald Schaefer
--- include/asm-ia64/hugetlb.h | 21 +++++++++++++++++++ include/asm-ia64/page.h | 6 ----- include/asm-powerpc/hugetlb.h | 35 +++++++++++++++++++++++++++++++ include/asm-powerpc/page_64.h | 7 ------ include/asm-sh/hugetlb.h | 28 +++++++++++++++++++++++++ include/asm-sparc64/hugetlb.h | 30 +++++++++++++++++++++++++++ include/asm-sparc64/page.h | 2 - include/asm-x86/hugetlb.h | 28 +++++++++++++++++++++++++ include/linux/hugetlb.h | 46 ------------------------------------------ 9 files changed, 143 insertions(+), 60 deletions(-)
include/asm-ia64/hugetlb.h new file +21 -0
@@ -0,0 +1,21 @@ +#ifndef _ASM_IA64_HUGETLB_H +#define _ASM_IA64_HUGETLB_H + +#include <asm/page.h> + + +#define is_hugepage_only_range (mm, addr, len) \ + (REGION_NUMBER(addr) == RGN_HPAGE || \ + REGION_NUMBER((addr)+(len)-1) == RGN_HPAGE) + +void hugetlb_free_pgd_range (struct mmu_gather **tlb,unsigned long addr, +unsigned long end,unsigned long floor, +unsigned long ceiling); +int prepare_hugepage_range (unsigned long addr,unsigned long len); + +#define set_huge_pte_at (mm, addr, ptep, pte) set_pte_at(mm, addr, ptep, pte) +#define huge_ptep_get_and_clear (mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep) + +#define hugetlb_prefault_arch_hook (mm) do { } while (0) + +#endif /* _ASM_IA64_HUGETLB_H */
include/asm-sh/hugetlb.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef _ASM_SH_HUGETLB_H +#define _ASM_SH_HUGETLB_H + +#include <asm/page.h> + + +#define is_hugepage_only_range (mm, addr, len) 0 +#define hugetlb_free_pgd_range free_pgd_range + +/* +* If the arch doesn't supply something else, assume that hugepage +* size aligned regions are ok without further preparation. +*/ +static inline int prepare_hugepage_range (unsigned long addr,unsigned long len) +{ +if (len & ~HPAGE_MASK ) +return -EINVAL ; +if (addr & ~HPAGE_MASK ) +return -EINVAL ; +return 0 ; +} + +#define set_huge_pte_at (mm, addr, ptep, pte) set_pte_at(mm, addr, ptep, pte) +#define huge_ptep_get_and_clear (mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep) + +#define hugetlb_prefault_arch_hook (mm) do { } while (0) + +#endif /* _ASM_SH_HUGETLB_H */
include/asm-sparc64/hugetlb.h new file +30 -0
@@ -0,0 +1,30 @@ +#ifndef _ASM_SPARC64_HUGETLB_H +#define _ASM_SPARC64_HUGETLB_H + +#include <asm/page.h> + + +#define is_hugepage_only_range (mm, addr, len) 0 +#define hugetlb_free_pgd_range free_pgd_range + +/* +* If the arch doesn't supply something else, assume that hugepage +* size aligned regions are ok without further preparation. +*/ +static inline int prepare_hugepage_range (unsigned long addr,unsigned long len) +{ +if (len & ~HPAGE_MASK ) +return -EINVAL ; +if (addr & ~HPAGE_MASK ) +return -EINVAL ; +return 0 ; +} + +void set_huge_pte_at (struct mm_struct *mm,unsigned long addr, +pte_t *ptep,pte_t pte); +pte_t huge_ptep_get_and_clear (struct mm_struct *mm,unsigned long addr, +pte_t *ptep); + +void hugetlb_prefault_arch_hook (struct mm_struct *mm); + +#endif /* _ASM_SPARC64_HUGETLB_H */
include/asm-x86/hugetlb.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef _ASM_X86_HUGETLB_H +#define _ASM_X86_HUGETLB_H + +#include <asm/page.h> + + +#define is_hugepage_only_range (mm, addr, len) 0 +#define hugetlb_free_pgd_range free_pgd_range + +/* +* If the arch doesn't supply something else, assume that hugepage +* size aligned regions are ok without further preparation. +*/ +static inline int prepare_hugepage_range (unsigned long addr,unsigned long len) +{ +if (len & ~HPAGE_MASK ) +return -EINVAL ; +if (addr & ~HPAGE_MASK ) +return -EINVAL ; +return 0 ; +} + +#define set_huge_pte_at (mm, addr, ptep, pte) set_pte_at(mm, addr, ptep, pte) +#define huge_ptep_get_and_clear (mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep) + +#define hugetlb_prefault_arch_hook (mm) do { } while (0) + +#endif /* _ASM_X86_HUGETLB_H */
include/linux/hugetlb.h +1 -45
58 lines not on this page · raw message
include/asm-powerpc/hugetlb.h new file +35 -0
@@ -0,0 +1,35 @@ +#ifndef _ASM_POWERPC_HUGETLB_H +#define _ASM_POWERPC_HUGETLB_H + +#include <asm/page.h> + + +extern int is_hugepage_only_range (struct mm_struct *m, +unsigned long addr, +unsigned long len); + +void hugetlb_free_pgd_range (struct mmu_gather **tlb,unsigned long addr, +unsigned long end,unsigned long floor, +unsigned long ceiling); + +/* +* If the arch doesn't supply something else, assume that hugepage +* size aligned regions are ok without further preparation. +*/ +static inline int prepare_hugepage_range (unsigned long addr,unsigned long len) +{ +if (len & ~HPAGE_MASK ) +return -EINVAL ; +if (addr & ~HPAGE_MASK ) +return -EINVAL ; +return 0 ; +} + +void set_huge_pte_at (struct mm_struct *mm,unsigned long addr, +pte_t *ptep,pte_t pte); +pte_t huge_ptep_get_and_clear (struct mm_struct *mm,unsigned long addr, +pte_t *ptep); + +#define hugetlb_prefault_arch_hook (mm) do { } while (0) + +#endif /* _ASM_POWERPC_HUGETLB_H */
include/asm-ia64/page.h +0 -6
@@ -54,9 +54,6 @@# define HPAGE_MASK (~(HPAGE_SIZE - 1))# define HAVE_ARCH_HUGETLB_UNMAPPED_AREA -# define ARCH_HAS_HUGEPAGE_ONLY_RANGE -# define ARCH_HAS_PREPARE_HUGEPAGE_RANGE -# define ARCH_HAS_HUGETLB_FREE_PGD_RANGE #endif /* CONFIG_HUGETLB_PAGE */ #ifdef __ASSEMBLY__
@@ -153,9 +150,6 @@ typedef union ia64_va {# define htlbpage_to_page (x) (((unsigned long) REGION_NUMBER(x) << 61) \ | (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT)))# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -# define is_hugepage_only_range (mm, addr, len) \ - (REGION_NUMBER(addr) == RGN_HPAGE || \ - REGION_NUMBER((addr)+(len)-1) == RGN_HPAGE)extern unsigned int hpage_shift;#endif
include/asm-powerpc/page_64.h +0 -7
@@ -128,11 +128,6 @@ extern void slice_init_context(struct mmextern void slice_set_user_psize (struct mm_struct *mm,unsigned int psize);#define slice_mm_new_context (mm) ((mm)->context.id == 0) -#define ARCH_HAS_HUGEPAGE_ONLY_RANGE -extern int is_hugepage_only_range (struct mm_struct *m, -unsigned long addr, -unsigned long len); -#endif /* __ASSEMBLY__ */ #else #define slice_init ()
@@ -146,8 +141,6 @@ do { \#ifdef CONFIG_HUGETLB_PAGE -#define ARCH_HAS_HUGETLB_FREE_PGD_RANGE -#define ARCH_HAS_SETCLEAR_HUGE_PTE #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif /* !CONFIG_HUGETLB_PAGE */
include/asm-sparc64/page.h +0 -2
@@ -39,8 +39,6 @@#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -#define ARCH_HAS_SETCLEAR_HUGE_PTE -#define ARCH_HAS_HUGETLB_PREFAULT_HOOK #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif
Re: [patch 09/10] Hugetlb common code update for System z.
Quoted 3 lines · Gerald Schaefer
include/asm-sh/hugetlb.h | 28 +++++++++++++++++++++++++ include/asm-sparc64/hugetlb.h | 30 +++++++++++++++++++++++++++ include/asm-x86/hugetlb.h | 28 +++++++++++++++++++++++++
these seem largely duplicated - shouldnt there be an asm-generic/hugetlb.h instead, which asm/hugetlb.h could include to get default behavior? It would probably reduce the linecount of your patch as well.
Ingo
Re: [patch 09/10] Hugetlb common code update for System z.
Quoted 10 lines · Ingo Molnar
Quoted 3 lines · Gerald Schaefer
include/asm-sh/hugetlb.h | 28 +++++++++++++++++++++++++ include/asm-sparc64/hugetlb.h | 30 +++++++++++++++++++++++++++ include/asm-x86/hugetlb.h | 28 +++++++++++++++++++++++++these seem largely duplicated - shouldnt there be an
asm-generic/hugetlb.hinstead, whichasm/hugetlb.hcould include to get default behavior? It would probably reduce the linecount of your patch as well.
Right, asm-generic was also suggested by Andrew as a first step, before getting rid of the ARCH_HAS_xxx stuff, and it would also reduce the loc. But it would make things complicated if one architecture later wants to take out some of the generic stuff to define it on their own, then they'd need to touch all architecture headers again.
So I thought I'd rather not introduce the asm-generic header at all but let all architectures have their own headers, risking code duplication but hopefully making future updates easier.
--
Gerald Schaefer
Re: [patch 09/10] Hugetlb common code update for System z.
In reply to Ingo MolnarQuoted 10 lines · Ingo Molnar
Quoted 3 lines · Gerald Schaefer
include/asm-sh/hugetlb.h | 28 +++++++++++++++++++++++++ include/asm-sparc64/hugetlb.h | 30 +++++++++++++++++++++++++++ include/asm-x86/hugetlb.h | 28 +++++++++++++++++++++++++these seem largely duplicated - shouldnt there be an
asm-generic/hugetlb.hinstead, whichasm/hugetlb.hcould include to get default behavior? It would probably reduce the linecount of your patch as well.
Well the hugetlbfs primitives are architecture specific, aren't they? Just like the other page table manipulation functions. I find the usual method to use asm-generic/<xxx> and a lot of defines and #ifdefs to pick up the correct definition from a generic header file rather hard to read. In the end each arch that wants to use hugetlbfs has to define each of the hugetlb primitives. Most of them are rather simple, e.g. the x86 set_huge_pte_at is just a set_pte_at. One line to define the primitive. Now we could have an #ifdef block around the default definition that maps set_huge_pte_at to set_pte_at in asm-generic and an ARCH_HAS_xx override for architecture that need to do something more complicated. Somehow that was where we started ..
I think the best way to get rid of the ARCH_HAS_xxx fugliness is to let each architecture define their primitives, even if it looks like code duplication.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [patch 09/10] Hugetlb common code update for System z.
Quoted 9 lines · Martin Schwidefsky
Quoted 8 lines
Quoted 3 lines
include/asm-sh/hugetlb.h | 28 +++++++++++++++++++++++++ include/asm-sparc64/hugetlb.h | 30 +++++++++++++++++++++++++++ include/asm-x86/hugetlb.h | 28 +++++++++++++++++++++++++these seem largely duplicated - shouldnt there be an
asm-generic/hugetlb.hinstead, whichasm/hugetlb.hcould include to get default behavior? It would probably reduce the linecount of your patch as well.
Quoted 14 lines
Well the hugetlbfs primitives are architecture specific, aren't they? Just like the other page table manipulation functions. I find the usual method to use asm-generic/<xxx> and a lot of defines and #ifdefs to pick up the correct definition from a generic header file rather hard to read. In the end each arch that wants to use hugetlbfs has to define each of the hugetlb primitives. Most of them are rather simple, e.g. the x86
set_huge_pte_atis just aset_pte_at. One line to define the primitive. Now we could have an #ifdef block around the default definition that mapsset_huge_pte_attoset_pte_atin asm-generic and anARCH_HAS_xxoverride for architecture that need to do something more complicated. Somehow that was where we started .. I think the best way to get rid of theARCH_HAS_xxxfugliness is to let each architecture define their primitives, even if it looks like code duplication.
sorry, i misread your patch - it indeed looks cleaner with your patch applied.
Ingo
PATCH 10/10 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/defconfig | 3 arch/s390/kernel/early.c | 14 +++ arch/s390/kernel/head64.S | 12 +++ arch/s390/kernel/setup.c | 19 +---- 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/page.h | 29 ++++++-- include/asm-s390/pgtable.h | 158 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-s390/setup.h | 4 + include/asm-s390/system.h | 10 ++ include/asm-s390/tlbflush.h | 1 15 files changed, 418 insertions(+), 52 deletions(-)
arch/s390/defconfig +2 -1
@@ -653,7 +653,8 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_CONFIGFS_FS=m #
arch/s390/kernel/early.c +14 -0
@@ -263,6 +263,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 |=1024 ; +__ctl_set_bit (0 ,23 ); +#endif +} +/* * Save ipl parameters, clear bss memory, initialize storage keys * and create a kernel NSS at startup if the SAVESYS= parm is defined
@@ -280,6 +293,7 @@ void __init startup_init(void)create_kernel_nss ();sort_main_extable ();setup_lowcore_early (); +setup_hpage ();sclp_read_info_early ();sclp_facilities_detect (); memsize =sclp_memory_detect ();
arch/s390/kernel/head64.S +11 -1
@@ -187,11 +187,21 @@ startup_continue: oi 6(%r12),2 # set MVCOS flag 1: + la %r1,0f-.LPG1(%r13) + stg %r1,__LC_PGM_NEW_PSW+8 + lhi %r1,-1 + .short 0xb9af + .short 0x0011 +0: tm 0x8f,0x6 # specification exception? + bno 1f-.LPG1(%r13) + oi 6(%r12),8 +1: + lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, # 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 -12
@@ -679,15 +679,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 ;
@@ -754,6 +745,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 )
@@ -873,8 +867,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 ;
@@ -889,7 +884,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>
@@ -374,6 +375,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
@@ -78,28 +78,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 */
@@ -122,7 +100,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
@@ -978,7 +978,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/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_CPAGE ) { + 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 +158 -0
176 lines not on this page · raw message
include/asm-s390/setup.h +4 -0
@@ -70,11 +70,15 @@ extern unsigned long machine_flags;#define MACHINE_HAS_CSP (machine_flags & 8)#define MACHINE_HAS_DIAG44 (1)#define MACHINE_HAS_MVCOS (0) +#define MACHINE_HAS_HPAGE (0) +#define MACHINE_HAS_CPAGE (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_HPAGE (machine_flags & 1024) +#define MACHINE_HAS_CPAGE (machine_flags & 2048)#endif /* __s390x__ */ #define MACHINE_HAS_SCLP (!MACHINE_IS_P390)
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__
@@ -423,6 +424,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 );
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.
Re: [patch 10/10] System z large page support.
arch/s390/mm/hugetlbpage.c line 86
Quoted 13 lines · Martin Schwidefsky
arch/s390/mm/hugetlbpage.c new file +12
-0+pte_t *huge_pte_alloc (struct mm_struct *mm,unsigned long addr) +{ +pgd_t *pgdp; +pud_t *pudp; +pmd_t *pmdp =NULL ; + + pgdp =pgd_offset (mm, addr); + pudp =pud_alloc (mm, pgdp, addr); +if (pudp) + pmdp =pmd_alloc (mm, pudp, addr); +return (pte_t *) pmdp; +}
That looks pretty generic. Why can't you share with the version we already have?
-- Dave
Re: [patch 10/10] System z large page support.
Quoted 16 lines · Dave Hansen
arch/s390/mm/hugetlbpage.c line 86
Quoted 13 lines
arch/s390/mm/hugetlbpage.c new file +12
-0+pte_t *huge_pte_alloc (struct mm_struct *mm,unsigned long addr) +{ +pgd_t *pgdp; +pud_t *pudp; +pmd_t *pmdp =NULL ; + + pgdp =pgd_offset (mm, addr); + pudp =pud_alloc (mm, pgdp, addr); +if (pudp) + pmdp =pmd_alloc (mm, pudp, addr); +return (pte_t *) pmdp; +}That looks pretty generic. Why can't you share with the version we already have?
What version do you mean? Every architecture with hugetlbfs support has its own huge_pte_alloc() function in arch/<arch>/mm/hugetlbfs.c, and they are all doing slightly different things.
--
Gerald Schaefer