aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-generic/memory_model.h27
-rw-r--r--mm/page_alloc.c32
2 files changed, 17 insertions, 42 deletions
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index 0cfb086dd373..8078cbd2c016 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -23,29 +23,23 @@
23 23
24#endif /* CONFIG_DISCONTIGMEM */ 24#endif /* CONFIG_DISCONTIGMEM */
25 25
26#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE
27struct page;
28/* this is useful when inlined pfn_to_page is too big */
29extern struct page *pfn_to_page(unsigned long pfn);
30extern unsigned long page_to_pfn(struct page *page);
31#else
32/* 26/*
33 * supports 3 memory models. 27 * supports 3 memory models.
34 */ 28 */
35#if defined(CONFIG_FLATMEM) 29#if defined(CONFIG_FLATMEM)
36 30
37#define pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET)) 31#define __pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET))
38#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + \ 32#define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + \
39 ARCH_PFN_OFFSET) 33 ARCH_PFN_OFFSET)
40#elif defined(CONFIG_DISCONTIGMEM) 34#elif defined(CONFIG_DISCONTIGMEM)
41 35
42#define pfn_to_page(pfn) \ 36#define __pfn_to_page(pfn) \
43({ unsigned long __pfn = (pfn); \ 37({ unsigned long __pfn = (pfn); \
44 unsigned long __nid = arch_pfn_to_nid(pfn); \ 38 unsigned long __nid = arch_pfn_to_nid(pfn); \
45 NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\ 39 NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
46}) 40})
47 41
48#define page_to_pfn(pg) \ 42#define __page_to_pfn(pg) \
49({ struct page *__pg = (pg); \ 43({ struct page *__pg = (pg); \
50 struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg)); \ 44 struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg)); \
51 (unsigned long)(__pg - __pgdat->node_mem_map) + \ 45 (unsigned long)(__pg - __pgdat->node_mem_map) + \
@@ -57,18 +51,27 @@ extern unsigned long page_to_pfn(struct page *page);
57 * Note: section's mem_map is encorded to reflect its start_pfn. 51 * Note: section's mem_map is encorded to reflect its start_pfn.
58 * section[i].section_mem_map == mem_map's address - start_pfn; 52 * section[i].section_mem_map == mem_map's address - start_pfn;
59 */ 53 */
60#define page_to_pfn(pg) \ 54#define __page_to_pfn(pg) \
61({ struct page *__pg = (pg); \ 55({ struct page *__pg = (pg); \
62 int __sec = page_to_section(__pg); \ 56 int __sec = page_to_section(__pg); \
63 __pg - __section_mem_map_addr(__nr_to_section(__sec)); \ 57 __pg - __section_mem_map_addr(__nr_to_section(__sec)); \
64}) 58})
65 59
66#define pfn_to_page(pfn) \ 60#define __pfn_to_page(pfn) \
67({ unsigned long __pfn = (pfn); \ 61({ unsigned long __pfn = (pfn); \
68 struct mem_section *__sec = __pfn_to_section(__pfn); \ 62 struct mem_section *__sec = __pfn_to_section(__pfn); \
69 __section_mem_map_addr(__sec) + __pfn; \ 63 __section_mem_map_addr(__sec) + __pfn; \
70}) 64})
71#endif /* CONFIG_FLATMEM/DISCONTIGMEM/SPARSEMEM */ 65#endif /* CONFIG_FLATMEM/DISCONTIGMEM/SPARSEMEM */
66
67#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE
68struct page;
69/* this is useful when inlined pfn_to_page is too big */
70extern struct page *pfn_to_page(unsigned long pfn);
71extern unsigned long page_to_pfn(struct page *page);
72#else
73#define page_to_pfn __page_to_pfn
74#define pfn_to_page __pfn_to_page
72#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ 75#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
73 76
74#endif /* __ASSEMBLY__ */ 77#endif /* __ASSEMBLY__ */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 9dfbe6b7d1c8..5af33186a25f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2879,42 +2879,14 @@ void *__init alloc_large_system_hash(const char *tablename,
2879} 2879}
2880 2880
2881#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE 2881#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE
2882/*
2883 * pfn <-> page translation. out-of-line version.
2884 * (see asm-generic/memory_model.h)
2885 */
2886#if defined(CONFIG_FLATMEM)
2887struct page *pfn_to_page(unsigned long pfn)
2888{
2889 return mem_map + (pfn - ARCH_PFN_OFFSET);
2890}
2891unsigned long page_to_pfn(struct page *page)
2892{
2893 return (page - mem_map) + ARCH_PFN_OFFSET;
2894}
2895#elif defined(CONFIG_DISCONTIGMEM)
2896struct page *pfn_to_page(unsigned long pfn) 2882struct page *pfn_to_page(unsigned long pfn)
2897{ 2883{
2898 int nid = arch_pfn_to_nid(pfn); 2884 return __pfn_to_page(pfn);
2899 return NODE_DATA(nid)->node_mem_map + arch_local_page_offset(pfn,nid);
2900} 2885}
2901unsigned long page_to_pfn(struct page *page) 2886unsigned long page_to_pfn(struct page *page)
2902{ 2887{
2903 struct pglist_data *pgdat = NODE_DATA(page_to_nid(page)); 2888 return __page_to_pfn(page);
2904 return (page - pgdat->node_mem_map) + pgdat->node_start_pfn;
2905}
2906#elif defined(CONFIG_SPARSEMEM)
2907struct page *pfn_to_page(unsigned long pfn)
2908{
2909 return __section_mem_map_addr(__pfn_to_section(pfn)) + pfn;
2910}
2911
2912unsigned long page_to_pfn(struct page *page)
2913{
2914 long section_id = page_to_section(page);
2915 return page - __section_mem_map_addr(__nr_to_section(section_id));
2916} 2889}
2917#endif /* CONFIG_FLATMEM/DISCONTIGMME/SPARSEMEM */
2918EXPORT_SYMBOL(pfn_to_page); 2890EXPORT_SYMBOL(pfn_to_page);
2919EXPORT_SYMBOL(page_to_pfn); 2891EXPORT_SYMBOL(page_to_pfn);
2920#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ 2892#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */