]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.arch/mm-avoid-bad-page-on-lru
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / mm-avoid-bad-page-on-lru
CommitLineData
00e5a55c
BS
1From: Russ Anderson <rja@sgi.com>
2Subject: mm: Avoid putting a bad page back on the LRU v8
3References: 415829
4Acked-by: schwab@suse.de
5
6Prevent a page with a physical memory error from being placed back
7on the LRU. A new page flag (PG_memerror) is added if
8CONFIG_PAGEFLAGS_EXTENDED is defined.
9
10Version 8 change: Removed hot path check for pages with memory
11errors on the free list.
12
13Signed-off-by: Russ Anderson <rja@sgi.com>
14Reviewed-by: Christoph Lameter <cl@linux-foundation.org>
15
16---
17 include/linux/page-flags.h | 15 ++++++++++++++-
18 mm/migrate.c | 36 +++++++++++++++++++++++++++++++++++-
19 2 files changed, 49 insertions(+), 2 deletions(-)
20
21Index: 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,
26 }
27 return ret;
28 }
29+EXPORT_SYMBOL(isolate_lru_page);
30
31 /*
32 * migrate_prep() needs to be called before we start compiling a list of pages
33@@ -82,6 +83,7 @@ int migrate_prep(void)
34
35 return 0;
36 }
37+EXPORT_SYMBOL(migrate_prep);
38
39 static inline void move_to_lru(struct page *page)
40 {
41@@ -116,6 +118,7 @@ int putback_lru_pages(struct list_head *
42 }
43 return count;
44 }
45+EXPORT_SYMBOL(putback_lru_pages);
46
47 /*
48 * Restore a potential migration pte to a working pte entry
49@@ -741,7 +744,26 @@ unlock:
50 * restored.
51 */
52 list_del(&page->lru);
53- move_to_lru(page);
54+ if (PageMemError(page)) {
55+ if (rc == 0)
56+ /*
57+ * A page with a memory error that has
58+ * been migrated will not be moved to
59+ * the LRU.
60+ */
61+ goto move_newpage;
62+ else
63+ /*
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
68+ * error.
69+ */
70+ ClearPageMemError(page);
71+ }
72+
73+ move_to_lru(page);
74 }
75
76 move_newpage:
77@@ -813,6 +835,17 @@ int migrate_pages(struct list_head *from
78 }
79 }
80 }
81+
82+ if (rc != 0)
83+ list_for_each_entry_safe(page, page2, from, lru)
84+ if (PageMemError(page))
85+ /*
86+ * The page failed to migrate. Clearing
87+ * the error bit will allow another attempt
88+ * to migrate if it gets another correctable
89+ * error.
90+ */
91+ ClearPageMemError(page);
92 rc = 0;
93 out:
94 if (!swapwrite)
95@@ -825,6 +858,7 @@ out:
96
97 return nr_failed + retry;
98 }
99+EXPORT_SYMBOL(migrate_pages);
100
101 #ifdef CONFIG_NUMA
102 /*
103Index: 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 */
114 #else
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); }
118
119+#define PAGEFLAGMASK(uname, lname) \
120+static inline int PAGEMASK_##uname(void) \
121+ { return (1 << PG_##lname); }
122
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)
127
128 #define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
129 __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
130
131 #define PAGEFLAG_FALSE(uname) \
132 static inline int Page##uname(struct page *page) \
133+ { return 0; } \
134+static inline int PAGEMASK_##uname(void) \
135 { return 0; }
136
137 #define TESTSCFLAG(uname, lname) \
138@@ -325,6 +332,12 @@ static inline void __ClearPageTail(struc
139 }
140
141 #endif /* !PAGEFLAGS_EXTENDED */
142+
143+#ifdef CONFIG_PAGEFLAGS_EXTENDED
144+PAGEFLAG(MemError, memerror)
145+#else
146+PAGEFLAG_FALSE(MemError)
147+#endif
148
149 #define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \
150 1 << PG_buddy | 1 << PG_writeback | \