aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-14 11:52:10 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-22 06:16:01 -0500
commit10ad34bc76dfbc49bda327a13012f6754c0c72e0 (patch)
tree4d76fb6882da2eb3e77b53c4fe64f6367ffbd79d
parent1f6b83e5e4d3aed46eac1d219322fba9c7341cd8 (diff)
s390: add SMT support
The multi-threading facility is introduced with the z13 processor family. This patch adds code to detect the multi-threading facility. With the facility enabled each core will surface multiple hardware threads to the system. Each hardware threads looks like a normal CPU to the operating system with all its registers and properties. The SCLP interface reports the SMT topology indirectly via the maximum thread id. Each reported CPU in the result of a read-scp-information is a core representing a number of hardware threads. To reflect the reduced CPU capacity if two hardware threads run on a single core the MT utilization counter set is used to normalize the raw cputime obtained by the CPU timer deltas. This scaled cputime is reported via the taskstats interface. The normal /proc/stat numbers are based on the raw cputime and are not affected by the normalization. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/Kconfig15
-rw-r--r--arch/s390/include/asm/cpu_mf.h14
-rw-r--r--arch/s390/include/asm/reset.h3
-rw-r--r--arch/s390/include/asm/sclp.h5
-rw-r--r--arch/s390/include/asm/sigp.h1
-rw-r--r--arch/s390/include/asm/smp.h4
-rw-r--r--arch/s390/include/asm/sysinfo.h20
-rw-r--r--arch/s390/include/asm/topology.h4
-rw-r--r--arch/s390/kernel/base.S3
-rw-r--r--arch/s390/kernel/dis.c8
-rw-r--r--arch/s390/kernel/ipl.c11
-rw-r--r--arch/s390/kernel/machine_kexec.c19
-rw-r--r--arch/s390/kernel/smp.c261
-rw-r--r--arch/s390/kernel/sysinfo.c8
-rw-r--r--arch/s390/kernel/topology.c63
-rw-r--r--arch/s390/kernel/vtime.c58
-rw-r--r--drivers/s390/char/sclp_early.c49
-rw-r--r--drivers/s390/cio/cio.c2
18 files changed, 430 insertions, 118 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 06c6d9ab5a8d..7eba5b5723e9 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -396,17 +396,26 @@ config HOTPLUG_CPU
396 can be controlled through /sys/devices/system/cpu/cpu#. 396 can be controlled through /sys/devices/system/cpu/cpu#.
397 Say N if you want to disable CPU hotplug. 397 Say N if you want to disable CPU hotplug.
398 398
399config SCHED_SMT
400 def_bool n
401
399config SCHED_MC 402config SCHED_MC
400 def_bool n 403 def_bool n
401 404
402config SCHED_BOOK 405config SCHED_BOOK
406 def_bool n
407
408config SCHED_TOPOLOGY
403 def_bool y 409 def_bool y
404 prompt "Book scheduler support" 410 prompt "Topology scheduler support"
405 depends on SMP 411 depends on SMP
412 select SCHED_SMT
406 select SCHED_MC 413 select SCHED_MC
414 select SCHED_BOOK
407 help 415 help
408 Book scheduler support improves the CPU scheduler's decision making 416 Topology scheduler support improves the CPU scheduler's decision
409 when dealing with machines that have several books. 417 making when dealing with machines that have multi-threading,
418 multiple cores or multiple books.
410 419
411source kernel/Kconfig.preempt 420source kernel/Kconfig.preempt
412 421
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index cb700d54bd83..5243a8679a1d 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -189,6 +189,20 @@ static inline int ecctr(u64 ctr, u64 *val)
189 return cc; 189 return cc;
190} 190}
191 191
192/* Store CPU counter multiple for the MT utilization counter set */
193static inline int stcctm5(u64 num, u64 *val)
194{
195 typedef struct { u64 _[num]; } addrtype;
196 int cc;
197
198 asm volatile (
199 " .insn rsy,0xeb0000000017,%2,5,%1\n"
200 " ipm %0\n"
201 " srl %0,28\n"
202 : "=d" (cc), "=Q" (*(addrtype *) val) : "d" (num) : "cc");
203 return cc;
204}
205
192/* Query sampling information */ 206/* Query sampling information */
193static inline int qsi(struct hws_qsi_info_block *info) 207static inline int qsi(struct hws_qsi_info_block *info)
194{ 208{
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h
index 804578587a7a..72786067b300 100644
--- a/arch/s390/include/asm/reset.h
+++ b/arch/s390/include/asm/reset.h
@@ -15,5 +15,6 @@ struct reset_call {
15 15
16extern void register_reset_call(struct reset_call *reset); 16extern void register_reset_call(struct reset_call *reset);
17extern void unregister_reset_call(struct reset_call *reset); 17extern void unregister_reset_call(struct reset_call *reset);
18extern void s390_reset_system(void (*func)(void *), void *data); 18extern void s390_reset_system(void (*fn_pre)(void),
19 void (*fn_post)(void *), void *data);
19#endif /* _ASM_S390_RESET_H */ 20#endif /* _ASM_S390_RESET_H */
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index b6f8066789c1..edb453cfc2c6 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -27,7 +27,7 @@ struct sclp_ipl_info {
27}; 27};
28 28
29struct sclp_cpu_entry { 29struct sclp_cpu_entry {
30 u8 address; 30 u8 core_id;
31 u8 reserved0[2]; 31 u8 reserved0[2];
32 u8 : 3; 32 u8 : 3;
33 u8 siif : 1; 33 u8 siif : 1;
@@ -51,6 +51,9 @@ int sclp_cpu_deconfigure(u8 cpu);
51unsigned long long sclp_get_rnmax(void); 51unsigned long long sclp_get_rnmax(void);
52unsigned long long sclp_get_rzm(void); 52unsigned long long sclp_get_rzm(void);
53unsigned int sclp_get_max_cpu(void); 53unsigned int sclp_get_max_cpu(void);
54unsigned int sclp_get_mtid(u8 cpu_type);
55unsigned int sclp_get_mtid_max(void);
56unsigned int sclp_get_mtid_prev(void);
54int sclp_sdias_blk_count(void); 57int sclp_sdias_blk_count(void);
55int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 58int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
56int sclp_chp_configure(struct chp_id chpid); 59int sclp_chp_configure(struct chp_id chpid);
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index 49576115dbb7..c49d9c0483a8 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -15,6 +15,7 @@
15#define SIGP_SET_ARCHITECTURE 18 15#define SIGP_SET_ARCHITECTURE 18
16#define SIGP_COND_EMERGENCY_SIGNAL 19 16#define SIGP_COND_EMERGENCY_SIGNAL 19
17#define SIGP_SENSE_RUNNING 21 17#define SIGP_SENSE_RUNNING 21
18#define SIGP_SET_MULTI_THREADING 22
18#define SIGP_STORE_ADDITIONAL_STATUS 23 19#define SIGP_STORE_ADDITIONAL_STATUS 23
19 20
20/* SIGP condition codes */ 21/* SIGP condition codes */
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 762d4f88af5a..b3bd0282dd98 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -16,6 +16,8 @@
16#define raw_smp_processor_id() (S390_lowcore.cpu_nr) 16#define raw_smp_processor_id() (S390_lowcore.cpu_nr)
17 17
18extern struct mutex smp_cpu_state_mutex; 18extern struct mutex smp_cpu_state_mutex;
19extern unsigned int smp_cpu_mt_shift;
20extern unsigned int smp_cpu_mtid;
19 21
20extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); 22extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
21 23
@@ -35,6 +37,8 @@ extern void smp_fill_possible_mask(void);
35 37
36#else /* CONFIG_SMP */ 38#else /* CONFIG_SMP */
37 39
40#define smp_cpu_mtid 0
41
38static inline void smp_call_ipl_cpu(void (*func)(void *), void *data) 42static inline void smp_call_ipl_cpu(void (*func)(void *), void *data)
39{ 43{
40 func(data); 44 func(data);
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index f92428e459f8..73f12d21af4d 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -90,7 +90,11 @@ struct sysinfo_2_2_2 {
90 unsigned short cpus_reserved; 90 unsigned short cpus_reserved;
91 char name[8]; 91 char name[8];
92 unsigned int caf; 92 unsigned int caf;
93 char reserved_2[16]; 93 char reserved_2[8];
94 unsigned char mt_installed;
95 unsigned char mt_general;
96 unsigned char mt_psmtid;
97 char reserved_3[5];
94 unsigned short cpus_dedicated; 98 unsigned short cpus_dedicated;
95 unsigned short cpus_shared; 99 unsigned short cpus_shared;
96}; 100};
@@ -120,26 +124,28 @@ struct sysinfo_3_2_2 {
120 124
121extern int topology_max_mnest; 125extern int topology_max_mnest;
122 126
123#define TOPOLOGY_CPU_BITS 64 127#define TOPOLOGY_CORE_BITS 64
124#define TOPOLOGY_NR_MAG 6 128#define TOPOLOGY_NR_MAG 6
125 129
126struct topology_cpu { 130struct topology_core {
127 unsigned char reserved0[4]; 131 unsigned char nl;
132 unsigned char reserved0[3];
128 unsigned char :6; 133 unsigned char :6;
129 unsigned char pp:2; 134 unsigned char pp:2;
130 unsigned char reserved1; 135 unsigned char reserved1;
131 unsigned short origin; 136 unsigned short origin;
132 unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG]; 137 unsigned long mask[TOPOLOGY_CORE_BITS / BITS_PER_LONG];
133}; 138};
134 139
135struct topology_container { 140struct topology_container {
136 unsigned char reserved[7]; 141 unsigned char nl;
142 unsigned char reserved[6];
137 unsigned char id; 143 unsigned char id;
138}; 144};
139 145
140union topology_entry { 146union topology_entry {
141 unsigned char nl; 147 unsigned char nl;
142 struct topology_cpu cpu; 148 struct topology_core cpu;
143 struct topology_container container; 149 struct topology_container container;
144}; 150};
145 151
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 56af53093d24..c4fbb9527c5c 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -9,9 +9,11 @@ struct cpu;
9#ifdef CONFIG_SCHED_BOOK 9#ifdef CONFIG_SCHED_BOOK
10 10
11struct cpu_topology_s390 { 11struct cpu_topology_s390 {
12 unsigned short thread_id;
12 unsigned short core_id; 13 unsigned short core_id;
13 unsigned short socket_id; 14 unsigned short socket_id;
14 unsigned short book_id; 15 unsigned short book_id;
16 cpumask_t thread_mask;
15 cpumask_t core_mask; 17 cpumask_t core_mask;
16 cpumask_t book_mask; 18 cpumask_t book_mask;
17}; 19};
@@ -19,6 +21,8 @@ struct cpu_topology_s390 {
19extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; 21extern struct cpu_topology_s390 cpu_topology[NR_CPUS];
20 22
21#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) 23#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
24#define topology_thread_id(cpu) (cpu_topology[cpu].thread_id)
25#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_mask)
22#define topology_core_id(cpu) (cpu_topology[cpu].core_id) 26#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
23#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask) 27#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask)
24#define topology_book_id(cpu) (cpu_topology[cpu].book_id) 28#define topology_book_id(cpu) (cpu_topology[cpu].book_id)
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index 797a823a2275..f74a53d339b0 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -97,7 +97,8 @@ ENTRY(diag308_reset)
97 lg %r4,0(%r4) # Save PSW 97 lg %r4,0(%r4) # Save PSW
98 sturg %r4,%r3 # Use sturg, because of large pages 98 sturg %r4,%r3 # Use sturg, because of large pages
99 lghi %r1,1 99 lghi %r1,1
100 diag %r1,%r1,0x308 100 lghi %r0,0
101 diag %r0,%r1,0x308
101.Lrestart_part2: 102.Lrestart_part2:
102 lhi %r0,0 # Load r0 with zero 103 lhi %r0,0 # Load r0 with zero
103 lhi %r1,2 # Use mode 2 = ESAME (dump) 104 lhi %r1,2 # Use mode 2 = ESAME (dump)
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index d46d0b0b2cda..533430307da8 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -137,7 +137,7 @@ enum {
137 INSTR_RSI_RRP, 137 INSTR_RSI_RRP,
138 INSTR_RSL_LRDFU, INSTR_RSL_R0RD, 138 INSTR_RSL_LRDFU, INSTR_RSL_R0RD,
139 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD, 139 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
140 INSTR_RSY_RDRM, 140 INSTR_RSY_RDRM, INSTR_RSY_RMRD,
141 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD, 141 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
142 INSTR_RS_RURD, 142 INSTR_RS_RURD,
143 INSTR_RXE_FRRD, INSTR_RXE_RRRD, INSTR_RXE_RRRDM, 143 INSTR_RXE_FRRD, INSTR_RXE_RRRD, INSTR_RXE_RRRDM,
@@ -307,6 +307,7 @@ static const unsigned char formats[][7] = {
307 [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 }, 307 [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },
308 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 }, 308 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
309 [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 }, 309 [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 },
310 [INSTR_RSY_RMRD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
310 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 }, 311 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
311 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, 312 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
312 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, 313 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
@@ -450,7 +451,8 @@ enum {
450 LONG_INSN_VERLLV, 451 LONG_INSN_VERLLV,
451 LONG_INSN_VESRAV, 452 LONG_INSN_VESRAV,
452 LONG_INSN_VESRLV, 453 LONG_INSN_VESRLV,
453 LONG_INSN_VSBCBI 454 LONG_INSN_VSBCBI,
455 LONG_INSN_STCCTM
454}; 456};
455 457
456static char *long_insn_name[] = { 458static char *long_insn_name[] = {
@@ -530,6 +532,7 @@ static char *long_insn_name[] = {
530 [LONG_INSN_VESRAV] = "vesrav", 532 [LONG_INSN_VESRAV] = "vesrav",
531 [LONG_INSN_VESRLV] = "vesrlv", 533 [LONG_INSN_VESRLV] = "vesrlv",
532 [LONG_INSN_VSBCBI] = "vsbcbi", 534 [LONG_INSN_VSBCBI] = "vsbcbi",
535 [LONG_INSN_STCCTM] = "stcctm",
533}; 536};
534 537
535static struct s390_insn opcode[] = { 538static struct s390_insn opcode[] = {
@@ -1655,6 +1658,7 @@ static struct s390_insn opcode_eb[] = {
1655 { "lric", 0x60, INSTR_RSY_RDRM }, 1658 { "lric", 0x60, INSTR_RSY_RDRM },
1656 { "stric", 0x61, INSTR_RSY_RDRM }, 1659 { "stric", 0x61, INSTR_RSY_RDRM },
1657 { "mric", 0x62, INSTR_RSY_RDRM }, 1660 { "mric", 0x62, INSTR_RSY_RDRM },
1661 { { 0, LONG_INSN_STCCTM }, 0x17, INSTR_RSY_RMRD },
1658#endif 1662#endif
1659 { "rll", 0x1d, INSTR_RSY_RRRD }, 1663 { "rll", 0x1d, INSTR_RSY_RRRD },
1660 { "mvclu", 0x8e, INSTR_RSY_RRRD }, 1664 { "mvclu", 0x8e, INSTR_RSY_RRRD },
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 39badb9ca0b3..5c8651f36509 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2074,7 +2074,8 @@ static void do_reset_calls(void)
2074 2074
2075u32 dump_prefix_page; 2075u32 dump_prefix_page;
2076 2076
2077void s390_reset_system(void (*func)(void *), void *data) 2077void s390_reset_system(void (*fn_pre)(void),
2078 void (*fn_post)(void *), void *data)
2078{ 2079{
2079 struct _lowcore *lc; 2080 struct _lowcore *lc;
2080 2081
@@ -2112,7 +2113,11 @@ void s390_reset_system(void (*func)(void *), void *data)
2112 /* Store status at absolute zero */ 2113 /* Store status at absolute zero */
2113 store_status(); 2114 store_status();
2114 2115
2116 /* Call function before reset */
2117 if (fn_pre)
2118 fn_pre();
2115 do_reset_calls(); 2119 do_reset_calls();
2116 if (func) 2120 /* Call function after reset */
2117 func(data); 2121 if (fn_post)
2122 fn_post(data);
2118} 2123}
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 4685337fa7c6..fb0901ec4306 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -103,21 +103,18 @@ static int __init machine_kdump_pm_init(void)
103 return 0; 103 return 0;
104} 104}
105arch_initcall(machine_kdump_pm_init); 105arch_initcall(machine_kdump_pm_init);
106#endif
107 106
108/* 107/*
109 * Start kdump: We expect here that a store status has been done on our CPU 108 * Start kdump: We expect here that a store status has been done on our CPU
110 */ 109 */
111static void __do_machine_kdump(void *image) 110static void __do_machine_kdump(void *image)
112{ 111{
113#ifdef CONFIG_CRASH_DUMP
114 int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; 112 int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
115 113
116 setup_regs();
117 __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); 114 __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
118 start_kdump(1); 115 start_kdump(1);
119#endif
120} 116}
117#endif
121 118
122/* 119/*
123 * Check if kdump checksums are valid: We call purgatory with parameter "0" 120 * Check if kdump checksums are valid: We call purgatory with parameter "0"
@@ -249,18 +246,18 @@ static void __do_machine_kexec(void *data)
249 */ 246 */
250static void __machine_kexec(void *data) 247static void __machine_kexec(void *data)
251{ 248{
252 struct kimage *image = data;
253
254 __arch_local_irq_stosm(0x04); /* enable DAT */ 249 __arch_local_irq_stosm(0x04); /* enable DAT */
255 pfault_fini(); 250 pfault_fini();
256 tracing_off(); 251 tracing_off();
257 debug_locks_off(); 252 debug_locks_off();
258 if (image->type == KEXEC_TYPE_CRASH) { 253#ifdef CONFIG_CRASH_DUMP
254 if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) {
255
259 lgr_info_log(); 256 lgr_info_log();
260 s390_reset_system(__do_machine_kdump, data); 257 s390_reset_system(setup_regs, __do_machine_kdump, data);
261 } else { 258 } else
262 s390_reset_system(__do_machine_kexec, data); 259#endif
263 } 260 s390_reset_system(NULL, __do_machine_kexec, data);
264 disabled_wait((unsigned long) __builtin_return_address(0)); 261 disabled_wait((unsigned long) __builtin_return_address(0));
265} 262}
266 263
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 0b499f5cbe19..370ff3a092a3 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -71,9 +71,30 @@ struct pcpu {
71}; 71};
72 72
73static u8 boot_cpu_type; 73static u8 boot_cpu_type;
74static u16 boot_cpu_address;
75static struct pcpu pcpu_devices[NR_CPUS]; 74static struct pcpu pcpu_devices[NR_CPUS];
76 75
76unsigned int smp_cpu_mt_shift;
77EXPORT_SYMBOL(smp_cpu_mt_shift);
78
79unsigned int smp_cpu_mtid;
80EXPORT_SYMBOL(smp_cpu_mtid);
81
82static unsigned int smp_max_threads __initdata = -1U;
83
84static int __init early_nosmt(char *s)
85{
86 smp_max_threads = 1;
87 return 0;
88}
89early_param("nosmt", early_nosmt);
90
91static int __init early_smt(char *s)
92{
93 get_option(&s, &smp_max_threads);
94 return 0;
95}
96early_param("smt", early_smt);
97
77/* 98/*
78 * The smp_cpu_state_mutex must be held when changing the state or polarization 99 * The smp_cpu_state_mutex must be held when changing the state or polarization
79 * member of a pcpu data structure within the pcpu_devices arreay. 100 * member of a pcpu data structure within the pcpu_devices arreay.
@@ -132,7 +153,7 @@ static inline int pcpu_running(struct pcpu *pcpu)
132/* 153/*
133 * Find struct pcpu by cpu address. 154 * Find struct pcpu by cpu address.
134 */ 155 */
135static struct pcpu *pcpu_find_address(const struct cpumask *mask, int address) 156static struct pcpu *pcpu_find_address(const struct cpumask *mask, u16 address)
136{ 157{
137 int cpu; 158 int cpu;
138 159
@@ -299,6 +320,32 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
299} 320}
300 321
301/* 322/*
323 * Enable additional logical cpus for multi-threading.
324 */
325static int pcpu_set_smt(unsigned int mtid)
326{
327 register unsigned long reg1 asm ("1") = (unsigned long) mtid;
328 int cc;
329
330 if (smp_cpu_mtid == mtid)
331 return 0;
332 asm volatile(
333 " sigp %1,0,%2 # sigp set multi-threading\n"
334 " ipm %0\n"
335 " srl %0,28\n"
336 : "=d" (cc) : "d" (reg1), "K" (SIGP_SET_MULTI_THREADING)
337 : "cc");
338 if (cc == 0) {
339 smp_cpu_mtid = mtid;
340 smp_cpu_mt_shift = 0;
341 while (smp_cpu_mtid >= (1U << smp_cpu_mt_shift))
342 smp_cpu_mt_shift++;
343 pcpu_devices[0].address = stap();
344 }
345 return cc;
346}
347
348/*
302 * Call function on an online CPU. 349 * Call function on an online CPU.
303 */ 350 */
304void smp_call_online_cpu(void (*func)(void *), void *data) 351void smp_call_online_cpu(void (*func)(void *), void *data)
@@ -512,22 +559,17 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
512 559
513#ifdef CONFIG_CRASH_DUMP 560#ifdef CONFIG_CRASH_DUMP
514 561
515static void __init smp_get_save_area(int cpu, u16 address) 562static inline void __smp_store_cpu_state(int cpu, u16 address, int is_boot_cpu)
516{ 563{
517 void *lc = pcpu_devices[0].lowcore; 564 void *lc = pcpu_devices[0].lowcore;
518 struct save_area_ext *sa_ext; 565 struct save_area_ext *sa_ext;
519 unsigned long vx_sa; 566 unsigned long vx_sa;
520 567
521 if (is_kdump_kernel())
522 return;
523 if (!OLDMEM_BASE && (address == boot_cpu_address ||
524 ipl_info.type != IPL_TYPE_FCP_DUMP))
525 return;
526 sa_ext = dump_save_area_create(cpu); 568 sa_ext = dump_save_area_create(cpu);
527 if (!sa_ext) 569 if (!sa_ext)
528 panic("could not allocate memory for save area\n"); 570 panic("could not allocate memory for save area\n");
529 if (address == boot_cpu_address) { 571 if (is_boot_cpu) {
530 /* Copy the registers of the boot cpu. */ 572 /* Copy the registers of the boot CPU. */
531 copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa), 573 copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa),
532 SAVE_AREA_BASE - PAGE_SIZE, 0); 574 SAVE_AREA_BASE - PAGE_SIZE, 0);
533 if (MACHINE_HAS_VX) 575 if (MACHINE_HAS_VX)
@@ -548,6 +590,64 @@ static void __init smp_get_save_area(int cpu, u16 address)
548 free_page(vx_sa); 590 free_page(vx_sa);
549} 591}
550 592
593/*
594 * Collect CPU state of the previous, crashed system.
595 * There are four cases:
596 * 1) standard zfcp dump
597 * condition: OLDMEM_BASE == NULL && ipl_info.type == IPL_TYPE_FCP_DUMP
598 * The state for all CPUs except the boot CPU needs to be collected
599 * with sigp stop-and-store-status. The boot CPU state is located in
600 * the absolute lowcore of the memory stored in the HSA. The zcore code
601 * will allocate the save area and copy the boot CPU state from the HSA.
602 * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory)
603 * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP
604 * The state for all CPUs except the boot CPU needs to be collected
605 * with sigp stop-and-store-status. The firmware or the boot-loader
606 * stored the registers of the boot CPU in the absolute lowcore in the
607 * memory of the old system.
608 * 3) kdump and the old kernel did not store the CPU state,
609 * or stand-alone kdump for DASD
610 * condition: OLDMEM_BASE != NULL && !is_kdump_kernel()
611 * The state for all CPUs except the boot CPU needs to be collected
612 * with sigp stop-and-store-status. The kexec code or the boot-loader
613 * stored the registers of the boot CPU in the memory of the old system.
614 * 4) kdump and the old kernel stored the CPU state
615 * condition: OLDMEM_BASE != NULL && is_kdump_kernel()
616 * The state of all CPUs is stored in ELF sections in the memory of the
617 * old system. The ELF sections are picked up by the crash_dump code
618 * via elfcorehdr_addr.
619 */
620static void __init smp_store_cpu_states(struct sclp_cpu_info *info)
621{
622 unsigned int cpu, address, i, j;
623 int is_boot_cpu;
624
625 if (is_kdump_kernel())
626 /* Previous system stored the CPU states. Nothing to do. */
627 return;
628 if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP))
629 /* No previous system present, normal boot. */
630 return;
631 /* Set multi-threading state to the previous system. */
632 pcpu_set_smt(sclp_get_mtid_prev());
633 /* Collect CPU states. */
634 cpu = 0;
635 for (i = 0; i < info->configured; i++) {
636 /* Skip CPUs with different CPU type. */
637 if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type)
638 continue;
639 for (j = 0; j <= smp_cpu_mtid; j++, cpu++) {
640 address = (info->cpu[i].core_id << smp_cpu_mt_shift) + j;
641 is_boot_cpu = (address == pcpu_devices[0].address);
642 if (is_boot_cpu && !OLDMEM_BASE)
643 /* Skip boot CPU for standard zfcp dump. */
644 continue;
645 /* Get state for this CPu. */
646 __smp_store_cpu_state(cpu, address, is_boot_cpu);
647 }
648 }
649}
650
551int smp_store_status(int cpu) 651int smp_store_status(int cpu)
552{ 652{
553 unsigned long vx_sa; 653 unsigned long vx_sa;
@@ -565,10 +665,6 @@ int smp_store_status(int cpu)
565 return 0; 665 return 0;
566} 666}
567 667
568#else /* CONFIG_CRASH_DUMP */
569
570static inline void smp_get_save_area(int cpu, u16 address) { }
571
572#endif /* CONFIG_CRASH_DUMP */ 668#endif /* CONFIG_CRASH_DUMP */
573 669
574void smp_cpu_set_polarization(int cpu, int val) 670void smp_cpu_set_polarization(int cpu, int val)
@@ -590,11 +686,13 @@ static struct sclp_cpu_info *smp_get_cpu_info(void)
590 info = kzalloc(sizeof(*info), GFP_KERNEL); 686 info = kzalloc(sizeof(*info), GFP_KERNEL);
591 if (info && (use_sigp_detection || sclp_get_cpu_info(info))) { 687 if (info && (use_sigp_detection || sclp_get_cpu_info(info))) {
592 use_sigp_detection = 1; 688 use_sigp_detection = 1;
593 for (address = 0; address <= MAX_CPU_ADDRESS; address++) { 689 for (address = 0; address <= MAX_CPU_ADDRESS;
690 address += (1U << smp_cpu_mt_shift)) {
594 if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == 691 if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) ==
595 SIGP_CC_NOT_OPERATIONAL) 692 SIGP_CC_NOT_OPERATIONAL)
596 continue; 693 continue;
597 info->cpu[info->configured].address = address; 694 info->cpu[info->configured].core_id =
695 address >> smp_cpu_mt_shift;
598 info->configured++; 696 info->configured++;
599 } 697 }
600 info->combined = info->configured; 698 info->combined = info->configured;
@@ -608,7 +706,8 @@ static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add)
608{ 706{
609 struct pcpu *pcpu; 707 struct pcpu *pcpu;
610 cpumask_t avail; 708 cpumask_t avail;
611 int cpu, nr, i; 709 int cpu, nr, i, j;
710 u16 address;
612 711
613 nr = 0; 712 nr = 0;
614 cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); 713 cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask);
@@ -616,51 +715,76 @@ static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add)
616 for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) { 715 for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) {
617 if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type) 716 if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type)
618 continue; 717 continue;
619 if (pcpu_find_address(cpu_present_mask, info->cpu[i].address)) 718 address = info->cpu[i].core_id << smp_cpu_mt_shift;
620 continue; 719 for (j = 0; j <= smp_cpu_mtid; j++) {
621 pcpu = pcpu_devices + cpu; 720 if (pcpu_find_address(cpu_present_mask, address + j))
622 pcpu->address = info->cpu[i].address; 721 continue;
623 pcpu->state = (i >= info->configured) ? 722 pcpu = pcpu_devices + cpu;
624 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; 723 pcpu->address = address + j;
625 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 724 pcpu->state =
626 set_cpu_present(cpu, true); 725 (cpu >= info->configured*(smp_cpu_mtid + 1)) ?
627 if (sysfs_add && smp_add_present_cpu(cpu) != 0) 726 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED;
628 set_cpu_present(cpu, false); 727 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
629 else 728 set_cpu_present(cpu, true);
630 nr++; 729 if (sysfs_add && smp_add_present_cpu(cpu) != 0)
631 cpu = cpumask_next(cpu, &avail); 730 set_cpu_present(cpu, false);
731 else
732 nr++;
733 cpu = cpumask_next(cpu, &avail);
734 if (cpu >= nr_cpu_ids)
735 break;
736 }
632 } 737 }
633 return nr; 738 return nr;
634} 739}
635 740
636static void __init smp_detect_cpus(void) 741static void __init smp_detect_cpus(void)
637{ 742{
638 unsigned int cpu, c_cpus, s_cpus; 743 unsigned int cpu, mtid, c_cpus, s_cpus;
639 struct sclp_cpu_info *info; 744 struct sclp_cpu_info *info;
745 u16 address;
640 746
747 /* Get CPU information */
641 info = smp_get_cpu_info(); 748 info = smp_get_cpu_info();
642 if (!info) 749 if (!info)
643 panic("smp_detect_cpus failed to allocate memory\n"); 750 panic("smp_detect_cpus failed to allocate memory\n");
751
752 /* Find boot CPU type */
644 if (info->has_cpu_type) { 753 if (info->has_cpu_type) {
645 for (cpu = 0; cpu < info->combined; cpu++) { 754 address = stap();
646 if (info->cpu[cpu].address != boot_cpu_address) 755 for (cpu = 0; cpu < info->combined; cpu++)
647 continue; 756 if (info->cpu[cpu].core_id == address) {
648 /* The boot cpu dictates the cpu type. */ 757 /* The boot cpu dictates the cpu type. */
649 boot_cpu_type = info->cpu[cpu].type; 758 boot_cpu_type = info->cpu[cpu].type;
650 break; 759 break;
651 } 760 }
761 if (cpu >= info->combined)
762 panic("Could not find boot CPU type");
652 } 763 }
764
765#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP)
766 /* Collect CPU state of previous system */
767 smp_store_cpu_states(info);
768#endif
769
770 /* Set multi-threading state for the current system */
771 mtid = sclp_get_mtid(boot_cpu_type);
772 mtid = (mtid < smp_max_threads) ? mtid : smp_max_threads - 1;
773 pcpu_set_smt(mtid);
774
775 /* Print number of CPUs */
653 c_cpus = s_cpus = 0; 776 c_cpus = s_cpus = 0;
654 for (cpu = 0; cpu < info->combined; cpu++) { 777 for (cpu = 0; cpu < info->combined; cpu++) {
655 if (info->has_cpu_type && info->cpu[cpu].type != boot_cpu_type) 778 if (info->has_cpu_type && info->cpu[cpu].type != boot_cpu_type)
656 continue; 779 continue;
657 if (cpu < info->configured) { 780 if (cpu < info->configured)
658 smp_get_save_area(c_cpus, info->cpu[cpu].address); 781 c_cpus += smp_cpu_mtid + 1;
659 c_cpus++; 782 else
660 } else 783 s_cpus += smp_cpu_mtid + 1;
661 s_cpus++;
662 } 784 }
663 pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus); 785 pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus);
786
787 /* Add CPUs present at boot */
664 get_online_cpus(); 788 get_online_cpus();
665 __smp_rescan_cpus(info, 0); 789 __smp_rescan_cpus(info, 0);
666 put_online_cpus(); 790 put_online_cpus();
@@ -696,12 +820,23 @@ static void smp_start_secondary(void *cpuvoid)
696int __cpu_up(unsigned int cpu, struct task_struct *tidle) 820int __cpu_up(unsigned int cpu, struct task_struct *tidle)
697{ 821{
698 struct pcpu *pcpu; 822 struct pcpu *pcpu;
699 int rc; 823 int base, i, rc;
700 824
701 pcpu = pcpu_devices + cpu; 825 pcpu = pcpu_devices + cpu;
702 if (pcpu->state != CPU_STATE_CONFIGURED) 826 if (pcpu->state != CPU_STATE_CONFIGURED)
703 return -EIO; 827 return -EIO;
704 if (pcpu_sigp_retry(pcpu, SIGP_INITIAL_CPU_RESET, 0) != 828 base = cpu - (cpu % (smp_cpu_mtid + 1));
829 for (i = 0; i <= smp_cpu_mtid; i++) {
830 if (base + i < nr_cpu_ids)
831 if (cpu_online(base + i))
832 break;
833 }
834 /*
835 * If this is the first CPU of the core to get online
836 * do an initial CPU reset.
837 */
838 if (i > smp_cpu_mtid &&
839 pcpu_sigp_retry(pcpu_devices + base, SIGP_INITIAL_CPU_RESET, 0) !=
705 SIGP_CC_ORDER_CODE_ACCEPTED) 840 SIGP_CC_ORDER_CODE_ACCEPTED)
706 return -EIO; 841 return -EIO;
707 842
@@ -774,7 +909,8 @@ void __init smp_fill_possible_mask(void)
774{ 909{
775 unsigned int possible, sclp, cpu; 910 unsigned int possible, sclp, cpu;
776 911
777 sclp = sclp_get_max_cpu() ?: nr_cpu_ids; 912 sclp = min(smp_max_threads, sclp_get_mtid_max() + 1);
913 sclp = sclp_get_max_cpu()*sclp ?: nr_cpu_ids;
778 possible = setup_possible_cpus ?: nr_cpu_ids; 914 possible = setup_possible_cpus ?: nr_cpu_ids;
779 possible = min(possible, sclp); 915 possible = min(possible, sclp);
780 for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) 916 for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++)
@@ -796,9 +932,8 @@ void __init smp_prepare_boot_cpu(void)
796{ 932{
797 struct pcpu *pcpu = pcpu_devices; 933 struct pcpu *pcpu = pcpu_devices;
798 934
799 boot_cpu_address = stap();
800 pcpu->state = CPU_STATE_CONFIGURED; 935 pcpu->state = CPU_STATE_CONFIGURED;
801 pcpu->address = boot_cpu_address; 936 pcpu->address = stap();
802 pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); 937 pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();
803 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE 938 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE
804 + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); 939 + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
@@ -848,7 +983,7 @@ static ssize_t cpu_configure_store(struct device *dev,
848 const char *buf, size_t count) 983 const char *buf, size_t count)
849{ 984{
850 struct pcpu *pcpu; 985 struct pcpu *pcpu;
851 int cpu, val, rc; 986 int cpu, val, rc, i;
852 char delim; 987 char delim;
853 988
854 if (sscanf(buf, "%d %c", &val, &delim) != 1) 989 if (sscanf(buf, "%d %c", &val, &delim) != 1)
@@ -860,29 +995,43 @@ static ssize_t cpu_configure_store(struct device *dev,
860 rc = -EBUSY; 995 rc = -EBUSY;
861 /* disallow configuration changes of online cpus and cpu 0 */ 996 /* disallow configuration changes of online cpus and cpu 0 */
862 cpu = dev->id; 997 cpu = dev->id;
863 if (cpu_online(cpu) || cpu == 0) 998 cpu -= cpu % (smp_cpu_mtid + 1);
999 if (cpu == 0)
864 goto out; 1000 goto out;
1001 for (i = 0; i <= smp_cpu_mtid; i++)
1002 if (cpu_online(cpu + i))
1003 goto out;
865 pcpu = pcpu_devices + cpu; 1004 pcpu = pcpu_devices + cpu;
866 rc = 0; 1005 rc = 0;
867 switch (val) { 1006 switch (val) {
868 case 0: 1007 case 0:
869 if (pcpu->state != CPU_STATE_CONFIGURED) 1008 if (pcpu->state != CPU_STATE_CONFIGURED)
870 break; 1009 break;
871 rc = sclp_cpu_deconfigure(pcpu->address); 1010 rc = sclp_cpu_deconfigure(pcpu->address >> smp_cpu_mt_shift);
872 if (rc) 1011 if (rc)
873 break; 1012 break;
874 pcpu->state = CPU_STATE_STANDBY; 1013 for (i = 0; i <= smp_cpu_mtid; i++) {
875 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 1014 if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i))
1015 continue;
1016 pcpu[i].state = CPU_STATE_STANDBY;
1017 smp_cpu_set_polarization(cpu + i,
1018 POLARIZATION_UNKNOWN);
1019 }
876 topology_expect_change(); 1020 topology_expect_change();
877 break; 1021 break;
878 case 1: 1022 case 1:
879 if (pcpu->state != CPU_STATE_STANDBY) 1023 if (pcpu->state != CPU_STATE_STANDBY)
880 break; 1024 break;
881 rc = sclp_cpu_configure(pcpu->address); 1025 rc = sclp_cpu_configure(pcpu->address >> smp_cpu_mt_shift);
882 if (rc) 1026 if (rc)
883 break; 1027 break;
884 pcpu->state = CPU_STATE_CONFIGURED; 1028 for (i = 0; i <= smp_cpu_mtid; i++) {
885 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 1029 if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i))
1030 continue;
1031 pcpu[i].state = CPU_STATE_CONFIGURED;
1032 smp_cpu_set_polarization(cpu + i,
1033 POLARIZATION_UNKNOWN);
1034 }
886 topology_expect_change(); 1035 topology_expect_change();
887 break; 1036 break;
888 default: 1037 default:
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index 811f542b8ed4..85565f1ff474 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -194,6 +194,14 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
194 seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); 194 seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved);
195 seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); 195 seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated);
196 seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); 196 seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared);
197 if (info->mt_installed & 0x80) {
198 seq_printf(m, "LPAR CPUs G-MTID: %d\n",
199 info->mt_general & 0x1f);
200 seq_printf(m, "LPAR CPUs S-MTID: %d\n",
201 info->mt_installed & 0x1f);
202 seq_printf(m, "LPAR CPUs PS-MTID: %d\n",
203 info->mt_psmtid & 0x1f);
204 }
197} 205}
198 206
199static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) 207static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info)
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index b93bed76ea94..24ee33f1af24 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -59,32 +59,50 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
59 return mask; 59 return mask;
60} 60}
61 61
62static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 62static cpumask_t cpu_thread_map(unsigned int cpu)
63{
64 cpumask_t mask;
65 int i;
66
67 cpumask_copy(&mask, cpumask_of(cpu));
68 if (!topology_enabled || !MACHINE_HAS_TOPOLOGY)
69 return mask;
70 cpu -= cpu % (smp_cpu_mtid + 1);
71 for (i = 0; i <= smp_cpu_mtid; i++)
72 if (cpu_present(cpu + i))
73 cpumask_set_cpu(cpu + i, &mask);
74 return mask;
75}
76
77static struct mask_info *add_cpus_to_mask(struct topology_core *tl_core,
63 struct mask_info *book, 78 struct mask_info *book,
64 struct mask_info *socket, 79 struct mask_info *socket,
65 int one_socket_per_cpu) 80 int one_socket_per_cpu)
66{ 81{
67 unsigned int cpu; 82 unsigned int core;
68 83
69 for_each_set_bit(cpu, &tl_cpu->mask[0], TOPOLOGY_CPU_BITS) { 84 for_each_set_bit(core, &tl_core->mask[0], TOPOLOGY_CORE_BITS) {
70 unsigned int rcpu; 85 unsigned int rcore;
71 int lcpu; 86 int lcpu, i;
72 87
73 rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin; 88 rcore = TOPOLOGY_CORE_BITS - 1 - core + tl_core->origin;
74 lcpu = smp_find_processor_id(rcpu); 89 lcpu = smp_find_processor_id(rcore << smp_cpu_mt_shift);
75 if (lcpu < 0) 90 if (lcpu < 0)
76 continue; 91 continue;
77 cpumask_set_cpu(lcpu, &book->mask); 92 for (i = 0; i <= smp_cpu_mtid; i++) {
78 cpu_topology[lcpu].book_id = book->id; 93 cpu_topology[lcpu + i].book_id = book->id;
79 cpumask_set_cpu(lcpu, &socket->mask); 94 cpu_topology[lcpu + i].core_id = rcore;
80 cpu_topology[lcpu].core_id = rcpu; 95 cpu_topology[lcpu + i].thread_id = lcpu + i;
81 if (one_socket_per_cpu) { 96 cpumask_set_cpu(lcpu + i, &book->mask);
82 cpu_topology[lcpu].socket_id = rcpu; 97 cpumask_set_cpu(lcpu + i, &socket->mask);
83 socket = socket->next; 98 if (one_socket_per_cpu)
84 } else { 99 cpu_topology[lcpu + i].socket_id = rcore;
85 cpu_topology[lcpu].socket_id = socket->id; 100 else
101 cpu_topology[lcpu + i].socket_id = socket->id;
102 smp_cpu_set_polarization(lcpu + i, tl_core->pp);
86 } 103 }
87 smp_cpu_set_polarization(lcpu, tl_cpu->pp); 104 if (one_socket_per_cpu)
105 socket = socket->next;
88 } 106 }
89 return socket; 107 return socket;
90} 108}
@@ -108,7 +126,7 @@ static void clear_masks(void)
108static union topology_entry *next_tle(union topology_entry *tle) 126static union topology_entry *next_tle(union topology_entry *tle)
109{ 127{
110 if (!tle->nl) 128 if (!tle->nl)
111 return (union topology_entry *)((struct topology_cpu *)tle + 1); 129 return (union topology_entry *)((struct topology_core *)tle + 1);
112 return (union topology_entry *)((struct topology_container *)tle + 1); 130 return (union topology_entry *)((struct topology_container *)tle + 1);
113} 131}
114 132
@@ -231,9 +249,11 @@ static void update_cpu_masks(void)
231 249
232 spin_lock_irqsave(&topology_lock, flags); 250 spin_lock_irqsave(&topology_lock, flags);
233 for_each_possible_cpu(cpu) { 251 for_each_possible_cpu(cpu) {
252 cpu_topology[cpu].thread_mask = cpu_thread_map(cpu);
234 cpu_topology[cpu].core_mask = cpu_group_map(&socket_info, cpu); 253 cpu_topology[cpu].core_mask = cpu_group_map(&socket_info, cpu);
235 cpu_topology[cpu].book_mask = cpu_group_map(&book_info, cpu); 254 cpu_topology[cpu].book_mask = cpu_group_map(&book_info, cpu);
236 if (!MACHINE_HAS_TOPOLOGY) { 255 if (!MACHINE_HAS_TOPOLOGY) {
256 cpu_topology[cpu].thread_id = cpu;
237 cpu_topology[cpu].core_id = cpu; 257 cpu_topology[cpu].core_id = cpu;
238 cpu_topology[cpu].socket_id = cpu; 258 cpu_topology[cpu].socket_id = cpu;
239 cpu_topology[cpu].book_id = cpu; 259 cpu_topology[cpu].book_id = cpu;
@@ -445,6 +465,12 @@ int topology_cpu_init(struct cpu *cpu)
445 return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group); 465 return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group);
446} 466}
447 467
468const struct cpumask *cpu_thread_mask(int cpu)
469{
470 return &cpu_topology[cpu].thread_mask;
471}
472
473
448const struct cpumask *cpu_coregroup_mask(int cpu) 474const struct cpumask *cpu_coregroup_mask(int cpu)
449{ 475{
450 return &cpu_topology[cpu].core_mask; 476 return &cpu_topology[cpu].core_mask;
@@ -456,6 +482,7 @@ static const struct cpumask *cpu_book_mask(int cpu)
456} 482}
457 483
458static struct sched_domain_topology_level s390_topology[] = { 484static struct sched_domain_topology_level s390_topology[] = {
485 { cpu_thread_mask, cpu_smt_flags, SD_INIT_NAME(SMT) },
459 { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, 486 { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
460 { cpu_book_mask, SD_INIT_NAME(BOOK) }, 487 { cpu_book_mask, SD_INIT_NAME(BOOK) },
461 { cpu_cpu_mask, SD_INIT_NAME(DIE) }, 488 { cpu_cpu_mask, SD_INIT_NAME(DIE) },
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index e34122e539a1..e53d3595a7c8 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -15,6 +15,8 @@
15#include <asm/cputime.h> 15#include <asm/cputime.h>
16#include <asm/vtimer.h> 16#include <asm/vtimer.h>
17#include <asm/vtime.h> 17#include <asm/vtime.h>
18#include <asm/cpu_mf.h>
19#include <asm/smp.h>
18 20
19static void virt_timer_expire(void); 21static void virt_timer_expire(void);
20 22
@@ -23,6 +25,10 @@ static DEFINE_SPINLOCK(virt_timer_lock);
23static atomic64_t virt_timer_current; 25static atomic64_t virt_timer_current;
24static atomic64_t virt_timer_elapsed; 26static atomic64_t virt_timer_elapsed;
25 27
28static DEFINE_PER_CPU(u64, mt_cycles[32]);
29static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
30static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
31
26static inline u64 get_vtimer(void) 32static inline u64 get_vtimer(void)
27{ 33{
28 u64 timer; 34 u64 timer;
@@ -61,6 +67,8 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
61{ 67{
62 struct thread_info *ti = task_thread_info(tsk); 68 struct thread_info *ti = task_thread_info(tsk);
63 u64 timer, clock, user, system, steal; 69 u64 timer, clock, user, system, steal;
70 u64 user_scaled, system_scaled;
71 int i;
64 72
65 timer = S390_lowcore.last_update_timer; 73 timer = S390_lowcore.last_update_timer;
66 clock = S390_lowcore.last_update_clock; 74 clock = S390_lowcore.last_update_clock;
@@ -76,15 +84,49 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
76 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 84 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
77 S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock; 85 S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock;
78 86
87 /* Do MT utilization calculation */
88 if (smp_cpu_mtid) {
89 u64 cycles_new[32], *cycles_old;
90 u64 delta, mult, div;
91
92 cycles_old = this_cpu_ptr(mt_cycles);
93 if (stcctm5(smp_cpu_mtid + 1, cycles_new) < 2) {
94 mult = div = 0;
95 for (i = 0; i <= smp_cpu_mtid; i++) {
96 delta = cycles_new[i] - cycles_old[i];
97 mult += delta;
98 div += (i + 1) * delta;
99 }
100 if (mult > 0) {
101 /* Update scaling factor */
102 __this_cpu_write(mt_scaling_mult, mult);
103 __this_cpu_write(mt_scaling_div, div);
104 memcpy(cycles_old, cycles_new,
105 sizeof(u64) * (smp_cpu_mtid + 1));
106 }
107 }
108 }
109
79 user = S390_lowcore.user_timer - ti->user_timer; 110 user = S390_lowcore.user_timer - ti->user_timer;
80 S390_lowcore.steal_timer -= user; 111 S390_lowcore.steal_timer -= user;
81 ti->user_timer = S390_lowcore.user_timer; 112 ti->user_timer = S390_lowcore.user_timer;
82 account_user_time(tsk, user, user);
83 113
84 system = S390_lowcore.system_timer - ti->system_timer; 114 system = S390_lowcore.system_timer - ti->system_timer;
85 S390_lowcore.steal_timer -= system; 115 S390_lowcore.steal_timer -= system;
86 ti->system_timer = S390_lowcore.system_timer; 116 ti->system_timer = S390_lowcore.system_timer;
87 account_system_time(tsk, hardirq_offset, system, system); 117
118 user_scaled = user;
119 system_scaled = system;
120 /* Do MT utilization scaling */
121 if (smp_cpu_mtid) {
122 u64 mult = __this_cpu_read(mt_scaling_mult);
123 u64 div = __this_cpu_read(mt_scaling_div);
124
125 user_scaled = (user_scaled * mult) / div;
126 system_scaled = (system_scaled * mult) / div;
127 }
128 account_user_time(tsk, user, user_scaled);
129 account_system_time(tsk, hardirq_offset, system, system_scaled);
88 130
89 steal = S390_lowcore.steal_timer; 131 steal = S390_lowcore.steal_timer;
90 if ((s64) steal > 0) { 132 if ((s64) steal > 0) {
@@ -126,7 +168,7 @@ void vtime_account_user(struct task_struct *tsk)
126void vtime_account_irq_enter(struct task_struct *tsk) 168void vtime_account_irq_enter(struct task_struct *tsk)
127{ 169{
128 struct thread_info *ti = task_thread_info(tsk); 170 struct thread_info *ti = task_thread_info(tsk);
129 u64 timer, system; 171 u64 timer, system, system_scaled;
130 172
131 timer = S390_lowcore.last_update_timer; 173 timer = S390_lowcore.last_update_timer;
132 S390_lowcore.last_update_timer = get_vtimer(); 174 S390_lowcore.last_update_timer = get_vtimer();
@@ -135,7 +177,15 @@ void vtime_account_irq_enter(struct task_struct *tsk)
135 system = S390_lowcore.system_timer - ti->system_timer; 177 system = S390_lowcore.system_timer - ti->system_timer;
136 S390_lowcore.steal_timer -= system; 178 S390_lowcore.steal_timer -= system;
137 ti->system_timer = S390_lowcore.system_timer; 179 ti->system_timer = S390_lowcore.system_timer;
138 account_system_time(tsk, 0, system, system); 180 system_scaled = system;
181 /* Do MT utilization scaling */
182 if (smp_cpu_mtid) {
183 u64 mult = __this_cpu_read(mt_scaling_mult);
184 u64 div = __this_cpu_read(mt_scaling_div);
185
186 system_scaled = (system_scaled * mult) / div;
187 }
188 account_system_time(tsk, 0, system, system_scaled);
139 189
140 virt_timer_forward(system); 190 virt_timer_forward(system);
141} 191}
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index 5bd6cb145a87..daf6cd5079ec 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -20,26 +20,31 @@ struct read_info_sccb {
20 struct sccb_header header; /* 0-7 */ 20 struct sccb_header header; /* 0-7 */
21 u16 rnmax; /* 8-9 */ 21 u16 rnmax; /* 8-9 */
22 u8 rnsize; /* 10 */ 22 u8 rnsize; /* 10 */
23 u8 _reserved0[16 - 11]; /* 11-15 */ 23 u8 _pad_11[16 - 11]; /* 11-15 */
24 u16 ncpurl; /* 16-17 */ 24 u16 ncpurl; /* 16-17 */
25 u16 cpuoff; /* 18-19 */ 25 u16 cpuoff; /* 18-19 */
26 u8 _reserved7[24 - 20]; /* 20-23 */ 26 u8 _pad_20[24 - 20]; /* 20-23 */
27 u8 loadparm[8]; /* 24-31 */ 27 u8 loadparm[8]; /* 24-31 */
28 u8 _reserved1[48 - 32]; /* 32-47 */ 28 u8 _pad_32[42 - 32]; /* 32-41 */
29 u8 fac42; /* 42 */
30 u8 fac43; /* 43 */
31 u8 _pad_44[48 - 44]; /* 44-47 */
29 u64 facilities; /* 48-55 */ 32 u64 facilities; /* 48-55 */
30 u8 _reserved2a[76 - 56]; /* 56-75 */ 33 u8 _pad_56[66 - 56]; /* 56-65 */
34 u8 fac66; /* 66 */
35 u8 _pad_67[76 - 67]; /* 67-83 */
31 u32 ibc; /* 76-79 */ 36 u32 ibc; /* 76-79 */
32 u8 _reserved2b[84 - 80]; /* 80-83 */ 37 u8 _pad80[84 - 80]; /* 80-83 */
33 u8 fac84; /* 84 */ 38 u8 fac84; /* 84 */
34 u8 fac85; /* 85 */ 39 u8 fac85; /* 85 */
35 u8 _reserved3[91 - 86]; /* 86-90 */ 40 u8 _pad_86[91 - 86]; /* 86-90 */
36 u8 flags; /* 91 */ 41 u8 flags; /* 91 */
37 u8 _reserved4[100 - 92]; /* 92-99 */ 42 u8 _pad_92[100 - 92]; /* 92-99 */
38 u32 rnsize2; /* 100-103 */ 43 u32 rnsize2; /* 100-103 */
39 u64 rnmax2; /* 104-111 */ 44 u64 rnmax2; /* 104-111 */
40 u8 _reserved5[120 - 112]; /* 112-119 */ 45 u8 _pad_112[120 - 112]; /* 112-119 */
41 u16 hcpua; /* 120-121 */ 46 u16 hcpua; /* 120-121 */
42 u8 _reserved6[4096 - 122]; /* 122-4095 */ 47 u8 _pad_122[4096 - 122]; /* 122-4095 */
43} __packed __aligned(PAGE_SIZE); 48} __packed __aligned(PAGE_SIZE);
44 49
45static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; 50static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
@@ -50,6 +55,10 @@ static unsigned int sclp_max_cpu;
50static struct sclp_ipl_info sclp_ipl_info; 55static struct sclp_ipl_info sclp_ipl_info;
51static unsigned char sclp_siif; 56static unsigned char sclp_siif;
52static u32 sclp_ibc; 57static u32 sclp_ibc;
58static unsigned int sclp_mtid;
59static unsigned int sclp_mtid_cp;
60static unsigned int sclp_mtid_max;
61static unsigned int sclp_mtid_prev;
53 62
54u64 sclp_facilities; 63u64 sclp_facilities;
55u8 sclp_fac84; 64u8 sclp_fac84;
@@ -128,7 +137,7 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
128 boot_cpu_address = stap(); 137 boot_cpu_address = stap();
129 cpue = (void *)sccb + sccb->cpuoff; 138 cpue = (void *)sccb + sccb->cpuoff;
130 for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { 139 for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) {
131 if (boot_cpu_address != cpue->address) 140 if (boot_cpu_address != cpue->core_id)
132 continue; 141 continue;
133 sclp_siif = cpue->siif; 142 sclp_siif = cpue->siif;
134 break; 143 break;
@@ -139,6 +148,11 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
139 if (sccb->flags & 0x2) 148 if (sccb->flags & 0x2)
140 sclp_ipl_info.has_dump = 1; 149 sclp_ipl_info.has_dump = 1;
141 memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); 150 memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN);
151
152 sclp_mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0;
153 sclp_mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0;
154 sclp_mtid_max = max(sclp_mtid, sclp_mtid_cp);
155 sclp_mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0;
142} 156}
143 157
144bool __init sclp_has_linemode(void) 158bool __init sclp_has_linemode(void)
@@ -178,6 +192,21 @@ unsigned int sclp_get_ibc(void)
178} 192}
179EXPORT_SYMBOL(sclp_get_ibc); 193EXPORT_SYMBOL(sclp_get_ibc);
180 194
195unsigned int sclp_get_mtid(u8 cpu_type)
196{
197 return cpu_type ? sclp_mtid : sclp_mtid_cp;
198}
199
200unsigned int sclp_get_mtid_max(void)
201{
202 return sclp_mtid_max;
203}
204
205unsigned int sclp_get_mtid_prev(void)
206{
207 return sclp_mtid_prev;
208}
209
181/* 210/*
182 * This function will be called after sclp_facilities_detect(), which gets 211 * This function will be called after sclp_facilities_detect(), which gets
183 * called from early.c code. The sclp_facilities_detect() function retrieves 212 * called from early.c code. The sclp_facilities_detect() function retrieves
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 10eb738fc81a..3578105989a0 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -938,7 +938,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
938{ 938{
939 struct subchannel_id uninitialized_var(schid); 939 struct subchannel_id uninitialized_var(schid);
940 940
941 s390_reset_system(NULL, NULL); 941 s390_reset_system(NULL, NULL, NULL);
942 if (reipl_find_schid(devid, &schid) != 0) 942 if (reipl_find_schid(devid, &schid) != 0)
943 panic("IPL Device not found\n"); 943 panic("IPL Device not found\n");
944 do_reipl_asm(*((__u32*)&schid)); 944 do_reipl_asm(*((__u32*)&schid));