|
@@ -56,6 +56,7 @@
|
|
|
#include <linux/memory_hotplug.h>
|
|
|
#include <linux/mm_inline.h>
|
|
|
#include <linux/kfifo.h>
|
|
|
+#include <linux/ratelimit.h>
|
|
|
#include "internal.h"
|
|
|
#include "ras/ras_event.h"
|
|
|
|
|
@@ -1403,6 +1404,12 @@ static int __init memory_failure_init(void)
|
|
|
}
|
|
|
core_initcall(memory_failure_init);
|
|
|
|
|
|
+#define unpoison_pr_info(fmt, pfn, rs) \
|
|
|
+({ \
|
|
|
+ if (__ratelimit(rs)) \
|
|
|
+ pr_info(fmt, pfn); \
|
|
|
+})
|
|
|
+
|
|
|
/**
|
|
|
* unpoison_memory - Unpoison a previously poisoned page
|
|
|
* @pfn: Page number of the to be unpoisoned page
|
|
@@ -1421,6 +1428,8 @@ int unpoison_memory(unsigned long pfn)
|
|
|
struct page *p;
|
|
|
int freeit = 0;
|
|
|
unsigned int nr_pages;
|
|
|
+ static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL,
|
|
|
+ DEFAULT_RATELIMIT_BURST);
|
|
|
|
|
|
if (!pfn_valid(pfn))
|
|
|
return -ENXIO;
|
|
@@ -1429,23 +1438,26 @@ int unpoison_memory(unsigned long pfn)
|
|
|
page = compound_head(p);
|
|
|
|
|
|
if (!PageHWPoison(p)) {
|
|
|
- pr_info("MCE: Page was already unpoisoned %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Page was already unpoisoned %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
if (page_count(page) > 1) {
|
|
|
- pr_info("MCE: Someone grabs the hwpoison page %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Someone grabs the hwpoison page %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
if (page_mapped(page)) {
|
|
|
- pr_info("MCE: Someone maps the hwpoison page %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Someone maps the hwpoison page %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
if (page_mapping(page)) {
|
|
|
- pr_info("MCE: the hwpoison page has non-NULL mapping %#lx\n",
|
|
|
- pfn);
|
|
|
+ unpoison_pr_info("MCE: the hwpoison page has non-NULL mapping %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1455,7 +1467,8 @@ int unpoison_memory(unsigned long pfn)
|
|
|
* In such case, we yield to memory_failure() and make unpoison fail.
|
|
|
*/
|
|
|
if (!PageHuge(page) && PageTransHuge(page)) {
|
|
|
- pr_info("MCE: Memory failure is now running on %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Memory failure is now running on %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1469,12 +1482,14 @@ int unpoison_memory(unsigned long pfn)
|
|
|
* to the end.
|
|
|
*/
|
|
|
if (PageHuge(page)) {
|
|
|
- pr_info("MCE: Memory failure is now running on free hugepage %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Memory failure is now running on free hugepage %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
if (TestClearPageHWPoison(p))
|
|
|
num_poisoned_pages_dec();
|
|
|
- pr_info("MCE: Software-unpoisoned free page %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Software-unpoisoned free page %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1486,7 +1501,8 @@ int unpoison_memory(unsigned long pfn)
|
|
|
* the free buddy page pool.
|
|
|
*/
|
|
|
if (TestClearPageHWPoison(page)) {
|
|
|
- pr_info("MCE: Software-unpoisoned page %#lx\n", pfn);
|
|
|
+ unpoison_pr_info("MCE: Software-unpoisoned page %#lx\n",
|
|
|
+ pfn, &unpoison_rs);
|
|
|
num_poisoned_pages_sub(nr_pages);
|
|
|
freeit = 1;
|
|
|
if (PageHuge(page))
|