aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-10 09:50:16 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-03-17 10:53:06 -0400
commitcf813db0b448b45b454f0983329c3c7b007f9ab7 (patch)
tree2ccbddbc0c1494d92e4fa4f1c2f7d337595e1dd2
parent36a554021b44d146178ae98e598c9502a1269f7d (diff)
s390/smp: limit number of cpus in possible cpu mask
Limit the number of bits to the maximum number of cpus a machine can have. possible_cpu_mask typically will have more bits set than a machine may physically have. This results in wasted memory during per-cpu memory allocations, if the possible mask contains more cpus than physically possible for a given configuration. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/sclp.h1
-rw-r--r--arch/s390/kernel/smp.c8
-rw-r--r--drivers/s390/char/sclp_early.c23
3 files changed, 26 insertions, 6 deletions
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index abaca2275c7a..2f5e9932b4de 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -46,6 +46,7 @@ int sclp_cpu_configure(u8 cpu);
46int sclp_cpu_deconfigure(u8 cpu); 46int sclp_cpu_deconfigure(u8 cpu);
47unsigned long long sclp_get_rnmax(void); 47unsigned long long sclp_get_rnmax(void);
48unsigned long long sclp_get_rzm(void); 48unsigned long long sclp_get_rzm(void);
49unsigned int sclp_get_max_cpu(void);
49int sclp_sdias_blk_count(void); 50int sclp_sdias_blk_count(void);
50int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 51int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
51int sclp_chp_configure(struct chp_id chpid); 52int sclp_chp_configure(struct chp_id chpid);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index a7125b62a9a6..8827883310dd 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -773,11 +773,11 @@ void __noreturn cpu_die(void)
773 773
774void __init smp_fill_possible_mask(void) 774void __init smp_fill_possible_mask(void)
775{ 775{
776 unsigned int possible, cpu; 776 unsigned int possible, sclp, cpu;
777 777
778 possible = setup_possible_cpus; 778 sclp = sclp_get_max_cpu() ?: nr_cpu_ids;
779 if (!possible) 779 possible = setup_possible_cpus ?: nr_cpu_ids;
780 possible = MACHINE_IS_VM ? 64 : nr_cpu_ids; 780 possible = min(possible, sclp);
781 for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) 781 for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++)
782 set_cpu_possible(cpu, true); 782 set_cpu_possible(cpu, true);
783} 783}
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index 2c6aac66e2b0..14196ea0fdf3 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -20,7 +20,9 @@ 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[24 - 11]; /* 11-15 */ 23 u8 _reserved0[16 - 11]; /* 11-15 */
24 u16 ncpurl; /* 16-17 */
25 u8 _reserved7[24 - 18]; /* 18-23 */
24 u8 loadparm[8]; /* 24-31 */ 26 u8 loadparm[8]; /* 24-31 */
25 u8 _reserved1[48 - 32]; /* 32-47 */ 27 u8 _reserved1[48 - 32]; /* 32-47 */
26 u64 facilities; /* 48-55 */ 28 u64 facilities; /* 48-55 */
@@ -32,13 +34,16 @@ struct read_info_sccb {
32 u8 _reserved4[100 - 92]; /* 92-99 */ 34 u8 _reserved4[100 - 92]; /* 92-99 */
33 u32 rnsize2; /* 100-103 */ 35 u32 rnsize2; /* 100-103 */
34 u64 rnmax2; /* 104-111 */ 36 u64 rnmax2; /* 104-111 */
35 u8 _reserved5[4096 - 112]; /* 112-4095 */ 37 u8 _reserved5[120 - 112]; /* 112-119 */
38 u16 hcpua; /* 120-121 */
39 u8 _reserved6[4096 - 122]; /* 122-4095 */
36} __packed __aligned(PAGE_SIZE); 40} __packed __aligned(PAGE_SIZE);
37 41
38static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; 42static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
39static unsigned int sclp_con_has_vt220 __initdata; 43static unsigned int sclp_con_has_vt220 __initdata;
40static unsigned int sclp_con_has_linemode __initdata; 44static unsigned int sclp_con_has_linemode __initdata;
41static unsigned long sclp_hsa_size; 45static unsigned long sclp_hsa_size;
46static unsigned int sclp_max_cpu;
42static struct sclp_ipl_info sclp_ipl_info; 47static struct sclp_ipl_info sclp_ipl_info;
43 48
44u64 sclp_facilities; 49u64 sclp_facilities;
@@ -102,6 +107,15 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
102 sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 107 sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
103 sclp_rzm <<= 20; 108 sclp_rzm <<= 20;
104 109
110 if (!sccb->hcpua) {
111 if (MACHINE_IS_VM)
112 sclp_max_cpu = 64;
113 else
114 sclp_max_cpu = sccb->ncpurl;
115 } else {
116 sclp_max_cpu = sccb->hcpua + 1;
117 }
118
105 /* Save IPL information */ 119 /* Save IPL information */
106 sclp_ipl_info.is_valid = 1; 120 sclp_ipl_info.is_valid = 1;
107 if (sccb->flags & 0x2) 121 if (sccb->flags & 0x2)
@@ -129,6 +143,11 @@ unsigned long long sclp_get_rzm(void)
129 return sclp_rzm; 143 return sclp_rzm;
130} 144}
131 145
146unsigned int sclp_get_max_cpu(void)
147{
148 return sclp_max_cpu;
149}
150
132/* 151/*
133 * This function will be called after sclp_facilities_detect(), which gets 152 * This function will be called after sclp_facilities_detect(), which gets
134 * called from early.c code. The sclp_facilities_detect() function retrieves 153 * called from early.c code. The sclp_facilities_detect() function retrieves