summary refs log tree commit diff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-14 17:52:10 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-22 12:16:01 +0100
commit10ad34bc76dfbc49bda327a13012f6754c0c72e0 (patch)
tree4d76fb6882da2eb3e77b53c4fe64f6367ffbd79d /drivers/s390/char
parent1f6b83e5e4d3aed46eac1d219322fba9c7341cd8 (diff)
downloadlinux-10ad34bc76dfbc49bda327a13012f6754c0c72e0.tar.gz
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>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp_early.c49
1 files changed, 39 insertions, 10 deletions
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 {
 	struct	sccb_header header;	/* 0-7 */
 	u16	rnmax;			/* 8-9 */
 	u8	rnsize;			/* 10 */
-	u8	_reserved0[16 - 11];	/* 11-15 */
+	u8	_pad_11[16 - 11];	/* 11-15 */
 	u16	ncpurl;			/* 16-17 */
 	u16	cpuoff;			/* 18-19 */
-	u8	_reserved7[24 - 20];	/* 20-23 */
+	u8	_pad_20[24 - 20];	/* 20-23 */
 	u8	loadparm[8];		/* 24-31 */
-	u8	_reserved1[48 - 32];	/* 32-47 */
+	u8	_pad_32[42 - 32];	/* 32-41 */
+	u8	fac42;			/* 42 */
+	u8	fac43;			/* 43 */
+	u8	_pad_44[48 - 44];	/* 44-47 */
 	u64	facilities;		/* 48-55 */
-	u8	_reserved2a[76 - 56];	/* 56-75 */
+	u8	_pad_56[66 - 56];	/* 56-65 */
+	u8	fac66;			/* 66 */
+	u8	_pad_67[76 - 67];	/* 67-83 */
 	u32	ibc;			/* 76-79 */
-	u8	_reserved2b[84 - 80];	/* 80-83 */
+	u8	_pad80[84 - 80];	/* 80-83 */
 	u8	fac84;			/* 84 */
 	u8	fac85;			/* 85 */
-	u8	_reserved3[91 - 86];	/* 86-90 */
+	u8	_pad_86[91 - 86];	/* 86-90 */
 	u8	flags;			/* 91 */
-	u8	_reserved4[100 - 92];	/* 92-99 */
+	u8	_pad_92[100 - 92];	/* 92-99 */
 	u32	rnsize2;		/* 100-103 */
 	u64	rnmax2;			/* 104-111 */
-	u8	_reserved5[120 - 112];	/* 112-119 */
+	u8	_pad_112[120 - 112];	/* 112-119 */
 	u16	hcpua;			/* 120-121 */
-	u8	_reserved6[4096 - 122];	/* 122-4095 */
+	u8	_pad_122[4096 - 122];	/* 122-4095 */
 } __packed __aligned(PAGE_SIZE);
 
 static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
@@ -50,6 +55,10 @@ static unsigned int sclp_max_cpu;
 static struct sclp_ipl_info sclp_ipl_info;
 static unsigned char sclp_siif;
 static u32 sclp_ibc;
+static unsigned int sclp_mtid;
+static unsigned int sclp_mtid_cp;
+static unsigned int sclp_mtid_max;
+static unsigned int sclp_mtid_prev;
 
 u64 sclp_facilities;
 u8 sclp_fac84;
@@ -128,7 +137,7 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
 	boot_cpu_address = stap();
 	cpue = (void *)sccb + sccb->cpuoff;
 	for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) {
-		if (boot_cpu_address != cpue->address)
+		if (boot_cpu_address != cpue->core_id)
 			continue;
 		sclp_siif = cpue->siif;
 		break;
@@ -139,6 +148,11 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
 	if (sccb->flags & 0x2)
 		sclp_ipl_info.has_dump = 1;
 	memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN);
+
+	sclp_mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0;
+	sclp_mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0;
+	sclp_mtid_max = max(sclp_mtid, sclp_mtid_cp);
+	sclp_mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0;
 }
 
 bool __init sclp_has_linemode(void)
@@ -178,6 +192,21 @@ unsigned int sclp_get_ibc(void)
 }
 EXPORT_SYMBOL(sclp_get_ibc);
 
+unsigned int sclp_get_mtid(u8 cpu_type)
+{
+	return cpu_type ? sclp_mtid : sclp_mtid_cp;
+}
+
+unsigned int sclp_get_mtid_max(void)
+{
+	return sclp_mtid_max;
+}
+
+unsigned int sclp_get_mtid_prev(void)
+{
+	return sclp_mtid_prev;
+}
+
 /*
  * This function will be called after sclp_facilities_detect(), which gets
  * called from early.c code. The sclp_facilities_detect() function retrieves