aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/setup.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-25 18:59:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-25 18:59:38 -0400
commitfa2af6e4fe0c4d2f8875d42625b25675e8584010 (patch)
treeef9a92949858ab763aa1bfda7cb11a5f7b84d123 /arch/tile/kernel/setup.c
parent109b9b0408e5f1dd327a44f446841a9fbe0bcd83 (diff)
parent1fcb78e9da714d96f65edd37b29dae3b1f7df508 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
Pull tile updates from Chris Metcalf: "These changes cover a range of new arch/tile features and optimizations. They've been through LKML review and on linux-next for a month or so. There's also one bug-fix that just missed 3.4, which I've marked for stable." Fixed up trivial conflict in arch/tile/Kconfig (new added tile Kconfig entries clashing with the generic timer/clockevents changes). * git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: tile: default to tilegx_defconfig for ARCH=tile tile: fix bug where fls(0) was not returning 0 arch/tile: mark TILEGX as not EXPERIMENTAL tile/mm/fault.c: Port OOM changes to handle_page_fault arch/tile: add descriptive text if the kernel reports a bad trap arch/tile: allow querying cpu module information from the hypervisor arch/tile: fix hardwall for tilegx and generalize for idn and ipi arch/tile: support multiple huge page sizes dynamically mm: add new arch_make_huge_pte() method for tile support arch/tile: support kexec() for tilegx arch/tile: support <asm/cachectl.h> header for cacheflush() syscall arch/tile: Allow tilegx to build with either 16K or 64K page size arch/tile: optimize get_user/put_user and friends arch/tile: support building big-endian kernel arch/tile: allow building Linux with transparent huge pages enabled arch/tile: use interrupt critical sections less
Diffstat (limited to 'arch/tile/kernel/setup.c')
-rw-r--r--arch/tile/kernel/setup.c169
1 files changed, 115 insertions, 54 deletions
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index 98d80eb49ddb..6098ccc59be2 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -28,6 +28,7 @@
28#include <linux/highmem.h> 28#include <linux/highmem.h>
29#include <linux/smp.h> 29#include <linux/smp.h>
30#include <linux/timex.h> 30#include <linux/timex.h>
31#include <linux/hugetlb.h>
31#include <asm/setup.h> 32#include <asm/setup.h>
32#include <asm/sections.h> 33#include <asm/sections.h>
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
@@ -49,9 +50,6 @@ char chip_model[64] __write_once;
49struct pglist_data node_data[MAX_NUMNODES] __read_mostly; 50struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
50EXPORT_SYMBOL(node_data); 51EXPORT_SYMBOL(node_data);
51 52
52/* We only create bootmem data on node 0. */
53static bootmem_data_t __initdata node0_bdata;
54
55/* Information on the NUMA nodes that we compute early */ 53/* Information on the NUMA nodes that we compute early */
56unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES]; 54unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
57unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES]; 55unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
@@ -534,37 +532,96 @@ static void __init setup_memory(void)
534#endif 532#endif
535} 533}
536 534
537static void __init setup_bootmem_allocator(void) 535/*
536 * On 32-bit machines, we only put bootmem on the low controller,
537 * since PAs > 4GB can't be used in bootmem. In principle one could
538 * imagine, e.g., multiple 1 GB controllers all of which could support
539 * bootmem, but in practice using controllers this small isn't a
540 * particularly interesting scenario, so we just keep it simple and
541 * use only the first controller for bootmem on 32-bit machines.
542 */
543static inline int node_has_bootmem(int nid)
538{ 544{
539 unsigned long bootmap_size, first_alloc_pfn, last_alloc_pfn; 545#ifdef CONFIG_64BIT
546 return 1;
547#else
548 return nid == 0;
549#endif
550}
540 551
541 /* Provide a node 0 bdata. */ 552static inline unsigned long alloc_bootmem_pfn(int nid,
542 NODE_DATA(0)->bdata = &node0_bdata; 553 unsigned long size,
554 unsigned long goal)
555{
556 void *kva = __alloc_bootmem_node(NODE_DATA(nid), size,
557 PAGE_SIZE, goal);
558 unsigned long pfn = kaddr_to_pfn(kva);
559 BUG_ON(goal && PFN_PHYS(pfn) != goal);
560 return pfn;
561}
543 562
544#ifdef CONFIG_PCI 563static void __init setup_bootmem_allocator_node(int i)
545 /* Don't let boot memory alias the PCI region. */ 564{
546 last_alloc_pfn = min(max_low_pfn, pci_reserve_start_pfn); 565 unsigned long start, end, mapsize, mapstart;
566
567 if (node_has_bootmem(i)) {
568 NODE_DATA(i)->bdata = &bootmem_node_data[i];
569 } else {
570 /* Share controller zero's bdata for now. */
571 NODE_DATA(i)->bdata = &bootmem_node_data[0];
572 return;
573 }
574
575 /* Skip up to after the bss in node 0. */
576 start = (i == 0) ? min_low_pfn : node_start_pfn[i];
577
578 /* Only lowmem, if we're a HIGHMEM build. */
579#ifdef CONFIG_HIGHMEM
580 end = node_lowmem_end_pfn[i];
547#else 581#else
548 last_alloc_pfn = max_low_pfn; 582 end = node_end_pfn[i];
549#endif 583#endif
550 584
551 /* 585 /* No memory here. */
552 * Initialize the boot-time allocator (with low memory only): 586 if (end == start)
553 * The first argument says where to put the bitmap, and the 587 return;
554 * second says where the end of allocatable memory is. 588
555 */ 589 /* Figure out where the bootmem bitmap is located. */
556 bootmap_size = init_bootmem(min_low_pfn, last_alloc_pfn); 590 mapsize = bootmem_bootmap_pages(end - start);
591 if (i == 0) {
592 /* Use some space right before the heap on node 0. */
593 mapstart = start;
594 start += mapsize;
595 } else {
596 /* Allocate bitmap on node 0 to avoid page table issues. */
597 mapstart = alloc_bootmem_pfn(0, PFN_PHYS(mapsize), 0);
598 }
557 599
600 /* Initialize a node. */
601 init_bootmem_node(NODE_DATA(i), mapstart, start, end);
602
603 /* Free all the space back into the allocator. */
604 free_bootmem(PFN_PHYS(start), PFN_PHYS(end - start));
605
606#if defined(CONFIG_PCI)
558 /* 607 /*
559 * Let the bootmem allocator use all the space we've given it 608 * Throw away any memory aliased by the PCI region. FIXME: this
560 * except for its own bitmap. 609 * is a temporary hack to work around bug 10502, and needs to be
610 * fixed properly.
561 */ 611 */
562 first_alloc_pfn = min_low_pfn + PFN_UP(bootmap_size); 612 if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start)
563 if (first_alloc_pfn >= last_alloc_pfn) 613 reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn),
564 early_panic("Not enough memory on controller 0 for bootmem\n"); 614 PFN_PHYS(pci_reserve_end_pfn -
615 pci_reserve_start_pfn),
616 BOOTMEM_EXCLUSIVE);
617#endif
618}
565 619
566 free_bootmem(PFN_PHYS(first_alloc_pfn), 620static void __init setup_bootmem_allocator(void)
567 PFN_PHYS(last_alloc_pfn - first_alloc_pfn)); 621{
622 int i;
623 for (i = 0; i < MAX_NUMNODES; ++i)
624 setup_bootmem_allocator_node(i);
568 625
569#ifdef CONFIG_KEXEC 626#ifdef CONFIG_KEXEC
570 if (crashk_res.start != crashk_res.end) 627 if (crashk_res.start != crashk_res.end)
@@ -595,14 +652,6 @@ static int __init percpu_size(void)
595 return size; 652 return size;
596} 653}
597 654
598static inline unsigned long alloc_bootmem_pfn(int size, unsigned long goal)
599{
600 void *kva = __alloc_bootmem(size, PAGE_SIZE, goal);
601 unsigned long pfn = kaddr_to_pfn(kva);
602 BUG_ON(goal && PFN_PHYS(pfn) != goal);
603 return pfn;
604}
605
606static void __init zone_sizes_init(void) 655static void __init zone_sizes_init(void)
607{ 656{
608 unsigned long zones_size[MAX_NR_ZONES] = { 0 }; 657 unsigned long zones_size[MAX_NR_ZONES] = { 0 };
@@ -640,21 +689,22 @@ static void __init zone_sizes_init(void)
640 * though, there'll be no lowmem, so we just alloc_bootmem 689 * though, there'll be no lowmem, so we just alloc_bootmem
641 * the memmap. There will be no percpu memory either. 690 * the memmap. There will be no percpu memory either.
642 */ 691 */
643 if (__pfn_to_highbits(start) == 0) { 692 if (i != 0 && cpu_isset(i, isolnodes)) {
644 /* In low PAs, allocate via bootmem. */ 693 node_memmap_pfn[i] =
694 alloc_bootmem_pfn(0, memmap_size, 0);
695 BUG_ON(node_percpu[i] != 0);
696 } else if (node_has_bootmem(start)) {
645 unsigned long goal = 0; 697 unsigned long goal = 0;
646 node_memmap_pfn[i] = 698 node_memmap_pfn[i] =
647 alloc_bootmem_pfn(memmap_size, goal); 699 alloc_bootmem_pfn(i, memmap_size, 0);
648 if (kdata_huge) 700 if (kdata_huge)
649 goal = PFN_PHYS(lowmem_end) - node_percpu[i]; 701 goal = PFN_PHYS(lowmem_end) - node_percpu[i];
650 if (node_percpu[i]) 702 if (node_percpu[i])
651 node_percpu_pfn[i] = 703 node_percpu_pfn[i] =
652 alloc_bootmem_pfn(node_percpu[i], goal); 704 alloc_bootmem_pfn(i, node_percpu[i],
653 } else if (cpu_isset(i, isolnodes)) { 705 goal);
654 node_memmap_pfn[i] = alloc_bootmem_pfn(memmap_size, 0);
655 BUG_ON(node_percpu[i] != 0);
656 } else { 706 } else {
657 /* In high PAs, just reserve some pages. */ 707 /* In non-bootmem zones, just reserve some pages. */
658 node_memmap_pfn[i] = node_free_pfn[i]; 708 node_memmap_pfn[i] = node_free_pfn[i];
659 node_free_pfn[i] += PFN_UP(memmap_size); 709 node_free_pfn[i] += PFN_UP(memmap_size);
660 if (!kdata_huge) { 710 if (!kdata_huge) {
@@ -678,16 +728,9 @@ static void __init zone_sizes_init(void)
678 zones_size[ZONE_NORMAL] = end - start; 728 zones_size[ZONE_NORMAL] = end - start;
679#endif 729#endif
680 730
681 /* 731 /* Take zone metadata from controller 0 if we're isolnode. */
682 * Everyone shares node 0's bootmem allocator, but 732 if (node_isset(i, isolnodes))
683 * we use alloc_remap(), above, to put the actual 733 NODE_DATA(i)->bdata = &bootmem_node_data[0];
684 * struct page array on the individual controllers,
685 * which is most of the data that we actually care about.
686 * We can't place bootmem allocators on the other
687 * controllers since the bootmem allocator can only
688 * operate on 32-bit physical addresses.
689 */
690 NODE_DATA(i)->bdata = NODE_DATA(0)->bdata;
691 734
692 free_area_init_node(i, zones_size, start, NULL); 735 free_area_init_node(i, zones_size, start, NULL);
693 printk(KERN_DEBUG " Normal zone: %ld per-cpu pages\n", 736 printk(KERN_DEBUG " Normal zone: %ld per-cpu pages\n",
@@ -870,6 +913,22 @@ subsys_initcall(topology_init);
870 913
871#endif /* CONFIG_NUMA */ 914#endif /* CONFIG_NUMA */
872 915
916/*
917 * Initialize hugepage support on this cpu. We do this on all cores
918 * early in boot: before argument parsing for the boot cpu, and after
919 * argument parsing but before the init functions run on the secondaries.
920 * So the values we set up here in the hypervisor may be overridden on
921 * the boot cpu as arguments are parsed.
922 */
923static __cpuinit void init_super_pages(void)
924{
925#ifdef CONFIG_HUGETLB_SUPER_PAGES
926 int i;
927 for (i = 0; i < HUGE_SHIFT_ENTRIES; ++i)
928 hv_set_pte_super_shift(i, huge_shift[i]);
929#endif
930}
931
873/** 932/**
874 * setup_cpu() - Do all necessary per-cpu, tile-specific initialization. 933 * setup_cpu() - Do all necessary per-cpu, tile-specific initialization.
875 * @boot: Is this the boot cpu? 934 * @boot: Is this the boot cpu?
@@ -924,6 +983,8 @@ void __cpuinit setup_cpu(int boot)
924 /* Reset the network state on this cpu. */ 983 /* Reset the network state on this cpu. */
925 reset_network_state(); 984 reset_network_state();
926#endif 985#endif
986
987 init_super_pages();
927} 988}
928 989
929#ifdef CONFIG_BLK_DEV_INITRD 990#ifdef CONFIG_BLK_DEV_INITRD
@@ -1412,13 +1473,13 @@ void __init setup_per_cpu_areas(void)
1412 for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) { 1473 for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
1413 1474
1414 /* Update the vmalloc mapping and page home. */ 1475 /* Update the vmalloc mapping and page home. */
1415 pte_t *ptep = 1476 unsigned long addr = (unsigned long)ptr + i;
1416 virt_to_pte(NULL, (unsigned long)ptr + i); 1477 pte_t *ptep = virt_to_pte(NULL, addr);
1417 pte_t pte = *ptep; 1478 pte_t pte = *ptep;
1418 BUG_ON(pfn != pte_pfn(pte)); 1479 BUG_ON(pfn != pte_pfn(pte));
1419 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3); 1480 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
1420 pte = set_remote_cache_cpu(pte, cpu); 1481 pte = set_remote_cache_cpu(pte, cpu);
1421 set_pte(ptep, pte); 1482 set_pte_at(&init_mm, addr, ptep, pte);
1422 1483
1423 /* Update the lowmem mapping for consistency. */ 1484 /* Update the lowmem mapping for consistency. */
1424 lowmem_va = (unsigned long)pfn_to_kaddr(pfn); 1485 lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
@@ -1431,7 +1492,7 @@ void __init setup_per_cpu_areas(void)
1431 BUG_ON(pte_huge(*ptep)); 1492 BUG_ON(pte_huge(*ptep));
1432 } 1493 }
1433 BUG_ON(pfn != pte_pfn(*ptep)); 1494 BUG_ON(pfn != pte_pfn(*ptep));
1434 set_pte(ptep, pte); 1495 set_pte_at(&init_mm, lowmem_va, ptep, pte);
1435 } 1496 }
1436 } 1497 }
1437 1498