Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/numa: Make memory reserve code more robust

Adjust amount to reserve based on previous nodes for reserves spanning
multiple nodes. Check if the node active range is empty before attempting
to pass the reserve to bootmem. In practice the range shouldn't be empty,
but to be sure we check.

Signed-off-by: Jon Tollefson <kniht@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Jon Tollefson and committed by
Benjamin Herrenschmidt
e8170372 a5598ca0

+10 -5
+10 -5
arch/powerpc/mm/numa.c
··· 116 116 117 117 /* 118 118 * get_node_active_region - Return active region containing start_pfn 119 + * Active range returned is empty if none found. 119 120 * @start_pfn: The page to return the region for. 120 121 * @node_ar: Returned set to the active region containing start_pfn 121 122 */ ··· 127 126 128 127 node_ar->nid = nid; 129 128 node_ar->start_pfn = start_pfn; 129 + node_ar->end_pfn = start_pfn; 130 130 work_with_active_regions(nid, get_active_region_work_fn, node_ar); 131 131 } 132 132 ··· 935 933 struct node_active_region node_ar; 936 934 937 935 get_node_active_region(start_pfn, &node_ar); 938 - while (start_pfn < end_pfn) { 936 + while (start_pfn < end_pfn && 937 + node_ar.start_pfn < node_ar.end_pfn) { 938 + unsigned long reserve_size = size; 939 939 /* 940 940 * if reserved region extends past active region 941 941 * then trim size to active region 942 942 */ 943 943 if (end_pfn > node_ar.end_pfn) 944 - size = (node_ar.end_pfn << PAGE_SHIFT) 944 + reserve_size = (node_ar.end_pfn << PAGE_SHIFT) 945 945 - (start_pfn << PAGE_SHIFT); 946 - dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size, 947 - node_ar.nid); 946 + dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, 947 + reserve_size, node_ar.nid); 948 948 reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, 949 - size, BOOTMEM_DEFAULT); 949 + reserve_size, BOOTMEM_DEFAULT); 950 950 /* 951 951 * if reserved region is contained in the active region 952 952 * then done. ··· 963 959 */ 964 960 start_pfn = node_ar.end_pfn; 965 961 physbase = start_pfn << PAGE_SHIFT; 962 + size = size - reserve_size; 966 963 get_node_active_region(start_pfn, &node_ar); 967 964 } 968 965