diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 14:18:26 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 14:18:26 -0500 |
| commit | d34696c2208b2dc1b27ec8f0a017a91e4e6eb85d (patch) | |
| tree | 4928379eef6664788be968616e90f6a44de2d4a9 | |
| parent | f9677375b0c07e39c78b43aab9fb2c253a4b50c2 (diff) | |
| parent | 61b0b01686d482205db14987826e1a11dd17d65c (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.h | 24 | ||||
| -rw-r--r-- | arch/s390/kernel/cache.c | 25 | ||||
| -rw-r--r-- | arch/s390/kernel/early.c | 12 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 54 | ||||
| -rw-r--r-- | arch/s390/kernel/topology.c | 134 | ||||
| -rw-r--r-- | arch/s390/kernel/vdso64/clock_gettime.S | 6 | ||||
| -rw-r--r-- | arch/s390/mm/mmap.c | 5 |
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 | ||
| 21 | extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; | 21 | DECLARE_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 | ||
| 55 | void s390_init_cpu_topology(void); | ||
| 56 | #else | ||
| 57 | static 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 | ||
| 113 | static void ci_leaf_init(struct cacheinfo *this_leaf, int private, | 110 | static 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 | ||
| 164 | int populate_cache_leaves(unsigned int cpu) | 154 | int 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 | ||
| 401 | static int __init nocad_setup(char | ||
