1 From: Russ Anderson <rja@sgi.com>
2 Subject: mm: Avoid putting a bad page back on the LRU v8
4 Acked-by: schwab@suse.de
6 Prevent a page with a physical memory error from being placed back
7 on the LRU. A new page flag (PG_memerror) is added if
8 CONFIG_PAGEFLAGS_EXTENDED is defined.
10 Version 8 change: Removed hot path check for pages with memory
11 errors on the free list.
13 Signed-off-by: Russ Anderson <rja@sgi.com>
14 Reviewed-by: Christoph Lameter <cl@linux-foundation.org>
17 include/linux/page-flags.h | 15 ++++++++++++++-
18 mm/migrate.c | 36 +++++++++++++++++++++++++++++++++++-
19 2 files changed, 49 insertions(+), 2 deletions(-)
21 Index: linux/mm/migrate.c
22 ===================================================================
23 --- linux.orig/mm/migrate.c 2008-07-29 13:18:23.000000000 -0500
24 +++ linux/mm/migrate.c 2008-07-29 13:21:03.000000000 -0500
25 @@ -65,6 +65,7 @@ int isolate_lru_page(struct page *page,
29 +EXPORT_SYMBOL(isolate_lru_page);
32 * migrate_prep() needs to be called before we start compiling a list of pages
33 @@ -82,6 +83,7 @@ int migrate_prep(void)
37 +EXPORT_SYMBOL(migrate_prep);
39 static inline void move_to_lru(struct page *page)
41 @@ -116,6 +118,7 @@ int putback_lru_pages(struct list_head *
45 +EXPORT_SYMBOL(putback_lru_pages);
48 * Restore a potential migration pte to a working pte entry
49 @@ -741,7 +744,26 @@ unlock:
54 + if (PageMemError(page)) {
57 + * A page with a memory error that has
58 + * been migrated will not be moved to
64 + * The page failed to migrate and will not
65 + * be added to the bad page list. Clearing
66 + * the error bit will allow another attempt
67 + * to migrate if it gets another correctable
70 + ClearPageMemError(page);
77 @@ -813,6 +835,17 @@ int migrate_pages(struct list_head *from
83 + list_for_each_entry_safe(page, page2, from, lru)
84 + if (PageMemError(page))
86 + * The page failed to migrate. Clearing
87 + * the error bit will allow another attempt
88 + * to migrate if it gets another correctable
91 + ClearPageMemError(page);
95 @@ -825,6 +858,7 @@ out:
97 return nr_failed + retry;
99 +EXPORT_SYMBOL(migrate_pages);
103 Index: linux/include/linux/page-flags.h
104 ===================================================================
105 --- linux.orig/include/linux/page-flags.h 2008-07-29 13:18:23.000000000 -0500
106 +++ linux/include/linux/page-flags.h 2008-07-29 13:21:03.000000000 -0500
107 @@ -84,6 +84,7 @@ enum pageflags {
108 PG_private, /* If pagecache, has fs-private data */
109 PG_writeback, /* Page is under writeback */
110 #ifdef CONFIG_PAGEFLAGS_EXTENDED
111 + PG_memerror, /* Page has a physical memory error */
112 PG_head, /* A head page */
113 PG_tail, /* A tail page */
115 @@ -147,15 +148,21 @@ static inline int TestSetPage##uname(str
116 static inline int TestClearPage##uname(struct page *page) \
117 { return test_and_clear_bit(PG_##lname, &page->flags); }
119 +#define PAGEFLAGMASK(uname, lname) \
120 +static inline int PAGEMASK_##uname(void) \
121 + { return (1 << PG_##lname); }
123 #define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
124 - SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
125 + SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname) \
126 + PAGEFLAGMASK(uname, lname)
128 #define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
129 __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
131 #define PAGEFLAG_FALSE(uname) \
132 static inline int Page##uname(struct page *page) \
134 +static inline int PAGEMASK_##uname(void) \
137 #define TESTSCFLAG(uname, lname) \
138 @@ -325,6 +332,12 @@ static inline void __ClearPageTail(struc
141 #endif /* !PAGEFLAGS_EXTENDED */
143 +#ifdef CONFIG_PAGEFLAGS_EXTENDED
144 +PAGEFLAG(MemError, memerror)
146 +PAGEFLAG_FALSE(MemError)
149 #define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \
150 1 << PG_buddy | 1 << PG_writeback | \