4545#include <linux/page-isolation.h>
4646#include <linux/suspend.h>
4747#include <linux/slab.h>
48+ #include <linux/hugetlb.h>
4849#include "internal.h"
4950
5051int sysctl_memory_failure_early_kill __read_mostly = 0 ;
@@ -837,6 +838,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
837838 int ret ;
838839 int i ;
839840 int kill = 1 ;
841+ struct page * hpage = compound_head (p );
840842
841843 if (PageReserved (p ) || PageSlab (p ))
842844 return SWAP_SUCCESS ;
@@ -845,10 +847,10 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
845847 * This check implies we don't kill processes if their pages
846848 * are in the swap cache early. Those are always late kills.
847849 */
848- if (!page_mapped (p ))
850+ if (!page_mapped (hpage ))
849851 return SWAP_SUCCESS ;
850852
851- if (PageCompound ( p ) || PageKsm (p ))
853+ if (PageKsm (p ))
852854 return SWAP_FAIL ;
853855
854856 if (PageSwapCache (p )) {
@@ -863,10 +865,11 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
863865 * XXX: the dirty test could be racy: set_page_dirty() may not always
864866 * be called inside page lock (it's recommended but not enforced).
865867 */
866- mapping = page_mapping (p );
867- if (!PageDirty (p ) && mapping && mapping_cap_writeback_dirty (mapping )) {
868- if (page_mkclean (p )) {
869- SetPageDirty (p );
868+ mapping = page_mapping (hpage );
869+ if (!PageDirty (hpage ) && mapping &&
870+ mapping_cap_writeback_dirty (mapping )) {
871+ if (page_mkclean (hpage )) {
872+ SetPageDirty (hpage );
870873 } else {
871874 kill = 0 ;
872875 ttu |= TTU_IGNORE_HWPOISON ;
@@ -885,22 +888,22 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
885888 * there's nothing that can be done.
886889 */
887890 if (kill )
888- collect_procs (p , & tokill );
891+ collect_procs (hpage , & tokill );
889892
890893 /*
891894 * try_to_unmap can fail temporarily due to races.
892895 * Try a few times (RED-PEN better strategy?)
893896 */
894897 for (i = 0 ; i < N_UNMAP_TRIES ; i ++ ) {
895- ret = try_to_unmap (p , ttu );
898+ ret = try_to_unmap (hpage , ttu );
896899 if (ret == SWAP_SUCCESS )
897900 break ;
898901 pr_debug ("MCE %#lx: try_to_unmap retry needed %d\n" , pfn , ret );
899902 }
900903
901904 if (ret != SWAP_SUCCESS )
902905 printk (KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n" ,
903- pfn , page_mapcount (p ));
906+ pfn , page_mapcount (hpage ));
904907
905908 /*
906909 * Now that the dirty bit has been propagated to the
@@ -911,7 +914,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
911914 * use a more force-full uncatchable kill to prevent
912915 * any accesses to the poisoned memory.
913916 */
914- kill_procs_ao (& tokill , !!PageDirty (p ), trapno ,
917+ kill_procs_ao (& tokill , !!PageDirty (hpage ), trapno ,
915918 ret != SWAP_SUCCESS , pfn );
916919
917920 return ret ;
@@ -921,6 +924,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
921924{
922925 struct page_state * ps ;
923926 struct page * p ;
927+ struct page * hpage ;
924928 int res ;
925929
926930 if (!sysctl_memory_failure_recovery )
@@ -934,6 +938,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
934938 }
935939
936940 p = pfn_to_page (pfn );
941+ hpage = compound_head (p );
937942 if (TestSetPageHWPoison (p )) {
938943 printk (KERN_ERR "MCE %#lx: already hardware poisoned\n" , pfn );
939944 return 0 ;
@@ -953,7 +958,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
953958 * that may make page_freeze_refs()/page_unfreeze_refs() mismatch.
954959 */
955960 if (!(flags & MF_COUNT_INCREASED ) &&
956- !get_page_unless_zero (compound_head ( p ) )) {
961+ !get_page_unless_zero (hpage )) {
957962 if (is_free_buddy_page (p )) {
958963 action_result (pfn , "free buddy" , DELAYED );
959964 return 0 ;
@@ -971,9 +976,9 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
971976 * The check (unnecessarily) ignores LRU pages being isolated and
972977 * walked by the page reclaim code, however that's not a big loss.
973978 */
974- if (!PageLRU (p ))
979+ if (!PageLRU (p ) && ! PageHuge ( p ) )
975980 shake_page (p , 0 );
976- if (!PageLRU (p )) {
981+ if (!PageLRU (p ) && ! PageHuge ( p ) ) {
977982 /*
978983 * shake_page could have turned it free.
979984 */
@@ -991,7 +996,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
991996 * It's very difficult to mess with pages currently under IO
992997 * and in many cases impossible, so we just avoid it here.
993998 */
994- lock_page_nosync (p );
999+ lock_page_nosync (hpage );
9951000
9961001 /*
9971002 * unpoison always clear PG_hwpoison inside page lock
@@ -1004,8 +1009,8 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
10041009 if (hwpoison_filter (p )) {
10051010 if (TestClearPageHWPoison (p ))
10061011 atomic_long_dec (& mce_bad_pages );
1007- unlock_page (p );
1008- put_page (p );
1012+ unlock_page (hpage );
1013+ put_page (hpage );
10091014 return 0 ;
10101015 }
10111016
@@ -1038,7 +1043,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
10381043 }
10391044 }
10401045out :
1041- unlock_page (p );
1046+ unlock_page (hpage );
10421047 return res ;
10431048}
10441049EXPORT_SYMBOL_GPL (__memory_failure );
0 commit comments