45
45
#include <linux/page-isolation.h>
46
46
#include <linux/suspend.h>
47
47
#include <linux/slab.h>
48
+ #include <linux/hugetlb.h>
48
49
#include "internal.h"
49
50
50
51
int sysctl_memory_failure_early_kill __read_mostly = 0 ;
@@ -837,6 +838,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
837
838
int ret ;
838
839
int i ;
839
840
int kill = 1 ;
841
+ struct page * hpage = compound_head (p );
840
842
841
843
if (PageReserved (p ) || PageSlab (p ))
842
844
return SWAP_SUCCESS ;
@@ -845,10 +847,10 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
845
847
* This check implies we don't kill processes if their pages
846
848
* are in the swap cache early. Those are always late kills.
847
849
*/
848
- if (!page_mapped (p ))
850
+ if (!page_mapped (hpage ))
849
851
return SWAP_SUCCESS ;
850
852
851
- if (PageCompound ( p ) || PageKsm (p ))
853
+ if (PageKsm (p ))
852
854
return SWAP_FAIL ;
853
855
854
856
if (PageSwapCache (p )) {
@@ -863,10 +865,11 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
863
865
* XXX: the dirty test could be racy: set_page_dirty() may not always
864
866
* be called inside page lock (it's recommended but not enforced).
865
867
*/
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 );
870
873
} else {
871
874
kill = 0 ;
872
875
ttu |= TTU_IGNORE_HWPOISON ;
@@ -885,22 +888,22 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
885
888
* there's nothing that can be done.
886
889
*/
887
890
if (kill )
888
- collect_procs (p , & tokill );
891
+ collect_procs (hpage , & tokill );
889
892
890
893
/*
891
894
* try_to_unmap can fail temporarily due to races.
892
895
* Try a few times (RED-PEN better strategy?)
893
896
*/
894
897
for (i = 0 ; i < N_UNMAP_TRIES ; i ++ ) {
895
- ret = try_to_unmap (p , ttu );
898
+ ret = try_to_unmap (hpage , ttu );
896
899
if (ret == SWAP_SUCCESS )
897
900
break ;
898
901
pr_debug ("MCE %#lx: try_to_unmap retry needed %d\n" , pfn , ret );
899
902
}
900
903
901
904
if (ret != SWAP_SUCCESS )
902
905
printk (KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n" ,
903
- pfn , page_mapcount (p ));
906
+ pfn , page_mapcount (hpage ));
904
907
905
908
/*
906
909
* 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,
911
914
* use a more force-full uncatchable kill to prevent
912
915
* any accesses to the poisoned memory.
913
916
*/
914
- kill_procs_ao (& tokill , !!PageDirty (p ), trapno ,
917
+ kill_procs_ao (& tokill , !!PageDirty (hpage ), trapno ,
915
918
ret != SWAP_SUCCESS , pfn );
916
919
917
920
return ret ;
@@ -921,6 +924,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
921
924
{
922
925
struct page_state * ps ;
923
926
struct page * p ;
927
+ struct page * hpage ;
924
928
int res ;
925
929
926
930
if (!sysctl_memory_failure_recovery )
@@ -934,6 +938,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
934
938
}
935
939
936
940
p = pfn_to_page (pfn );
941
+ hpage = compound_head (p );
937
942
if (TestSetPageHWPoison (p )) {
938
943
printk (KERN_ERR "MCE %#lx: already hardware poisoned\n" , pfn );
939
944
return 0 ;
@@ -953,7 +958,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
953
958
* that may make page_freeze_refs()/page_unfreeze_refs() mismatch.
954
959
*/
955
960
if (!(flags & MF_COUNT_INCREASED ) &&
956
- !get_page_unless_zero (compound_head ( p ) )) {
961
+ !get_page_unless_zero (hpage )) {
957
962
if (is_free_buddy_page (p )) {
958
963
action_result (pfn , "free buddy" , DELAYED );
959
964
return 0 ;
@@ -971,9 +976,9 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
971
976
* The check (unnecessarily) ignores LRU pages being isolated and
972
977
* walked by the page reclaim code, however that's not a big loss.
973
978
*/
974
- if (!PageLRU (p ))
979
+ if (!PageLRU (p ) && ! PageHuge ( p ) )
975
980
shake_page (p , 0 );
976
- if (!PageLRU (p )) {
981
+ if (!PageLRU (p ) && ! PageHuge ( p ) ) {
977
982
/*
978
983
* shake_page could have turned it free.
979
984
*/
@@ -991,7 +996,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
991
996
* It's very difficult to mess with pages currently under IO
992
997
* and in many cases impossible, so we just avoid it here.
993
998
*/
994
- lock_page_nosync (p );
999
+ lock_page_nosync (hpage );
995
1000
996
1001
/*
997
1002
* unpoison always clear PG_hwpoison inside page lock
@@ -1004,8 +1009,8 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
1004
1009
if (hwpoison_filter (p )) {
1005
1010
if (TestClearPageHWPoison (p ))
1006
1011
atomic_long_dec (& mce_bad_pages );
1007
- unlock_page (p );
1008
- put_page (p );
1012
+ unlock_page (hpage );
1013
+ put_page (hpage );
1009
1014
return 0 ;
1010
1015
}
1011
1016
@@ -1038,7 +1043,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
1038
1043
}
1039
1044
}
1040
1045
out :
1041
- unlock_page (p );
1046
+ unlock_page (hpage );
1042
1047
return res ;
1043
1048
}
1044
1049
EXPORT_SYMBOL_GPL (__memory_failure );
0 commit comments