diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-04-11 13:15:24 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-10-09 05:21:12 -0400 |
commit | 54c57795e848100a2502b7a39b12b784292f4576 (patch) | |
tree | ae93ff66373017b80bbeecd2bc74aa5e04746246 | |
parent | cd45c995610420755c5fe0d09afee3106c586e26 (diff) |
s390/mem_detect: replace tprot loop with binary search
In a situation when other memory detection methods are not available
(no SCLP and no z/VM diag260), continuous online memory is assumed.
Replacing tprot loop with faster binary search, as only online memory
end has to be found.
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/boot/mem_detect.c | 49 | ||||
-rw-r--r-- | arch/s390/include/asm/mem_detect.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/sclp.h | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_early_core.c | 3 |
4 files changed, 20 insertions, 36 deletions
diff --git a/arch/s390/boot/mem_detect.c b/arch/s390/boot/mem_detect.c index 3becf6bbe4c7..65ae3c926042 100644 --- a/arch/s390/boot/mem_detect.c +++ b/arch/s390/boot/mem_detect.c | |||
@@ -3,12 +3,10 @@ | |||
3 | #include <asm/sclp.h> | 3 | #include <asm/sclp.h> |
4 | #include <asm/sections.h> | 4 | #include <asm/sections.h> |
5 | #include <asm/mem_detect.h> | 5 | #include <asm/mem_detect.h> |
6 | #include <asm/sparsemem.h> | ||
6 | #include "compressed/decompressor.h" | 7 | #include "compressed/decompressor.h" |
7 | #include "boot.h" | 8 | #include "boot.h" |
8 | 9 | ||
9 | #define CHUNK_READ_WRITE 0 | ||
10 | #define CHUNK_READ_ONLY 1 | ||
11 | |||
12 | unsigned long __bootdata(max_physmem_end); | 10 | unsigned long __bootdata(max_physmem_end); |
13 | struct mem_detect_info __bootdata(mem_detect); | 11 | struct mem_detect_info __bootdata(mem_detect); |
14 | 12 | ||
@@ -141,38 +139,25 @@ static int tprot(unsigned long addr) | |||
141 | return rc; | 139 | return rc; |
142 | } | 140 | } |
143 | 141 | ||
144 | static void scan_memory(unsigned long rzm) | 142 | static void search_mem_end(void) |
145 | { | 143 | { |
146 | unsigned long addr, size; | 144 | unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */ |
147 | int type; | 145 | unsigned long offset = 0; |
148 | 146 | unsigned long pivot; | |
149 | if (!rzm) | 147 | |
150 | rzm = 1UL << 20; | 148 | while (range > 1) { |
151 | 149 | range >>= 1; | |
152 | addr = 0; | 150 | pivot = offset + range; |
153 | do { | 151 | if (!tprot(pivot << 20)) |
154 | size = 0; | 152 | offset = pivot; |
155 | /* assume lowcore is writable */ | 153 | } |
156 | type = addr ? tprot(addr) : CHUNK_READ_WRITE; | 154 | |
157 | do { | 155 | add_mem_detect_block(0, (offset + 1) << 20); |
158 | size += rzm; | ||
159 | if (max_physmem_end && addr + size >= max_physmem_end) | ||
160 | break; | ||
161 | } while (type == tprot(addr + size)); | ||
162 | if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { | ||
163 | if (max_physmem_end && (addr + size > max_physmem_end)) | ||
164 | size = max_physmem_end - addr; | ||
165 | add_mem_detect_block(addr, addr + size); | ||
166 | } | ||
167 | addr += size; | ||
168 | } while (addr < max_physmem_end); | ||
169 | } | 156 | } |
170 | 157 | ||
171 | void detect_memory(void) | 158 | void detect_memory(void) |
172 | { | 159 | { |
173 | unsigned long rzm; | 160 | sclp_early_get_memsize(&max_physmem_end); |
174 | |||
175 | sclp_early_get_meminfo(&max_physmem_end, &rzm); | ||
176 | 161 | ||
177 | if (!sclp_early_read_storage_info()) { | 162 | if (!sclp_early_read_storage_info()) { |
178 | mem_detect.info_source = MEM_DETECT_SCLP_STOR_INFO; | 163 | mem_detect.info_source = MEM_DETECT_SCLP_STOR_INFO; |
@@ -190,7 +175,7 @@ void detect_memory(void) | |||
190 | return; | 175 | return; |
191 | } | 176 | } |
192 | 177 | ||
193 | scan_memory(rzm); | 178 | search_mem_end(); |
194 | mem_detect.info_source = MEM_DETECT_TPROT_LOOP; | 179 | mem_detect.info_source = MEM_DETECT_BIN_SEARCH; |
195 | max_physmem_end = get_mem_detect_end(); | 180 | max_physmem_end = get_mem_detect_end(); |
196 | } | 181 | } |
diff --git a/arch/s390/include/asm/mem_detect.h b/arch/s390/include/asm/mem_detect.h index 153c3542fa8a..6114b92ab667 100644 --- a/arch/s390/include/asm/mem_detect.h +++ b/arch/s390/include/asm/mem_detect.h | |||
@@ -9,7 +9,7 @@ enum mem_info_source { | |||
9 | MEM_DETECT_SCLP_STOR_INFO, | 9 | MEM_DETECT_SCLP_STOR_INFO, |
10 | MEM_DETECT_DIAG260, | 10 | MEM_DETECT_DIAG260, |
11 | MEM_DETECT_SCLP_READ_INFO, | 11 | MEM_DETECT_SCLP_READ_INFO, |
12 | MEM_DETECT_TPROT_LOOP | 12 | MEM_DETECT_BIN_SEARCH |
13 | }; | 13 | }; |
14 | 14 | ||
15 | struct mem_detect_block { | 15 | struct mem_detect_block { |
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index e0da13c0ef79..32b683f6992f 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
@@ -114,7 +114,7 @@ void sclp_early_printk(const char *s); | |||
114 | void sclp_early_printk_force(const char *s); | 114 | void sclp_early_printk_force(const char *s); |
115 | void __sclp_early_printk(const char *s, unsigned int len, unsigned int force); | 115 | void __sclp_early_printk(const char *s, unsigned int len, unsigned int force); |
116 | 116 | ||
117 | int sclp_early_get_meminfo(unsigned long *mem, unsigned long *rzm); | 117 | int sclp_early_get_memsize(unsigned long *mem); |
118 | int _sclp_get_core_info(struct sclp_core_info *info); | 118 | int _sclp_get_core_info(struct sclp_core_info *info); |
119 | int sclp_core_configure(u8 core); | 119 | int sclp_core_configure(u8 core); |
120 | int sclp_core_deconfigure(u8 core); | 120 | int sclp_core_deconfigure(u8 core); |
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index 0df08dcb9fe8..acfe09313852 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c | |||
@@ -272,7 +272,7 @@ int __init sclp_early_get_info(struct read_info_sccb *info) | |||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | int __init sclp_early_get_meminfo(unsigned long *mem, unsigned long *rzm) | 275 | int __init sclp_early_get_memsize(unsigned long *mem) |
276 | { | 276 | { |
277 | unsigned long rnmax; | 277 | unsigned long rnmax; |
278 | unsigned long rnsize; | 278 | unsigned long rnsize; |
@@ -285,7 +285,6 @@ int __init sclp_early_get_meminfo(unsigned long *mem, unsigned long *rzm) | |||
285 | rnsize = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; | 285 | rnsize = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; |
286 | rnsize <<= 20; | 286 | rnsize <<= 20; |
287 | *mem = rnsize * rnmax; | 287 | *mem = rnsize * rnmax; |
288 | *rzm = rnsize; | ||
289 | return 0; | 288 | return 0; |
290 | } | 289 | } |
291 | 290 | ||