diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/sysinfo.h | 35 | ||||
-rw-r--r-- | arch/s390/kernel/topology.c | 75 |
2 files changed, 56 insertions, 54 deletions
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index c2ece4dd6c0a..79d3d6e2e9c5 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #ifndef __ASM_S390_SYSINFO_H | 14 | #ifndef __ASM_S390_SYSINFO_H |
15 | #define __ASM_S390_SYSINFO_H | 15 | #define __ASM_S390_SYSINFO_H |
16 | 16 | ||
17 | #include <asm/bitsperlong.h> | ||
18 | |||
17 | struct sysinfo_1_1_1 { | 19 | struct sysinfo_1_1_1 { |
18 | unsigned short :16; | 20 | unsigned short :16; |
19 | unsigned char ccr; | 21 | unsigned char ccr; |
@@ -107,6 +109,39 @@ struct sysinfo_3_2_2 { | |||
107 | char reserved_544[3552]; | 109 | char reserved_544[3552]; |
108 | }; | 110 | }; |
109 | 111 | ||
112 | #define TOPOLOGY_CPU_BITS 64 | ||
113 | #define TOPOLOGY_NR_MAG 6 | ||
114 | |||
115 | struct topology_cpu { | ||
116 | unsigned char reserved0[4]; | ||
117 | unsigned char :6; | ||
118 | unsigned char pp:2; | ||
119 | unsigned char reserved1; | ||
120 | unsigned short origin; | ||
121 | unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG]; | ||
122 | }; | ||
123 | |||
124 | struct topology_container { | ||
125 | unsigned char reserved[7]; | ||
126 | unsigned char id; | ||
127 | }; | ||
128 | |||
129 | union topology_entry { | ||
130 | unsigned char nl; | ||
131 | struct topology_cpu cpu; | ||
132 | struct topology_container container; | ||
133 | }; | ||
134 | |||
135 | struct sysinfo_15_1_x { | ||
136 | unsigned char reserved0[2]; | ||
137 | unsigned short length; | ||
138 | unsigned char mag[TOPOLOGY_NR_MAG]; | ||
139 | unsigned char reserved1; | ||
140 | unsigned char mnest; | ||
141 | unsigned char reserved2[4]; | ||
142 | union topology_entry tle[0]; | ||
143 | }; | ||
144 | |||
110 | static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) | 145 | static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) |
111 | { | 146 | { |
112 | register int r0 asm("0") = (fc << 28) | sel1; | 147 | register int r0 asm("0") = (fc << 28) | sel1; |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 69004411a93d..ffea01e63218 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
@@ -20,43 +20,10 @@ | |||
20 | #include <asm/s390_ext.h> | 20 | #include <asm/s390_ext.h> |
21 | #include <asm/sysinfo.h> | 21 | #include <asm/sysinfo.h> |
22 | 22 | ||
23 | #define CPU_BITS 64 | ||
24 | #define NR_MAG 6 | ||
25 | |||
26 | #define PTF_HORIZONTAL (0UL) | 23 | #define PTF_HORIZONTAL (0UL) |
27 | #define PTF_VERTICAL (1UL) | 24 | #define PTF_VERTICAL (1UL) |
28 | #define PTF_CHECK (2UL) | 25 | #define PTF_CHECK (2UL) |
29 | 26 | ||
30 | struct tl_cpu { | ||
31 | unsigned char reserved0[4]; | ||
32 | unsigned char :6; | ||
33 | unsigned char pp:2; | ||
34 | unsigned char reserved1; | ||
35 | unsigned short origin; | ||
36 | unsigned long mask[CPU_BITS / BITS_PER_LONG]; | ||
37 | }; | ||
38 | |||
39 | struct tl_container { | ||
40 | unsigned char reserved[7]; | ||
41 | unsigned char id; | ||
42 | }; | ||
43 | |||
44 | union tl_entry { | ||
45 | unsigned char nl; | ||
46 | struct tl_cpu cpu; | ||
47 | struct tl_container container; | ||
48 | }; | ||
49 | |||
50 | struct tl_info { | ||
51 | unsigned char reserved0[2]; | ||
52 | unsigned short length; | ||
53 | unsigned char mag[NR_MAG]; | ||
54 | unsigned char reserved1; | ||
55 | unsigned char mnest; | ||
56 | unsigned char reserved2[4]; | ||
57 | union tl_entry tle[0]; | ||
58 | }; | ||
59 | |||
60 | struct mask_info { | 27 | struct mask_info { |
61 | struct mask_info *next; | 28 | struct mask_info *next; |
62 | unsigned char id; | 29 | unsigned char id; |
@@ -65,7 +32,7 @@ struct mask_info { | |||
65 | 32 | ||
66 | static int topology_enabled = 1; | 33 | static int topology_enabled = 1; |
67 | static void topology_work_fn(struct work_struct *work); | 34 | static void topology_work_fn(struct work_struct *work); |
68 | static struct tl_info *tl_info; | 35 | static struct sysinfo_15_1_x *tl_info; |
69 | static struct timer_list topology_timer; | 36 | static struct timer_list topology_timer; |
70 | static void set_topology_timer(void); | 37 | static void set_topology_timer(void); |
71 | static DECLARE_WORK(topology_work, topology_work_fn); | 38 | static DECLARE_WORK(topology_work, topology_work_fn); |
@@ -101,18 +68,18 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) | |||
101 | return mask; | 68 | return mask; |
102 | } | 69 | } |
103 | 70 | ||
104 | static void add_cpus_to_mask(struct tl_cpu *tl_cpu, struct mask_info *book, | 71 | static void add_cpus_to_mask(struct topology_cpu *tl_cpu, |
105 | struct mask_info *core) | 72 | struct mask_info *book, struct mask_info *core) |
106 | { | 73 | { |
107 | unsigned int cpu; | 74 | unsigned int cpu; |
108 | 75 | ||
109 | for (cpu = find_first_bit(&tl_cpu->mask[0], CPU_BITS); | 76 | for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS); |
110 | cpu < CPU_BITS; | 77 | cpu < TOPOLOGY_CPU_BITS; |
111 | cpu = find_next_bit(&tl_cpu->mask[0], CPU_BITS, cpu + 1)) | 78 | cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1)) |
112 | { | 79 | { |
113 | unsigned int rcpu, lcpu; | 80 | unsigned int rcpu, lcpu; |
114 | 81 | ||
115 | rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin; | 82 | rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin; |
116 | for_each_present_cpu(lcpu) { | 83 | for_each_present_cpu(lcpu) { |
117 | if (cpu_logical_map(lcpu) != rcpu) | 84 | if (cpu_logical_map(lcpu) != rcpu) |
118 | continue; | 85 | continue; |
@@ -145,15 +112,14 @@ static void clear_masks(void) | |||
145 | #endif | 112 | #endif |
146 | } | 113 | } |
147 | 114 | ||
148 | static union tl_entry *next_tle(union tl_entry *tle) | 115 | static union topology_entry *next_tle(union topology_entry *tle) |
149 | { | 116 | { |
150 | if (tle->nl) | 117 | if (!tle->nl) |
151 | return (union tl_entry *)((struct tl_container *)tle + 1); | 118 | return (union topology_entry *)((struct topology_cpu *)tle + 1); |
152 | else | 119 | return (union topology_entry *)((struct topology_container *)tle + 1); |
153 | return (union tl_entry *)((struct tl_cpu *)tle + 1); | ||
154 | } | 120 | } |
155 | 121 | ||
156 | static void tl_to_cores(struct tl_info *info) | 122 | static void tl_to_cores(struct sysinfo_15_1_x *info) |
157 | { | 123 | { |
158 | #ifdef CONFIG_SCHED_BOOK | 124 | #ifdef CONFIG_SCHED_BOOK |
159 | struct mask_info *book = &book_info; | 125 | struct mask_info *book = &book_info; |
@@ -161,13 +127,13 @@ static void tl_to_cores(struct tl_info *info) | |||
161 | struct mask_info *book = NULL; | 127 | struct mask_info *book = NULL; |
162 | #endif | 128 | #endif |
163 | struct mask_info *core = &core_info; | 129 | struct mask_info *core = &core_info; |
164 | union tl_entry *tle, *end; | 130 | union topology_entry *tle, *end; |
165 | 131 | ||
166 | 132 | ||
167 | spin_lock_irq(&topology_lock); | 133 | spin_lock_irq(&topology_lock); |
168 | clear_masks(); | 134 | clear_masks(); |
169 | tle = info->tle; | 135 | tle = info->tle; |
170 | end = (union tl_entry *)((unsigned long)info + info->length); | 136 | end = (union topology_entry *)((unsigned long)info + info->length); |
171 | while (tle < end) { | 137 | while (tle < end) { |
172 | switch (tle->nl) { | 138 | switch (tle->nl) { |
173 | #ifdef CONFIG_SCHED_BOOK | 139 | #ifdef CONFIG_SCHED_BOOK |
@@ -263,7 +229,7 @@ static void store_topology(struct tl_info *info) | |||
263 | 229 | ||
264 | int arch_update_cpu_topology(void) | 230 | int arch_update_cpu_topology(void) |
265 | { | 231 | { |
266 | struct tl_info *info = tl_info; | 232 | struct sysinfo_15_1_x *info = tl_info; |
267 | struct sys_device *sysdev; | 233 | struct sys_device *sysdev; |
268 | int cpu; | 234 | int cpu; |
269 | 235 | ||
@@ -333,13 +299,14 @@ out: | |||
333 | } | 299 | } |
334 | __initcall(init_topology_update); | 300 | __initcall(init_topology_update); |
335 | 301 | ||
336 | static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset) | 302 | static void alloc_masks(struct sysinfo_15_1_x *info, struct mask_info *mask, |
303 | int offset) | ||
337 | { | 304 | { |
338 | int i, nr_masks; | 305 | int i, nr_masks; |
339 | 306 | ||
340 | nr_masks = info->mag[NR_MAG - offset]; | 307 | nr_masks = info->mag[TOPOLOGY_NR_MAG - offset]; |
341 | for (i = 0; i < info->mnest - offset; i++) | 308 | for (i = 0; i < info->mnest - offset; i++) |
342 | nr_masks *= info->mag[NR_MAG - offset - 1 - i]; | 309 | nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i]; |
343 | nr_masks = max(nr_masks, 1); | 310 | nr_masks = max(nr_masks, 1); |
344 | for (i = 0; i < nr_masks; i++) { | 311 | for (i = 0; i < nr_masks; i++) { |
345 | mask->next = alloc_bootmem(sizeof(struct mask_info)); | 312 | mask->next = alloc_bootmem(sizeof(struct mask_info)); |
@@ -349,7 +316,7 @@ static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset | |||
349 | 316 | ||
350 | void __init s390_init_cpu_topology(void) | 317 | void __init s390_init_cpu_topology(void) |
351 | { | 318 | { |
352 | struct tl_info *info; | 319 | struct sysinfo_15_1_x *info; |
353 | int i; | 320 | int i; |
354 | 321 | ||
355 | if (!MACHINE_HAS_TOPOLOGY) | 322 | if (!MACHINE_HAS_TOPOLOGY) |
@@ -358,7 +325,7 @@ void __init s390_init_cpu_topology(void) | |||
358 | info = tl_info; | 325 | info = tl_info; |
359 | store_topology(info); | 326 | store_topology(info); |
360 | pr_info("The CPU configuration topology of the machine is:"); | 327 | pr_info("The CPU configuration topology of the machine is:"); |
361 | for (i = 0; i < NR_MAG; i++) | 328 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) |
362 | printk(" %d", info->mag[i]); | 329 | printk(" %d", info->mag[i]); |
363 | printk(" / %d\n", info->mnest); | 330 | printk(" / %d\n", info->mnest); |
364 | alloc_masks(info, &core_info, 2); | 331 | alloc_masks(info, &core_info, 2); |