]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.arch/mm-avoid-bad-page-on-lru
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / mm-avoid-bad-page-on-lru
diff --git a/src/patches/suse-2.6.27.31/patches.arch/mm-avoid-bad-page-on-lru b/src/patches/suse-2.6.27.31/patches.arch/mm-avoid-bad-page-on-lru
new file mode 100644 (file)
index 0000000..6cbad12
--- /dev/null
@@ -0,0 +1,150 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: mm: Avoid putting a bad page back on the LRU v8
+References: 415829
+Acked-by: schwab@suse.de
+
+Prevent a page with a physical memory error from being placed back
+on the LRU.  A new page flag (PG_memerror) is added if
+CONFIG_PAGEFLAGS_EXTENDED is defined.  
+
+Version 8 change:  Removed hot path check for pages with memory
+errors on the free list.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Reviewed-by: Christoph Lameter <cl@linux-foundation.org>
+
+---
+ include/linux/page-flags.h |   15 ++++++++++++++-
+ mm/migrate.c               |   36 +++++++++++++++++++++++++++++++++++-
+ 2 files changed, 49 insertions(+), 2 deletions(-)
+
+Index: linux/mm/migrate.c
+===================================================================
+--- linux.orig/mm/migrate.c    2008-07-29 13:18:23.000000000 -0500
++++ linux/mm/migrate.c 2008-07-29 13:21:03.000000000 -0500
+@@ -65,6 +65,7 @@ int isolate_lru_page(struct page *page, 
+       }
+       return ret;
+ }
++EXPORT_SYMBOL(isolate_lru_page);
+ /*
+  * migrate_prep() needs to be called before we start compiling a list of pages
+@@ -82,6 +83,7 @@ int migrate_prep(void)
+       return 0;
+ }
++EXPORT_SYMBOL(migrate_prep);
+ static inline void move_to_lru(struct page *page)
+ {
+@@ -116,6 +118,7 @@ int putback_lru_pages(struct list_head *
+       }
+       return count;
+ }
++EXPORT_SYMBOL(putback_lru_pages);
+ /*
+  * Restore a potential migration pte to a working pte entry
+@@ -741,7 +744,26 @@ unlock:
+                * restored.
+                */
+               list_del(&page->lru);
+-              move_to_lru(page);
++              if (PageMemError(page)) {
++                      if (rc == 0)
++                              /*
++                               * A page with a memory error that has
++                               * been migrated will not be moved to
++                               * the LRU.
++                               */
++                              goto move_newpage;
++                      else
++                              /*
++                               * The page failed to migrate and will not
++                               * be added to the bad page list.  Clearing
++                               * the error bit will allow another attempt
++                               * to migrate if it gets another correctable
++                               * error.
++                               */
++                              ClearPageMemError(page);
++              }
++
++              move_to_lru(page);
+       }
+ move_newpage:
+@@ -813,6 +835,17 @@ int migrate_pages(struct list_head *from
+                       }
+               }
+       }
++
++      if (rc != 0)
++              list_for_each_entry_safe(page, page2, from, lru)
++                      if (PageMemError(page))
++                              /*
++                               * The page failed to migrate.  Clearing
++                               * the error bit will allow another attempt
++                               * to migrate if it gets another correctable
++                               * error.
++                               */
++                              ClearPageMemError(page);
+       rc = 0;
+ out:
+       if (!swapwrite)
+@@ -825,6 +858,7 @@ out:
+       return nr_failed + retry;
+ }
++EXPORT_SYMBOL(migrate_pages);
+ #ifdef CONFIG_NUMA
+ /*
+Index: linux/include/linux/page-flags.h
+===================================================================
+--- linux.orig/include/linux/page-flags.h      2008-07-29 13:18:23.000000000 -0500
++++ linux/include/linux/page-flags.h   2008-07-29 13:21:03.000000000 -0500
+@@ -84,6 +84,7 @@ enum pageflags {
+       PG_private,             /* If pagecache, has fs-private data */
+       PG_writeback,           /* Page is under writeback */
+ #ifdef CONFIG_PAGEFLAGS_EXTENDED
++      PG_memerror,            /* Page has a physical memory error */
+       PG_head,                /* A head page */
+       PG_tail,                /* A tail page */
+ #else
+@@ -147,15 +148,21 @@ static inline int TestSetPage##uname(str
+ static inline int TestClearPage##uname(struct page *page)             \
+               { return test_and_clear_bit(PG_##lname, &page->flags); }
++#define PAGEFLAGMASK(uname, lname)                                    \
++static inline int PAGEMASK_##uname(void)                              \
++              { return (1 << PG_##lname); }
+ #define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)             \
+-      SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
++      SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)           \
++      PAGEFLAGMASK(uname, lname)
+ #define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)           \
+       __SETPAGEFLAG(uname, lname)  __CLEARPAGEFLAG(uname, lname)
+ #define PAGEFLAG_FALSE(uname)                                                 \
+ static inline int Page##uname(struct page *page)                      \
++                      { return 0; }                                   \
++static inline int PAGEMASK_##uname(void)                              \
+                       { return 0; }
+ #define TESTSCFLAG(uname, lname)                                      \
+@@ -325,6 +332,12 @@ static inline void __ClearPageTail(struc
+ }
+ #endif /* !PAGEFLAGS_EXTENDED */
++
++#ifdef CONFIG_PAGEFLAGS_EXTENDED
++PAGEFLAG(MemError, memerror)
++#else
++PAGEFLAG_FALSE(MemError)
++#endif
+ #define PAGE_FLAGS    (1 << PG_lru   | 1 << PG_private   | 1 << PG_locked | \
+                        1 << PG_buddy | 1 << PG_writeback | \