Skip to contentSkip to conversation

naming reserved pages and remove PG_uncached [0/3]

RFC PATCH In review KAMEZAWA Hiroyuki 2 participants 5 messages Apr 28, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 naming reserved pages and remove PG_uncached [0/3]

Hi, Jes

I'm now writing a patch and want your comments .

(*)This patches add information to Reserved pages using page->private field.

I think pages markd with PG_uncached are not managed by alloc_pages()/free_pages(). So, instead of using PG_uncached, using (*) and reserved as "reserved_uncached" can work enough, I think.

"Allocating and isolating" method cannot work with memory-hotplug stuff.

Can this patch work with your mspec ?

[1/3] function for naming pages using page->private [2/3] name reserved_at_boot pages
[3/3] name reserved_uncached pages

Thanks.
-- Kame

#1 lore raw

RFC PATCH 1/1 naming reserved pages and remove PG_uncached [1/3]

inline functions for naming reserved pages.
-- Kame

This patch add additonal information to 'Reserved' pages. Information is stored in page->private.
Now, PG_reserved is used for many purpose and we cannot find why it is reserved easily.

I'm now thinking of distinguishing
a) Memory Hole
b) isolated by MCA
c) Reserved by drivers
d) others
,which are all "Reserved".
Further more investigation will be needed.

By the way there are two way to isolate pages,
(i) set PG_reserved
(ii) allocate and never free.

Using (i) and setting page->private correctly looks clearer way and wiil help memory-hotplug (and other stuffs).

---

 linux-2.6.12-rc2-mm3-kamezawa/include/linux/mm.h |   31 +++++++++++++++++++++++
 1 files changed, 31 insertions(+)
