aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-21 14:18:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-21 14:18:26 -0500
commitd34696c2208b2dc1b27ec8f0a017a91e4e6eb85d (patch)
tree4928379eef6664788be968616e90f6a44de2d4a9
parentf9677375b0c07e39c78b43aab9fb2c253a4b50c2 (diff)
parent61b0b01686d482205db14987826e1a11dd17d65c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Two patches to save some memory if CONFIG_NR_CPUS is large, a changed default for the use of compare-and-delay, and a couple of bug fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/spinlock: disabled compare-and-delay by default s390/mm: align 64-bit PIE binaries to 4GB s390/cacheinfo: coding style changes s390/cacheinfo: fix shared cpu masks s390/smp: reduce size of struct pcpu s390/topology: convert cpu_topology array to per cpu variable s390/topology: delay initialization of topology cpu masks s390/vdso: fix clock_gettime for CLOCK_THREAD_CPUTIME_ID, -2 and -3
-rw-r--r--arch/s390/include/asm/topology.h24
-rw-r--r--arch/s390/kernel/cache.c25
-rw-r--r--arch/s390/kernel/early.c12
-rw-r--r--arch/s390/kernel/setup.c1
-rw-r--r--arch/s390/kernel/smp.c54
-rw-r--r--arch/s390/kernel/topology.c134
-rw-r--r--arch/s390/kernel/vdso64/clock_gettime.S6
-rw-r--r--arch/s390/mm/mmap.c5
8 files changed, 119 insertions, 142 deletions
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index c4fbb9527c5c..b1453a2ae1ca 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -18,15 +18,15 @@ struct cpu_topology_s390 {
18 cpumask_t book_mask; 18 cpumask_t book_mask;
19}; 19};
20 20
21extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; 21DECLARE_PER_CPU(struct cpu_topology_s390, cpu_topology);
22 22
23#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) 23#define topology_physical_package_id(cpu) (per_cpu(cpu_topology, cpu).socket_id)
24#define topology_thread_id(cpu) (cpu_topology[cpu].thread_id) 24#define topology_thread_id(cpu) (per_cpu(cpu_topology, cpu).thread_id)
25#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_mask) 25#define topology_thread_cpumask(cpu) (&per_cpu(cpu_topology, cpu).thread_mask)
26#define topology_core_id(cpu) (cpu_topology[cpu].core_id) 26#define topology_core_id(cpu) (per_cpu(cpu_topology, cpu).core_id)
27#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask) 27#define topology_core_cpumask(cpu) (&per_cpu(cpu_topology, cpu).core_mask)
28#define topology_book_id(cpu) (cpu_topology[cpu].book_id) 28#define topology_book_id(cpu) (per_cpu(cpu_topology, cpu).book_id)
29#define topology_book_cpumask(cpu) (&cpu_topology[cpu].book_mask) 29#define topology_book_cpumask(cpu) (&per_cpu(cpu_topology, cpu).book_mask)
30 30
31#define mc_capable() 1 31#define mc_capable() 1
32 32
@@ -51,14 +51,6 @@ static inline void topology_expect_change(void) { }
51#define POLARIZATION_VM (2) 51#define POLARIZATION_VM (2)
52#define POLARIZATION_VH (3) 52#define POLARIZATION_VH (3)
53 53
54#ifdef CONFIG_SCHED_BOOK
55void s390_init_cpu_topology(void);
56#else
57static inline void s390_init_cpu_topology(void)
58{
59};
60#endif
61
62#include <asm-generic/topology.h> 54#include <asm-generic/topology.h>
63 55
64#endif /* _ASM_S390_TOPOLOGY_H */ 56#endif /* _ASM_S390_TOPOLOGY_H */
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c
index 632fa06ea162..0969d113b3d6 100644
--- a/arch/s390/kernel/cache.c
+++ b/arch/s390/kernel/cache.c
@@ -91,12 +91,9 @@ static inline enum cache_type get_cache_type(struct cache_info *ci, int level)
91{ 91{
92 if (level >= CACHE_MAX_LEVEL) 92 if (level >= CACHE_MAX_LEVEL)
93 return CACHE_TYPE_NOCACHE; 93 return CACHE_TYPE_NOCACHE;
94
95 ci += level; 94 ci += level;
96
97 if (ci->scope != CACHE_SCOPE_SHARED && ci->scope != CACHE_SCOPE_PRIVATE) 95 if (ci->scope != CACHE_SCOPE_SHARED && ci->scope != CACHE_SCOPE_PRIVATE)
98 return CACHE_TYPE_NOCACHE; 96 return CACHE_TYPE_NOCACHE;
99
100 return cache_type_map[ci->type]; 97 return cache_type_map[ci->type];
101} 98}
102 99
@@ -111,23 +108,19 @@ static inline unsigned long ecag(int ai, int li, int ti)
111} 108}
112 109
113static void ci_leaf_init(struct cacheinfo *this_leaf, int private, 110static void ci_leaf_init(struct cacheinfo *this_leaf, int private,
114 enum cache_type type, unsigned int level) 111 enum cache_type type, unsigned int level, int cpu)
115{ 112{
116 int ti, num_sets; 113 int ti, num_sets;
117 int cpu = smp_processor_id();
118 114
119 if (type == CACHE_TYPE_INST) 115 if (type == CACHE_TYPE_INST)
120 ti = CACHE_TI_INSTRUCTION; 116 ti = CACHE_TI_INSTRUCTION;
121 else 117 else
122 ti = CACHE_TI_UNIFIED; 118 ti = CACHE_TI_UNIFIED;
123
124 this_leaf->level = level + 1; 119 this_leaf->level = level + 1;
125 this_leaf->type = type; 120 this_leaf->type = type;
126 this_leaf->coherency_line_size = ecag(EXTRACT_LINE_SIZE, level, ti); 121 this_leaf->coherency_line_size = ecag(EXTRACT_LINE_SIZE, level, ti);
127 this_leaf->ways_of_associativity = ecag(EXTRACT_ASSOCIATIVITY, 122 this_leaf->ways_of_associativity = ecag(EXTRACT_ASSOCIATIVITY, level, ti);
128 level, ti);
129 this_leaf->size = ecag(EXTRACT_SIZE, level, ti); 123 this_leaf->size = ecag(EXTRACT_SIZE, level, ti);
130
131 num_sets = this_leaf->size / this_leaf->coherency_line_size; 124 num_sets = this_leaf->size / this_leaf->coherency_line_size;
132 num_sets /= this_leaf->ways_of_associativity; 125 num_sets /= this_leaf->ways_of_associativity;
133 this_leaf->number_of_sets = num_sets; 126 this_leaf->number_of_sets = num_sets;
@@ -145,7 +138,6 @@ int init_cache_level(unsigned int cpu)
145 138
146 if (!this_cpu_ci) 139 if (!this_cpu_ci)
147 return -EINVAL; 140 return -EINVAL;
148
149 ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); 141 ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0);
150 do { 142 do {
151 ctype = get_cache_type(&ct.ci[0], level); 143 ctype = get_cache_type(&ct.ci[0], level);
@@ -154,34 +146,31 @@ int init_cache_level(unsigned int cpu)
154 /* Separate instruction and data caches */ 146 /* Separate instruction and data caches */
155 leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; 147 leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
156 } while (++level < CACHE_MAX_LEVEL); 148 } while (++level < CACHE_MAX_LEVEL);
157
158 this_cpu_ci->num_levels = level; 149 this_cpu_ci->num_levels = level;
159 this_cpu_ci->num_leaves = leaves; 150 this_cpu_ci->num_leaves = leaves;
160
161 return 0; 151 return 0;
162} 152}
163 153
164int populate_cache_leaves(unsigned int cpu) 154int populate_cache_leaves(unsigned int cpu)
165{ 155{
156 struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
157 struct cacheinfo *this_leaf = this_cpu_ci->info_list;
166 unsigned int level, idx, pvt; 158 unsigned int level, idx, pvt;
167 union cache_topology ct; 159 union cache_topology ct;
168 enum cache_type ctype; 160 enum cache_type ctype;
169 struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
170 struct cacheinfo *this_leaf = this_cpu_ci->info_list;
171 161
172 ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); 162 ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0);
173 for (idx = 0, level = 0; level < this_cpu_ci->num_levels && 163 for (idx = 0, level = 0; level < this_cpu_ci->num_levels &&
174 idx < this_cpu_ci->num_leaves; idx++, level++) { 164 idx < this_cpu_ci->num_leaves; idx++, level++) {
175 if (!this_leaf) 165 if (!this_leaf)
176 return -EINVAL; 166 return -EINVAL;
177
178 pvt = (ct.ci[level].scope == CACHE_SCOPE_PRIVATE) ? 1 : 0; 167 pvt = (ct.ci[level].scope == CACHE_SCOPE_PRIVATE) ? 1 : 0;
179 ctype = get_cache_type(&ct.ci[0], level); 168 ctype = get_cache_type(&ct.ci[0], level);
180 if (ctype == CACHE_TYPE_SEPARATE) { 169 if (ctype == CACHE_TYPE_SEPARATE) {
181 ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_DATA, level); 170 ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_DATA, level, cpu);
182 ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_INST, level); 171 ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_INST, level, cpu);
183 } else { 172 } else {
184 ci_leaf_init(this_leaf++, pvt, ctype, level); 173 ci_leaf_init(this_leaf++, pvt, ctype, level, cpu);
185 } 174 }
186 } 175 }
187 return 0; 176 return 0;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 70a329450901..4427ab7ac23a 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -393,17 +393,19 @@ static __init void detect_machine_facilities(void)
393 S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC; 393 S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC;
394 if (test_facility(129)) 394 if (test_facility(129))
395 S390_lowcore.machine_flags |= MACHINE_FLAG_VX; 395 S390_lowcore.machine_flags |= MACHINE_FLAG_VX;
396 if (test_facility(128))
397 S390_lowcore.machine_flags |= MACHINE_FLAG_CAD;
398#endif 396#endif
399} 397}
400 398
401static int __init nocad_setup(char