3 memory models are now available, memmaps of 3 models are defined as
FLATMEM --- pfn = (page - mem_map) + offset
DISCONTIGMEM --- pfn = (page - page_node(page)->node_mem_map) +
(page_node(page)->node_start_pfn)
SPARSEMEM --- see linux/mmzone.h , generic ones are defined.
Now, each arch has its own page_to_pfn()/pfn_to_page() on FLATMEM/DISCONTIGIMEM.
But most of them keeps above assumptions and looks same to i386's ones.
This patch unifies each arch's page_to_pfn/pfn_to_page to generic ones.
This patch is against 2.6.16-rc2.
comments ?
-- Kame
This patch defines generic page_to_pfn()/pfn_to_page().
For DISCONTIGMEM, page_to_pfn/pfn_to_page are not inlined.
(x86_64 already has not-inlined version and it reduces text size.)
If FLATMEM and memmap <-> pfn translation needs offset,
ARCH_PFN_OFFSET is defined by each archs.
If DISCONTIGMEM , each arch defines arch_pfn_to_nid().
If necessary, arch_local_map_nr(pfn, nid) is also defined.
arch_local_map_nr() calculates page offset in a node.
Signed-Off-By: KAMEZAWA Hiruyoki <[email protected]>
Index: cleanup_pfn_page/include/linux/mm.h
===================================================================
--- cleanup_pfn_page.orig/include/linux/mm.h
+++ cleanup_pfn_page/include/linux/mm.h
@@ -512,6 +512,32 @@ static inline void set_page_links(struct
extern struct page *mem_map;
#endif
+#if !defined(ARCH_HAS_PFN_PAGE) && !defined(CONFIG_SPARSEMEM)
+#if CONFIG_FLATMEM
+
+#ifndef ARCH_PFN_OFFSET
+#define ARCH_PFN_OFFSET 0
+#endif
+static inline unsigned long page_to_pfn(struct page *page)
+{
+ return (unsigned long)(page - mem_map) + ARCH_PFN_OFFSET;
+}
+static inline struct page *pfn_to_page(unsigned long pfn)
+{
+ return mem_map + (pfn - ARCH_PFN_OFFSET);
+}
+#endif /* CONFIG_FLATMEM */
+#ifdef CONFIG_DISCONTIGMEM
+/* arch_pfn_to_nid/arch_local_map_nr is defined if necesary */
+#ifndef arch_local_map_nr
+#define arch_local_map_nr(pfn ,nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
+#endif
+extern unsigned long page_to_pfn(struct page *page);
+extern struct page* pfn_to_page(unsigned long pfn);
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif
+
static __always_inline void *lowmem_page_address(struct page *page)
{
return __va(page_to_pfn(page) << PAGE_SHIFT);
Index: cleanup_pfn_page/mm/page_alloc.c
===================================================================
--- cleanup_pfn_page.orig/mm/page_alloc.c
+++ cleanup_pfn_page/mm/page_alloc.c
@@ -85,6 +85,25 @@ int min_free_kbytes = 1024;
unsigned long __initdata nr_kernel_pages;
unsigned long __initdata nr_all_pages;
+#if defined(CONFIG_DISCONTIGMEM) && !defined(CONFIG_VIRTUAL_MEM_MAP)
+
+struct page *pfn_to_page(unsigned long pfn)
+{
+ struct pglist_data *pgdat;
+ int nid = arch_pfn_to_nid(pfn);
+ pgdat = NODE_DATA(nid);
+ return pgdat->node_mem_map + arch_local_map_nr(pfn, nid);
+}
+EXPORT_SYMBOL(pfn_to_page);
+
+unsigned long page_to_pfn(struct page *page)
+{
+ struct zone *z = page_zone(page);
+ return z->zone_start_pfn + (unsigned long)(page - z->zone_mem_map);
+}
+EXPORT_SYMBOL(page_to_pfn);
+#endif
+
#ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]