@@ -1009,22 +1009,6 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
1009
1009
return unmap_success ;
1010
1010
}
1011
1011
1012
- static void set_page_hwpoison_huge_page (struct page * hpage )
1013
- {
1014
- int i ;
1015
- int nr_pages = 1 << compound_order (hpage );
1016
- for (i = 0 ; i < nr_pages ; i ++ )
1017
- SetPageHWPoison (hpage + i );
1018
- }
1019
-
1020
- static void clear_page_hwpoison_huge_page (struct page * hpage )
1021
- {
1022
- int i ;
1023
- int nr_pages = 1 << compound_order (hpage );
1024
- for (i = 0 ; i < nr_pages ; i ++ )
1025
- ClearPageHWPoison (hpage + i );
1026
- }
1027
-
1028
1012
/**
1029
1013
* memory_failure - Handle memory failure of a page.
1030
1014
* @pfn: Page Number of the corrupted page
@@ -1050,7 +1034,6 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1050
1034
struct page * hpage ;
1051
1035
struct page * orig_head ;
1052
1036
int res ;
1053
- unsigned int nr_pages ;
1054
1037
unsigned long page_flags ;
1055
1038
1056
1039
if (!sysctl_memory_failure_recovery )
@@ -1064,24 +1047,23 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1064
1047
1065
1048
p = pfn_to_page (pfn );
1066
1049
orig_head = hpage = compound_head (p );
1050
+
1051
+ /* tmporary check code, to be updated in later patches */
1052
+ if (PageHuge (p )) {
1053
+ if (TestSetPageHWPoison (hpage )) {
1054
+ pr_err ("Memory failure: %#lx: already hardware poisoned\n" , pfn );
1055
+ return 0 ;
1056
+ }
1057
+ goto tmp ;
1058
+ }
1067
1059
if (TestSetPageHWPoison (p )) {
1068
1060
pr_err ("Memory failure: %#lx: already hardware poisoned\n" ,
1069
1061
pfn );
1070
1062
return 0 ;
1071
1063
}
1072
1064
1073
- /*
1074
- * Currently errors on hugetlbfs pages are measured in hugepage units,
1075
- * so nr_pages should be 1 << compound_order. OTOH when errors are on
1076
- * transparent hugepages, they are supposed to be split and error
1077
- * measurement is done in normal page units. So nr_pages should be one
1078
- * in this case.
1079
- */
1080
- if (PageHuge (p ))
1081
- nr_pages = 1 << compound_order (hpage );
1082
- else /* normal page or thp */
1083
- nr_pages = 1 ;
1084
- num_poisoned_pages_add (nr_pages );
1065
+ tmp :
1066
+ num_poisoned_pages_inc ();
1085
1067
1086
1068
/*
1087
1069
* We need/can do nothing about count=0 pages.
@@ -1109,12 +1091,11 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1109
1091
if (PageHWPoison (hpage )) {
1110
1092
if ((hwpoison_filter (p ) && TestClearPageHWPoison (p ))
1111
1093
|| (p != hpage && TestSetPageHWPoison (hpage ))) {
1112
- num_poisoned_pages_sub ( nr_pages );
1094
+ num_poisoned_pages_dec ( );
1113
1095
unlock_page (hpage );
1114
1096
return 0 ;
1115
1097
}
1116
1098
}
1117
- set_page_hwpoison_huge_page (hpage );
1118
1099
res = dequeue_hwpoisoned_huge_page (hpage );
1119
1100
action_result (pfn , MF_MSG_FREE_HUGE ,
1120
1101
res ? MF_IGNORED : MF_DELAYED );
@@ -1137,7 +1118,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1137
1118
pr_err ("Memory failure: %#lx: thp split failed\n" ,
1138
1119
pfn );
1139
1120
if (TestClearPageHWPoison (p ))
1140
- num_poisoned_pages_sub ( nr_pages );
1121
+ num_poisoned_pages_dec ( );
1141
1122
put_hwpoison_page (p );
1142
1123
return - EBUSY ;
1143
1124
}
@@ -1193,14 +1174,14 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1193
1174
*/
1194
1175
if (!PageHWPoison (p )) {
1195
1176
pr_err ("Memory failure: %#lx: just unpoisoned\n" , pfn );
1196
- num_poisoned_pages_sub ( nr_pages );
1177
+ num_poisoned_pages_dec ( );
1197
1178
unlock_page (hpage );
1198
1179
put_hwpoison_page (hpage );
1199
1180
return 0 ;
1200
1181
}
1201
1182
if (hwpoison_filter (p )) {
1202
1183
if (TestClearPageHWPoison (p ))
1203
- num_poisoned_pages_sub ( nr_pages );
1184
+ num_poisoned_pages_dec ( );
1204
1185
unlock_page (hpage );
1205
1186
put_hwpoison_page (hpage );
1206
1187
return 0 ;
@@ -1219,14 +1200,6 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1219
1200
put_hwpoison_page (hpage );
1220
1201
return 0 ;
1221
1202
}
1222
- /*
1223
- * Set PG_hwpoison on all pages in an error hugepage,
1224
- * because containment is done in hugepage unit for now.
1225
- * Since we have done TestSetPageHWPoison() for the head page with
1226
- * page lock held, we can safely set PG_hwpoison bits on tail pages.
1227
- */
1228
- if (PageHuge (p ))
1229
- set_page_hwpoison_huge_page (hpage );
1230
1203
1231
1204
/*
1232
1205
* It's very difficult to mess with pages currently under IO
@@ -1397,7 +1370,6 @@ int unpoison_memory(unsigned long pfn)
1397
1370
struct page * page ;
1398
1371
struct page * p ;
1399
1372
int freeit = 0 ;
1400
- unsigned int nr_pages ;
1401
1373
static DEFINE_RATELIMIT_STATE (unpoison_rs , DEFAULT_RATELIMIT_INTERVAL ,
1402
1374
DEFAULT_RATELIMIT_BURST ) ;
1403
1375
@@ -1442,8 +1414,6 @@ int unpoison_memory(unsigned long pfn)
1442
1414
return 0 ;
1443
1415
}
1444
1416
1445
- nr_pages = 1 << compound_order (page );
1446
-
1447
1417
if (!get_hwpoison_page (p )) {
1448
1418
/*
1449
1419
* Since HWPoisoned hugepage should have non-zero refcount,
@@ -1473,10 +1443,8 @@ int unpoison_memory(unsigned long pfn)
1473
1443
if (TestClearPageHWPoison (page )) {
1474
1444
unpoison_pr_info ("Unpoison: Software-unpoisoned page %#lx\n" ,
1475
1445
pfn , & unpoison_rs );
1476
- num_poisoned_pages_sub ( nr_pages );
1446
+ num_poisoned_pages_dec ( );
1477
1447
freeit = 1 ;
1478
- if (PageHuge (page ))
1479
- clear_page_hwpoison_huge_page (page );
1480
1448
}
1481
1449
unlock_page (page );
1482
1450
@@ -1608,14 +1576,10 @@ static int soft_offline_huge_page(struct page *page, int flags)
1608
1576
ret = - EIO ;
1609
1577
} else {
1610
1578
/* overcommit hugetlb page will be freed to buddy */
1611
- if ( PageHuge ( page )) {
1612
- set_page_hwpoison_huge_page ( hpage );
1579
+ SetPageHWPoison ( page );
1580
+ if ( PageHuge ( page ))
1613
1581
dequeue_hwpoisoned_huge_page (hpage );
1614
- num_poisoned_pages_add (1 << compound_order (hpage ));
1615
- } else {
1616
- SetPageHWPoison (page );
1617
- num_poisoned_pages_inc ();
1618
- }
1582
+ num_poisoned_pages_inc ();
1619
1583
}
1620
1584
return ret ;
1621
1585
}
@@ -1731,15 +1695,12 @@ static int soft_offline_in_use_page(struct page *page, int flags)
1731
1695
1732
1696
static void soft_offline_free_page (struct page * page )
1733
1697
{
1734
- if (PageHuge (page )) {
1735
- struct page * hpage = compound_head (page );
1698
+ struct page * head = compound_head (page );
1736
1699
1737
- set_page_hwpoison_huge_page (hpage );
1738
- if (!dequeue_hwpoisoned_huge_page (hpage ))
1739
- num_poisoned_pages_add (1 << compound_order (hpage ));
1740
- } else {
1741
- if (!TestSetPageHWPoison (page ))
1742
- num_poisoned_pages_inc ();
1700
+ if (!TestSetPageHWPoison (head )) {
1701
+ num_poisoned_pages_inc ();
1702
+ if (PageHuge (head ))
1703
+ dequeue_hwpoisoned_huge_page (head );
1743
1704
}
1744
1705
}
1745
1706
0 commit comments