diff options
-rw-r--r-- | include/linux/memblock.h | 2 | ||||
-rw-r--r-- | mm/memblock.c | 18 | ||||
-rw-r--r-- | mm/page_alloc.c | 19 |
3 files changed, 29 insertions, 10 deletions
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index f388203db7e8..31e95acddb4d 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
@@ -60,6 +60,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size); | |||
60 | void memblock_trim_memory(phys_addr_t align); | 60 | void memblock_trim_memory(phys_addr_t align); |
61 | 61 | ||
62 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | 62 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP |
63 | int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, | ||
64 | unsigned long *end_pfn); | ||
63 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, | 65 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, |
64 | unsigned long *out_end_pfn, int *out_nid); | 66 | unsigned long *out_end_pfn, int *out_nid); |
65 | 67 | ||
diff --git a/mm/memblock.c b/mm/memblock.c index a847bfe6f3ba..0ac412a0a7ee 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -914,6 +914,24 @@ int __init_memblock memblock_is_memory(phys_addr_t addr) | |||
914 | return memblock_search(&memblock.memory, addr) != -1; | 914 | return memblock_search(&memblock.memory, addr) != -1; |
915 | } | 915 | } |
916 | 916 | ||
917 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | ||
918 | int __init_memblock memblock_search_pfn_nid(unsigned long pfn, | ||
919 | unsigned long *start_pfn, unsigned long *end_pfn) | ||
920 | { | ||
921 | struct memblock_type *type = &memblock.memory; | ||
922 | int mid = memblock_search(type, (phys_addr_t)pfn << PAGE_SHIFT); | ||
923 | |||
924 | if (mid == -1) | ||
925 | return -1; | ||
926 | |||
927 | *start_pfn = type->regions[mid].base >> PAGE_SHIFT; | ||
928 | *end_pfn = (type->regions[mid].base + type->regions[mid].size) | ||
929 | >> PAGE_SHIFT; | ||
930 | |||
931 | return type->regions[mid].nid; | ||
932 | } | ||
933 | #endif | ||
934 | |||
917 | /** | 935 | /** |
918 | * memblock_is_region_memory - check if a region is a subset of memory | 936 | * memblock_is_region_memory - check if a region is a subset of memory |
919 | * @base: base of region to check | 937 | * @base: base of region to check |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f7cc08dad26a..22653e34a047 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -4306,7 +4306,7 @@ int __meminit init_currently_empty_zone(struct zone *zone, | |||
4306 | int __meminit __early_pfn_to_nid(unsigned long pfn) | 4306 | int __meminit __early_pfn_to_nid(unsigned long pfn) |
4307 | { | 4307 | { |
4308 | unsigned long start_pfn, end_pfn; | 4308 | unsigned long start_pfn, end_pfn; |
4309 | int i, nid; | 4309 | int nid; |
4310 | /* | 4310 | /* |
4311 | * NOTE: The following SMP-unsafe globals are only used early in boot | 4311 | * NOTE: The following SMP-unsafe globals are only used early in boot |
4312 | * when the kernel is running single-threaded. | 4312 | * when the kernel is running single-threaded. |
@@ -4317,15 +4317,14 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) | |||
4317 | if (last_start_pfn <= pfn && pfn < last_end_pfn) | 4317 | if (last_start_pfn <= pfn && pfn < last_end_pfn) |
4318 | return last_nid; | 4318 | return last_nid; |
4319 | 4319 | ||
4320 | for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) | 4320 | nid = memblock_search_pfn_nid(pfn, &start_pfn, &end_pfn); |
4321 | if (start_pfn <= pfn && pfn < end_pfn) { | 4321 | if (nid != -1) { |
4322 | last_start_pfn = start_pfn; | 4322 | last_start_pfn = start_pfn; |
4323 | last_end_pfn = end_pfn; | 4323 | last_end_pfn = end_pfn; |
4324 | last_nid = nid; | 4324 | last_nid = nid; |
4325 | return nid; | 4325 | } |
4326 | } | 4326 | |
4327 | /* This is a memory hole */ | 4327 | return nid; |
4328 | return -1; | ||
4329 | } | 4328 | } |
4330 | #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ | 4329 | #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ |
4331 | 4330 | ||