include/linux/mm.h renamed from include/linux/mm.h~name_reserved +31 -0
diff -puN include/linux/mm.h~name_reserved include/linux/mm.h
@@ -353,6 +353,37 @@ static inline void put_page(struct page 
 #endif		/* CONFIG_HUGETLB_PAGE */
 
 /*
+ * types of pages
+ * value range is 0-255.
+ */
+enum page_type {
+	page_common = 0,
+	reserved_unknown = 1,
+	reserved_at_boot,
+	max_reserved_types,
+	invalid_page_type = 0xff,
+};
+
+/*
+ * Basically, page->private has no meaning without PG_private.
+ * Here, we use page->private for PG_reserved pages to record a type of a page.
+ * Because a page is reserved, anyone will not modify page->private.
+ * When it is freed, page->private will be overwritten by some code.
+ */
+static inline void set_page_reserved(struct page *page, enum page_type type)
+{
+	SetPageReserved(page);
+	page->private = (unsigned long)type;
+}
+
+static inline unsigned char reserved_page_type(struct page *page)
+{
+	if (!PageReserved(page))
+		return 0;
+	return (unsigned char) page->private;
+}
+
+/*
  * Multiple processes may "see" the same page. E.g. for untouched
  * mappings of /dev/null, all processes see the same page full of
  * zeroes, and text pages of executables and shared libraries have

_

#2 lore raw

RFC PATCH 1/1 naming reserved pages and remove PG_uncached [2/3]

In reply to KAMEZAWA Hiroyuki

set reserved_at_boot
-- Kame

set reserved_at_boot in page->private at the boot time.

---

 linux-2.6.12-rc2-mm3-kamezawa/mm/page_alloc.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c renamed from mm/page_alloc.c~set_rsvd_at_boot +1 -1
diff -puN mm/page_alloc.c~set_rsvd_at_boot mm/page_alloc.c
@@ -1641,7 +1641,7 @@ void __init memmap_init_zone(unsigned lo
 		set_page_links(page, zone, nid);
 		set_page_count(page, 0);
 		reset_page_mapcount(page);
-		SetPageReserved(page);
+		set_page_reserved(page, reserved_at_boot);
 		INIT_LIST_HEAD(&page->lru);
 #ifdef WANT_PAGE_VIRTUAL
 		/* The shift won't overflow because ZONE_NORMAL is below 4G. */

_

#3 lore raw

RFC PATCH 1/1 naming reserved pages and remove PG_uncached [3/3]

In reply to KAMEZAWA Hiroyuki

removing PG_uncached
-- Kame

Now, PG_uncached is used to remember that a page is uncached.

PG_uncached pages is not freed or allocated while it is uncached. So, PageReserved(page) && ( page->private = reserved_uncached) can work enough, I think.

---

 linux-2.6.12-rc2-mm3-kamezawa/include/asm-ia64/uaccess.h |    4 +-
 linux-2.6.12-rc2-mm3-kamezawa/include/linux/mm.h         |   21 ++++++++++++---
 linux-2.6.12-rc2-mm3-kamezawa/include/linux/page-flags.h |    3 --
 3 files changed, 20 insertions(+), 8 deletions(-)
include/linux/mm.h renamed from include/linux/mm.h~uncached_rsvd_page +18 -3
diff -puN include/linux/mm.h~uncached_rsvd_page include/linux/mm.h
@@ -358,10 +358,11 @@ static inline void put_page(struct page 
  */
 enum page_type {
 	page_common = 0,
-	reserved_unknown = 1,
-	reserved_at_boot,
+	page_reserved_unknown = 1,
+	page_reserved_at_boot,
+	page_reserved_uncached,
 	max_reserved_types,
-	invalid_page_type = 0xff,
+	page_invalid_type = 0xff,
 };
 
 /*
@@ -376,6 +377,12 @@ static inline void set_page_reserved(str
 	page->private = (unsigned long)type;
 }
 
+static inline void clear_page_reserved(struct page *page)
+{
+	page->private = 0;
+	ClearPageReserved(page);
+}
+
 static inline unsigned char reserved_page_type(struct page *page)
 {
 	if (!PageReserved(page))
@@ -383,6 +390,14 @@ static inline unsigned char reserved_pag
 	return (unsigned char) page->private;
 }
 
+#define set_page_uncached(page) \
+	set_page_reserved((page), page_reserved_uncached)
+#define clr_page_uncahced(page)\
+	clear_page_reserved(page);
+#define page_is_uncached(page)\
+	(reserved_page_type(page) == page_reserved_uncached)
+
+
 /*
  * Multiple processes may "see" the same page. E.g. for untouched
  * mappings of /dev/null, all processes see the same page full of
include/linux/page-flags.h renamed from include/linux/page-flags.h~uncached_rsvd_page +0 -3
diff -puN include/linux/page-flags.h~uncached_rsvd_page include/linux/page-flags.h
@@ -302,9 +302,6 @@ extern void __mod_page_state(unsigned of
 #define PageSwapCache(page)	0
 #endif
 
-#define PageUncached(page)	test_bit(PG_uncached, &(page)->flags)
-#define SetPageUncached(page)	set_bit(PG_uncached, &(page)->flags)
-#define ClearPageUncached(page)	clear_bit(PG_uncached, &(page)->flags)
 
 struct page;	/* forward declaration */
 
include/asm-ia64/uaccess.h renamed from include/asm-ia64/uaccess.h~uncached_rsvd_page +2 -2
diff -puN include/asm-ia64/uaccess.h~uncached_rsvd_page include/asm-ia64/uaccess.h
@@ -379,7 +379,7 @@ xlate_dev_mem_ptr (unsigned long p)
 	char * ptr;
 
 	page = pfn_to_page(p >> PAGE_SHIFT);
-	if (PageUncached(page))
+	if (page_is_uncached(page))
 		ptr = (char *)p + __IA64_UNCACHED_OFFSET;
 	else
 		ptr = __va(p);
@@ -397,7 +397,7 @@ xlate_dev_kmem_ptr (char * p)
 	char * ptr;
 
 	page = virt_to_page((unsigned long)p >> PAGE_SHIFT);
-	if (PageUncached(page))
+	if (page_is_uncached(page))
 		ptr = (char *)__pa(p) + __IA64_UNCACHED_OFFSET;
 	else
 		ptr = p;

_