aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorMike Rapoport <rppt@linux.vnet.ibm.com>2018-10-26 18:05:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-26 19:25:20 -0400
commit6471f52af786fc9cb82bf1af9d086fb09c62f99b (patch)
treeb70ab067e61c24c63b3788eb36d2c2994f291f8c /arch/alpha
parente92d39cdb120219a16502ca646d407d61cd7adf4 (diff)
alpha: switch to NO_BOOTMEM
Replace bootmem allocator with memblock and enable use of NO_BOOTMEM like on most other architectures. Alpha gets the description of the physical memory from the firmware as an array of memory clusters. Each cluster that is not reserved by the firmware is added to memblock.memory. Once the memblock.memory is set up, we reserve the kernel and initrd pages with memblock reserve. Since we don't need the bootmem bitmap anymore, the code that finds an appropriate place is removed. The conversion does not take care of NUMA support which is marked broken for more than 10 years now. Link: http://lkml.kernel.org/r/1535952894-10967-1-git-send-email-rppt@linux.vnet.ibm.com Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Michal Hocko <mhocko@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/kernel/core_irongate.c4
-rw-r--r--arch/alpha/kernel/setup.c98
-rw-r--r--arch/alpha/mm/numa.c113
4 files changed, 29 insertions, 188 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 5b4f88363453..620b0a711ee4 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -31,6 +31,8 @@ config ALPHA
31 select ODD_RT_SIGACTION 31 select ODD_RT_SIGACTION
32 select OLD_SIGSUSPEND 32 select OLD_SIGSUSPEND
33 select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67 33 select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
34 select HAVE_MEMBLOCK
35 select NO_BOOTMEM
34 help 36 help
35 The Alpha is a 64-bit general-purpose processor designed and 37 The Alpha is a 64-bit general-purpose processor designed and
36 marketed by the Digital Equipment Corporation of blessed memory, 38 marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index aec757250e07..f70986683fc6 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/initrd.h> 22#include <linux/initrd.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/memblock.h>
24 25
25#include <asm/ptrace.h> 26#include <asm/ptrace.h>
26#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
@@ -241,8 +242,7 @@ albacore_init_arch(void)
241 size / 1024); 242 size / 1024);
242 } 243 }
243#endif 244#endif
244 reserve_bootmem_node(NODE_DATA(0), pci_mem, memtop - 245 memblock_reserve(pci_mem, memtop - pci_mem);
245 pci_mem, BOOTMEM_DEFAULT);
246 printk("irongate_init_arch: temporarily reserving " 246 printk("irongate_init_arch: temporarily reserving "
247 "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1); 247 "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
248 } 248 }
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 5576f7646fb6..4f0d94471bc9 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -30,6 +30,7 @@
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/bootmem.h> 32#include <linux/bootmem.h>
33#include <linux/memblock.h>
33#include <linux/pci.h> 34#include <linux/pci.h>
34#include <linux/seq_file.h> 35#include <linux/seq_file.h>
35#include <linux/root_dev.h> 36#include <linux/root_dev.h>
@@ -312,9 +313,7 @@ setup_memory(void *kernel_end)
312{ 313{
313 struct memclust_struct * cluster; 314 struct memclust_struct * cluster;
314 struct memdesc_struct * memdesc; 315 struct memdesc_struct * memdesc;
315 unsigned long start_kernel_pfn, end_kernel_pfn; 316 unsigned long kernel_size;
316 unsigned long bootmap_size, bootmap_pages, bootmap_start;
317 unsigned long start, end;
318 unsigned long i; 317 unsigned long i;
319 318
320 /* Find free clusters, and init and free the bootmem accordingly. */ 319 /* Find free clusters, and init and free the bootmem accordingly. */
@@ -322,6 +321,8 @@ setup_memory(void *kernel_end)
322 (hwrpb->mddt_offset + (unsigned long) hwrpb); 321 (hwrpb->mddt_offset + (unsigned long) hwrpb);
323 322
324 for_each_mem_cluster(memdesc, cluster, i) { 323 for_each_mem_cluster(memdesc, cluster, i) {
324 unsigned long end;
325
325 printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n", 326 printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n",
326 i, cluster->usage, cluster->start_pfn, 327 i, cluster->usage, cluster->start_pfn,
327 cluster->start_pfn + cluster->numpages); 328 cluster->start_pfn + cluster->numpages);
@@ -335,6 +336,9 @@ setup_memory(void *kernel_end)
335 end = cluster->start_pfn + cluster->numpages; 336 end = cluster->start_pfn + cluster->numpages;
336 if (end > max_low_pfn) 337 if (end > max_low_pfn)
337 max_low_pfn = end; 338 max_low_pfn = end;
339
340 memblock_add(PFN_PHYS(cluster->start_pfn),
341 cluster->numpages << PAGE_SHIFT);
338 } 342 }
339 343
340 /* 344 /*
@@ -363,87 +367,9 @@ setup_memory(void *kernel_end)
363 max_low_pfn = mem_size_limit; 367 max_low_pfn = mem_size_limit;
364 } 368 }
365 369
366 /* Find the bounds of kernel memory. */ 370 /* Reserve the kernel memory. */
367 start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS); 371 kernel_size = virt_to_phys(kernel_end) - KERNEL_START_PHYS;
368 end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end)); 372 memblock_reserve(KERNEL_START_PHYS, kernel_size);
369 bootmap_start = -1;
370
371 try_again:
372 if (max_low_pfn <= end_kernel_pfn)
373 panic("not enough memory to boot");
374
375 /* We need to know how many physically contiguous pages
376 we'll need for the bootmap. */
377 bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
378
379 /* Now find a good region where to allocate the bootmap. */
380 for_each_mem_cluster(memdesc, cluster, i) {
381 if (cluster->usage & 3)
382 continue;
383
384 start = cluster->start_pfn;
385 end = start + cluster->numpages;
386 if (start >= max_low_pfn)
387 continue;
388 if (end > max_low_pfn)
389 end = max_low_pfn;
390 if (start < start_kernel_pfn) {
391 if (end > end_kernel_pfn
392 && end - end_kernel_pfn >= bootmap_pages) {
393 bootmap_start = end_kernel_pfn;
394 break;
395 } else if (end > start_kernel_pfn)
396 end = start_kernel_pfn;
397 } else if (start < end_kernel_pfn)
398 start = end_kernel_pfn;
399 if (end - start >= bootmap_pages) {
400 bootmap_start = start;
401 break;
402 }
403 }
404
405 if (bootmap_start == ~0UL) {
406 max_low_pfn >>= 1;
407 goto try_again;
408 }
409
410 /* Allocate the bootmap and mark the whole MM as reserved. */
411 bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
412
413 /* Mark the free regions. */
414 for_each_mem_cluster(memdesc, cluster, i) {
415 if (cluster->usage & 3)
416 continue;
417
418 start = cluster->start_pfn;
419 end = cluster->start_pfn + cluster->numpages;
420 if (start >= max_low_pfn)
421 continue;
422 if (end > max_low_pfn)
423 end = max_low_pfn;
424 if (start < start_kernel_pfn) {
425 if (end > end_kernel_pfn) {
426 free_bootmem(PFN_PHYS(start),
427 (PFN_PHYS(start_kernel_pfn)
428 - PFN_PHYS(start)));
429 printk("freeing pages %ld:%ld\n",
430 start, start_kernel_pfn);
431 start = end_kernel_pfn;
432 } else if (end > start_kernel_pfn)
433 end = start_kernel_pfn;
434 } else if (start < end_kernel_pfn)
435 start = end_kernel_pfn;
436 if (start >= end)
437 continue;
438
439 free_bootmem(PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start));
440 printk("freeing pages %ld:%ld\n", start, end);
441 }
442
443 /* Reserve the bootmap memory. */
444 reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size,
445 BOOTMEM_DEFAULT);
446 printk("reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
447 373
448#ifdef CONFIG_BLK_DEV_INITRD 374#ifdef CONFIG_BLK_DEV_INITRD
449 initrd_start = INITRD_START; 375 initrd_start = INITRD_START;
@@ -459,8 +385,8 @@ setup_memory(void *kernel_end)
459 initrd_end, 385 initrd_end,
460 phys_to_virt(PFN_PHYS(max_low_pfn))); 386 phys_to_virt(PFN_PHYS(max_low_pfn)));
461 } else { 387 } else {
462 reserve_bootmem(virt_to_phys((void *)initrd_start), 388 memblock_reserve(virt_to_phys((void *)initrd_start),
463 INITRD_SIZE, BOOTMEM_DEFAULT); 389 INITRD_SIZE);
464 } 390 }
465 } 391 }
466#endif /* CONFIG_BLK_DEV_INITRD */ 392#endif /* CONFIG_BLK_DEV_INITRD */
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index a9e86475f169..26cd925d19b1 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/memblock.h>
14#include <linux/swap.h> 15#include <linux/swap.h>
15#include <linux/initrd.h> 16#include <linux/initrd.h>
16#include <linux/pfn.h> 17#include <linux/pfn.h>
@@ -59,12 +60,10 @@ setup_memory_node(int nid, void *kernel_end)
59 struct memclust_struct * cluster; 60 struct memclust_struct * cluster;
60 struct memdesc_struct * memdesc; 61 struct memdesc_struct * memdesc;
61 unsigned long start_kernel_pfn, end_kernel_pfn; 62 unsigned long start_kernel_pfn, end_kernel_pfn;
62 unsigned long bootmap_size, bootmap_pages, bootmap_start;
63 unsigned long start, end; 63 unsigned long start, end;
64 unsigned long node_pfn_start, node_pfn_end; 64 unsigned long node_pfn_start, node_pfn_end;
65 unsigned long node_min_pfn, node_max_pfn; 65 unsigned long node_min_pfn, node_max_pfn;
66 int i; 66 int i;
67 unsigned long node_datasz = PFN_UP(sizeof(pg_data_t));
68 int show_init = 0; 67 int show_init = 0;
69 68
70 /* Find the bounds of current node */ 69 /* Find the bounds of current node */
@@ -134,24 +133,14 @@ setup_memory_node(int nid, void *kernel_end)
134 /* Cute trick to make sure our local node data is on local memory */ 133 /* Cute trick to make sure our local node data is on local memory */
135 node_data[nid] = (pg_data_t *)(__va(node_min_pfn << PAGE_SHIFT)); 134 node_data[nid] = (pg_data_t *)(__va(node_min_pfn << PAGE_SHIFT));
136#endif 135#endif
137 /* Quasi-mark the pg_data_t as in-use */
138 node_min_pfn += node_datasz;
139 if (node_min_pfn >= node_max_pfn) {
140 printk(" not enough mem to reserve NODE_DATA");
141 return;
142 }
143 NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
144
145 printk(" Detected node memory: start %8lu, end %8lu\n", 136 printk(" Detected node memory: start %8lu, end %8lu\n",
146 node_min_pfn, node_max_pfn); 137 node_min_pfn, node_max_pfn);
147 138
148 DBGDCONT(" DISCONTIG: node_data[%d] is at 0x%p\n", nid, NODE_DATA(nid)); 139 DBGDCONT(" DISCONTIG: node_data[%d] is at 0x%p\n", nid, NODE_DATA(nid));
149 DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata);
150 140
151 /* Find the bounds of kernel memory. */ 141 /* Find the bounds of kernel memory. */
152 start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS); 142 start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS);
153 end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end)); 143 end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end));
154 bootmap_start = -1;
155 144
156 if (!nid && (node_max_pfn < end_kernel_pfn || node_min_pfn > start_kernel_pfn)) 145 if (!nid && (node_max_pfn < end_kernel_pfn || node_min_pfn > start_kernel_pfn))
157 panic("kernel loaded out of ram"); 146 panic("kernel loaded out of ram");
@@ -161,89 +150,11 @@ setup_memory_node(int nid, void *kernel_end)
161 has much larger alignment than 8Mb, so it's safe. */ 150 has much larger alignment than 8Mb, so it's safe. */
162 node_min_pfn &= ~((1UL << (MAX_ORDER-1))-1); 151 node_min_pfn &= ~((1UL << (MAX_ORDER-1))-1);
163 152
164 /* We need to know how many physically contiguous pages 153 memblock_add(PFN_PHYS(node_min_pfn),
165 we'll need for the bootmap. */ 154 (node_max_pfn - node_min_pfn) << PAGE_SHIFT);
166 bootmap_pages = bootmem_bootmap_pages(node_max_pfn-node_min_pfn);
167
168 /* Now find a good region where to allocate the bootmap. */
169 for_each_mem_cluster(memdesc, cluster, i) {
170 if (cluster->usage & 3)
171 continue;
172
173 start = cluster->start_pfn;
174 end = start + cluster->numpages;
175
176 if (start >= node_max_pfn || end <= node_min_pfn)
177 continue;
178
179 if (end > node_max_pfn)
180 end = node_max_pfn;
181 if (start < node_min_pfn)
182 start = node_min_pfn;
183
184 if (start < start_kernel_pfn) {
185 if (end > end_kernel_pfn
186 && end - end_kernel_pfn >= bootmap_pages) {
187 bootmap_start = end_kernel_pfn;
188 break;
189 } else if (end > start_kernel_pfn)
190 end = start_kernel_pfn;
191 } else if (start < end_kernel_pfn)
192 start = end_kernel_pfn;
193 if (end - start >= bootmap_pages) {
194 bootmap_start = start;
195 break;
196 }
197 }
198
199 if (bootmap_start == -1)
200 panic("couldn't find a contiguous place for the bootmap");
201
202 /* Allocate the bootmap and mark the whole MM as reserved. */
203 bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start,
204 node_min_pfn, node_max_pfn);
205 DBGDCONT(" bootmap_start %lu, bootmap_size %lu, bootmap_pages %lu\n",
206 bootmap_start, bootmap_size, bootmap_pages);
207 155
208 /* Mark the free regions. */ 156 NODE_DATA(nid)->node_start_pfn = node_min_pfn;
209 for_each_mem_cluster(memdesc, cluster, i) { 157 NODE_DATA(nid)->node_present_pages = node_max_pfn - node_min_pfn;
210 if (cluster->usage & 3)
211 continue;
212
213 start = cluster->start_pfn;
214 end = cluster->start_pfn + cluster->numpages;
215
216 if (start >= node_max_pfn || end <= node_min_pfn)
217 continue;
218
219 if (end > node_max_pfn)
220 end = node_max_pfn;
221 if (start < node_min_pfn)
222 start = node_min_pfn;
223
224 if (start < start_kernel_pfn) {
225 if (end > end_kernel_pfn) {
226 free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start),
227 (PFN_PHYS(start_kernel_pfn)
228 - PFN_PHYS(start)));
229 printk(" freeing pages %ld:%ld\n",
230 start, start_kernel_pfn);
231 start = end_kernel_pfn;
232 } else if (end > start_kernel_pfn)
233 end = start_kernel_pfn;
234 } else if (start < end_kernel_pfn)
235 start = end_kernel_pfn;
236 if (start >= end)
237 continue;
238
239 free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start));
240 printk(" freeing pages %ld:%ld\n", start, end);
241 }
242
243 /* Reserve the bootmap memory. */
244 reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start),
245 bootmap_size, BOOTMEM_DEFAULT);
246 printk(" reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
247 158
248 node_set_online(nid); 159 node_set_online(nid);
249} 160}
@@ -251,6 +162,7 @@ setup_memory_node(int nid, void *kernel_end)
251void __init 162void __init
252setup_memory(void *kernel_end) 163setup_memory(void *kernel_end)
253{ 164{
165 unsigned long kernel_size;
254 int nid; 166 int nid;
255 167
256 show_mem_layout(); 168 show_mem_layout();
@@ -262,6 +174,9 @@ setup_memory(void *kernel_end)
262 for (nid = 0; nid < MAX_NUMNODES; nid++) 174 for (nid = 0; nid < MAX_NUMNODES; nid++)
263 setup_memory_node(nid, kernel_end); 175 setup_memory_node(nid, kernel_end);
264 176
177 kernel_size = virt_to_phys(kernel_end) - KERNEL_START_PHYS;
178 memblock_reserve(KERNEL_START_PHYS, kernel_size);
179
265#ifdef CONFIG_BLK_DEV_INITRD 180#ifdef CONFIG_BLK_DEV_INITRD
266 initrd_start = INITRD_START; 181 initrd_start = INITRD_START;
267 if (initrd_start) { 182 if (initrd_start) {
@@ -279,9 +194,8 @@ setup_memory(void *kernel_end)
279 phys_to_virt(PFN_PHYS(max_low_pfn))); 194 phys_to_virt(PFN_PHYS(max_low_pfn)));
280 } else { 195 } else {
281 nid = kvaddr_to_nid(initrd_start); 196 nid = kvaddr_to_nid(initrd_start);
282 reserve_bootmem_node(NODE_DATA(nid), 197 memblock_reserve(virt_to_phys((void *)initrd_start),
283 virt_to_phys((void *)initrd_start), 198 INITRD_SIZE);
284 INITRD_SIZE, BOOTMEM_DEFAULT);
285 } 199 }
286 } 200 }
287#endif /* CONFIG_BLK_DEV_INITRD */ 201#endif /* CONFIG_BLK_DEV_INITRD */
@@ -303,9 +217,8 @@ void __init paging_init(void)
303 dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 217 dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
304 218
305 for_each_online_node(nid) { 219 for_each_online_node(nid) {
306 bootmem_data_t *bdata = &bootmem_node_data[nid]; 220 unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
307 unsigned long start_pfn = bdata->node_min_pfn; 221 unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_present_pages;
308 unsigned long end_pfn = bdata->node_low_pfn;
309 222
310 if (dma_local_pfn >= end_pfn - start_pfn) 223 if (dma_local_pfn >= end_pfn - start_pfn)
311 zones_size[ZONE_DMA] = end_pfn - start_pfn; 224 zones_size[ZONE_DMA] = end_pfn - start_pfn;