summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memblock.h2
-rw-r--r--mm/memblock.c18
-rw-r--r--mm/page_alloc.c19
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);
60void memblock_trim_memory(phys_addr_t align); 60void memblock_trim_memory(phys_addr_t align);
61 61
62#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP 62#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
63int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
64 unsigned long *end_pfn);
63void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, 65void __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
918int __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,
4306int __meminit __early_pfn_to_nid(unsigned long pfn) 4306int __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