aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/mm/numa.c36
-rw-r--r--include/asm-x86_64/mmzone.h16
2 files changed, 39 insertions, 13 deletions
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 994dbaeb33f0..6ef9f9a76235 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -360,3 +360,39 @@ EXPORT_SYMBOL(node_to_cpumask);
360EXPORT_SYMBOL(memnode_shift); 360EXPORT_SYMBOL(memnode_shift);
361EXPORT_SYMBOL(memnodemap); 361EXPORT_SYMBOL(memnodemap);
362EXPORT_SYMBOL(node_data); 362EXPORT_SYMBOL(node_data);
363
364#ifdef CONFIG_DISCONTIGMEM
365/*
366 * Functions to convert PFNs from/to per node page addresses.
367 * These are out of line because they are quite big.
368 * They could be all tuned by pre caching more state.
369 * Should do that.
370 */
371
372/* Requires pfn_valid(pfn) to be true */
373struct page *pfn_to_page(unsigned long pfn)
374{
375 int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT);
376 return (pfn - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;
377}
378EXPORT_SYMBOL(pfn_to_page);
379
380unsigned long page_to_pfn(struct page *page)
381{
382 return (long)(((page) - page_zone(page)->zone_mem_map) +
383 page_zone(page)->zone_start_pfn);
384}
385EXPORT_SYMBOL(page_to_pfn);
386
387int pfn_valid(unsigned long pfn)
388{
389 unsigned nid;
390 if (pfn >= num_physpages)
391 return 0;
392 nid = pfn_to_nid(pfn);
393 if (nid == 0xff)
394 return 0;
395 return pfn >= node_start_pfn(nid) && (pfn) < node_end_pfn(nid);
396}
397EXPORT_SYMBOL(pfn_valid);
398#endif
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 69baaa8a3ce0..972c9359f7d7 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -36,22 +36,12 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
36 NODE_DATA(nid)->node_spanned_pages) 36 NODE_DATA(nid)->node_spanned_pages)
37 37
38#ifdef CONFIG_DISCONTIGMEM 38#ifdef CONFIG_DISCONTIGMEM
39
40#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT) 39#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
41#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr)) 40#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr))
42 41
43/* Requires pfn_valid(pfn) to be true */ 42extern struct page *pfn_to_page(unsigned long pfn);
44#define pfn_to_page(pfn) ({ \ 43extern unsigned long page_to_pfn(struct page *page);
45 int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); \ 44extern int pfn_valid(unsigned long pfn);
46 ((pfn) - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map; \
47})
48
49#define page_to_pfn(page) \
50 (long)(((page) - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
51
52#define pfn_valid(pfn) ((pfn) >= num_physpages ? 0 : \
53 ({ u8 nid__ = pfn_to_nid(pfn); \
54 nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) < node_end_pfn(nid__); }))
55#endif 45#endif
56 46
57#define local_mapnr(kvaddr) \ 47#define local_mapnr(kvaddr) \