[PATCH] x86_64: Move NUMA page_to_pfn/pfn_to_page functions out of line

Saves about ~18K .text in defconfig

There would be more optimization potential, but that's for later.

Suggestion originally from Bill Irwin.
Fix from Andy Whitcroft.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 994dbaeb..6ef9f9a 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -360,3 +360,39 @@
 EXPORT_SYMBOL(memnode_shift);
 EXPORT_SYMBOL(memnodemap);
 EXPORT_SYMBOL(node_data);
+
+#ifdef CONFIG_DISCONTIGMEM
+/*
+ * Functions to convert PFNs from/to per node page addresses.
+ * These are out of line because they are quite big.
+ * They could be all tuned by pre caching more state.
+ * Should do that.
+ */
+
+/* Requires pfn_valid(pfn) to be true */
+struct page *pfn_to_page(unsigned long pfn)
+{
+	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT);
+	return (pfn - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;
+}
+EXPORT_SYMBOL(pfn_to_page);
+
+unsigned long page_to_pfn(struct page *page)
+{
+	return (long)(((page) - page_zone(page)->zone_mem_map) +
+		      page_zone(page)->zone_start_pfn);
+}
+EXPORT_SYMBOL(page_to_pfn);
+
+int pfn_valid(unsigned long pfn)
+{
+	unsigned nid;
+	if (pfn >= num_physpages)
+		return 0;
+	nid = pfn_to_nid(pfn);
+	if (nid == 0xff)
+		return 0;
+	return pfn >= node_start_pfn(nid) && (pfn) < node_end_pfn(nid);
+}
+EXPORT_SYMBOL(pfn_valid);
+#endif
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 69baaa8..972c935 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -36,22 +36,12 @@
 				 NODE_DATA(nid)->node_spanned_pages)
 
 #ifdef CONFIG_DISCONTIGMEM
-
 #define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
 #define kvaddr_to_nid(kaddr)	phys_to_nid(__pa(kaddr))
 
-/* Requires pfn_valid(pfn) to be true */
-#define pfn_to_page(pfn) ({ \
-	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); 	\
-	((pfn) - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;	\
-})
-
-#define page_to_pfn(page) \
-	(long)(((page) - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
-
-#define pfn_valid(pfn) ((pfn) >= num_physpages ? 0 : \
-			({ u8 nid__ = pfn_to_nid(pfn); \
-			   nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) < node_end_pfn(nid__); }))
+extern struct page *pfn_to_page(unsigned long pfn);
+extern unsigned long page_to_pfn(struct page *page);
+extern int pfn_valid(unsigned long pfn);
 #endif
 
 #define local_mapnr(kvaddr) \