Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thp: allow a hwpoisoned head page to be put back to LRU

Andrea Arcangeli pointed out to me that a check in __memory_failure()
which was intended to prevent THP tail pages from being checked for the
absence of the PG_lru flag (something that is always the case), was also
preventing THP head pages from being checked.

A THP head page could actually benefit from the call to shake_page() by
ending up being put back to a LRU, provided it had been waiting in a
pagevec array.

Andrea suggested that the "!PageTransCompound(p)" in the if-statement
should be replaced by a "!PageTransTail(p)", thus allowing THP head pages
to be checked and possibly shaken.

Signed-off-by: Dean Nelson <dnelson@redhat.com>
Cc: Jin Dongming <jin.dongming@np.css.fujitsu.com>
Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dean Nelson and committed by
Linus Torvalds
385de357 6d9d88d0

+21 -1
+20
include/linux/page-flags.h
··· 414 414 return PageHead(page); 415 415 } 416 416 417 + /* 418 + * PageTransCompound returns true for both transparent huge pages 419 + * and hugetlbfs pages, so it should only be called when it's known 420 + * that hugetlbfs pages aren't involved. 421 + */ 417 422 static inline int PageTransCompound(struct page *page) 418 423 { 419 424 return PageCompound(page); 425 + } 426 + 427 + /* 428 + * PageTransTail returns true for both transparent huge pages 429 + * and hugetlbfs pages, so it should only be called when it's known 430 + * that hugetlbfs pages aren't involved. 431 + */ 432 + static inline int PageTransTail(struct page *page) 433 + { 434 + return PageTail(page); 420 435 } 421 436 422 437 #else ··· 442 427 } 443 428 444 429 static inline int PageTransCompound(struct page *page) 430 + { 431 + return 0; 432 + } 433 + 434 + static inline int PageTransTail(struct page *page) 445 435 { 446 436 return 0; 447 437 }
+1 -1
mm/memory-failure.c
··· 1063 1063 * The check (unnecessarily) ignores LRU pages being isolated and 1064 1064 * walked by the page reclaim code, however that's not a big loss. 1065 1065 */ 1066 - if (!PageHuge(p) && !PageTransCompound(p)) { 1066 + if (!PageHuge(p) && !PageTransTail(p)) { 1067 1067 if (!PageLRU(p)) 1068 1068 shake_page(p, 0); 1069 1069 if (!PageLRU(p)) {