diff options
| -rw-r--r-- | arch/powerpc/mm/numa.c | 122 |
1 files changed, 75 insertions, 47 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index eb505ad34a85..a8397bbad3d4 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -865,6 +865,67 @@ static struct notifier_block __cpuinitdata ppc64_numa_nb = { | |||
| 865 | .priority = 1 /* Must run before sched domains notifier. */ | 865 | .priority = 1 /* Must run before sched domains notifier. */ |
| 866 | }; | 866 | }; |
| 867 | 867 | ||
| 868 | static void mark_reserved_regions_for_nid(int nid) | ||
| 869 | { | ||
| 870 | struct pglist_data *node = NODE_DATA(nid); | ||
| 871 | int i; | ||
| 872 | |||
| 873 | for (i = 0; i < lmb.reserved.cnt; i++) { | ||
| 874 | unsigned long physbase = lmb.reserved.region[i].base; | ||
| 875 | unsigned long size = lmb.reserved.region[i].size; | ||
| 876 | unsigned long start_pfn = physbase >> PAGE_SHIFT; | ||
| 877 | unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); | ||
| 878 | struct node_active_region node_ar; | ||
| 879 | unsigned long node_end_pfn = node->node_start_pfn + | ||
| 880 | node->node_spanned_pages; | ||
| 881 | |||
| 882 | /* | ||
| 883 | * Check to make sure that this lmb.reserved area is | ||
| 884 | * within the bounds of the node that we care about. | ||
| 885 | * Checking the nid of the start and end points is not | ||
| 886 | * sufficient because the reserved area could span the | ||
| 887 | * entire node. | ||
| 888 | */ | ||
| 889 | if (end_pfn <= node->node_start_pfn || | ||
| 890 | start_pfn >= node_end_pfn) | ||
| 891 | continue; | ||
| 892 | |||
| 893 | get_node_active_region(start_pfn, &node_ar); | ||
| 894 | while (start_pfn < end_pfn && | ||
| 895 | node_ar.start_pfn < node_ar.end_pfn) { | ||
| 896 | unsigned long reserve_size = size; | ||
| 897 | /* | ||
| 898 | * if reserved region extends past active region | ||
| 899 | * then trim size to active region | ||
| 900 | */ | ||
| 901 | if (end_pfn > node_ar.end_pfn) | ||
| 902 | reserve_size = (node_ar.end_pfn << PAGE_SHIFT) | ||
| 903 | - (start_pfn << PAGE_SHIFT); | ||
| 904 | dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, | ||
| 905 | reserve_size, node_ar.nid); | ||
| 906 | reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, | ||
| 907 | reserve_size, BOOTMEM_DEFAULT); | ||
| 908 | /* | ||
| 909 | * if reserved region is contained in the active region | ||
| 910 | * then done. | ||
| 911 | */ | ||
| 912 | if (end_pfn <= node_ar.end_pfn) | ||
| 913 | break; | ||
| 914 | |||
| 915 | /* | ||
| 916 | * reserved region extends past the active region | ||
| 917 | * get next active region that contains this | ||
| 918 | * reserved region | ||
| 919 | */ | ||
| 920 | start_pfn = node_ar.end_pfn; | ||
| 921 | physbase = start_pfn << PAGE_SHIFT; | ||
| 922 | size = size - reserve_size; | ||
| 923 | get_node_active_region(start_pfn, &node_ar); | ||
| 924 | } | ||
| 925 | } | ||
| 926 | } | ||
| 927 | |||
| 928 | |||
| 868 | void __init do_init_bootmem(void) | 929 | void __init do_init_bootmem(void) |
| 869 | { | 930 | { |
| 870 | int nid; | 931 | int nid; |
| @@ -890,7 +951,13 @@ void __init do_init_bootmem(void) | |||
| 890 | 951 | ||
| 891 | get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); | 952 | get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); |
| 892 | 953 | ||
| 893 | /* Allocate the node structure node local if possible */ | 954 | /* |
| 955 | * Allocate the node structure node local if possible | ||
| 956 | * | ||
| 957 | * Be careful moving this around, as it relies on all | ||
| 958 | * previous nodes' bootmem to be initialized and have | ||
| 959 | * all reserved areas marked. | ||
| 960 | */ | ||
| 894 | NODE_DATA(nid) = careful_allocation(nid, | 961 | NODE_DATA(nid) = careful_allocation(nid, |
| 895 | sizeof(struct pglist_data), | 962 | sizeof(struct pglist_data), |
| 896 | SMP_CACHE_BYTES, end_pfn); | 963 | SMP_CACHE_BYTES, end_pfn); |
| @@ -922,53 +989,14 @@ void __init do_init_bootmem(void) | |||
| 922 | start_pfn, end_pfn); | 989 | start_pfn, end_pfn); |
| 923 | 990 | ||
| 924 | free_bootmem_with_active_regions(nid, end_pfn); | 991 | free_bootmem_with_active_regions(nid, end_pfn); |
| 925 | } | 992 | /* |
| 926 | 993 | * Be very careful about moving this around. Future | |
| 927 | /* Mark reserved regions */ | 994 | * calls to careful_allocation() depend on this getting |
| 928 | for (i = 0; i < lmb.reserved.cnt; i++) { | 995 | * done correctly. |
| 929 | unsigned long physbase = lmb.reserved.region[i].base; | 996 | */ |
| 930 | unsigned long size = lmb.reserved.region[i].size; | 997 | mark_reserved_regions_for_nid(nid); |
| 931 | unsigned long start_pfn = physbase >> PAGE_SHIFT; | ||
| 932 | unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); | ||
| 933 | struct node_active_region node_ar; | ||
| 934 | |||
| 935 | get_node_active_region(start_pfn, &node_ar); | ||
| 936 | while (start_pfn < end_pfn && | ||
| 937 | node_ar.start_pfn < node_ar.end_pfn) { | ||
| 938 | unsigned long reserve_size = size; | ||
| 939 | /* | ||
| 940 | * if reserved region extends past active region | ||
| 941 | * then trim size to active region | ||
| 942 | */ | ||
| 943 | if (end_pfn > node_ar.end_pfn) | ||
| 944 | reserve_size = (node_ar.end_pfn << PAGE_SHIFT) | ||
| 945 | - (start_pfn << PAGE_SHIFT); | ||
| 946 | dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, | ||
| 947 | reserve_size, node_ar.nid); | ||
| 948 | reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, | ||
| 949 | reserve_size, BOOTMEM_DEFAULT); | ||
| 950 | /* | ||
| 951 | * if reserved region is contained in the active region | ||
| 952 | * then done. | ||
| 953 | */ | ||
| 954 | if (end_pfn <= node_ar.end_pfn) | ||
| 955 | break; | ||
| 956 | |||
| 957 | /* | ||
| 958 | * reserved region extends past the active region | ||
| 959 | * get next active region that contains this | ||
| 960 | * reserved region | ||
| 961 | */ | ||
| 962 | start_pfn = node_ar.end_pfn; | ||
| 963 | physbase = start_pfn << PAGE_SHIFT; | ||
| 964 | size = size - reserve_size; | ||
| 965 | get_node_active_region(start_pfn, &node_ar); | ||
| 966 | } | ||
| 967 | |||
| 968 | } | ||
| 969 | |||
| 970 | for_each_online_node(nid) | ||
| 971 | sparse_memory_present_with_active_regions(nid); | 998 | sparse_memory_present_with_active_regions(nid); |
| 999 | } | ||
| 972 | } | 1000 | } |
| 973 | 1001 | ||
| 974 | void __init paging_init(void) | 1002 | void __init paging_init(void) |
