public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH] unify pfn_to_page [1/25] generic page_to_pfn / pfn_to_page
@ 2006-02-06 10:46 KAMEZAWA Hiroyuki
  0 siblings, 0 replies; only message in thread
From: KAMEZAWA Hiroyuki @ 2006-02-06 10:46 UTC (permalink / raw)
  To: Linux Kernel Mailing List

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 <kamezawa.hiroyu@jp.fujitu.com>


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)
  {



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-02-06 10:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-06 10:46 [RFC][PATCH] unify pfn_to_page [1/25] generic page_to_pfn / pfn_to_page KAMEZAWA Hiroyuki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox