mm: hwpoison: ratelimit messages from unpoison_memory()
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Fri, 6 Nov 2015 02:47:26 +0000 (18:47 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Nov 2015 03:34:48 +0000 (19:34 -0800)
Currently kernel prints out results of every single unpoison event, which
i= s not necessary because unpoison is purely a testing feature and
testers can = get little or no information from lots of lines of unpoison
log storm.  So this patch ratelimits printk in unpoison_memory().

This patch introduces a file local ratelimit_state, which adds 64 bytes to
memory-failure.o.  If we apply pr_info_ratelimited() for 8 callsite below,
2= 56 bytes is added, so it's a win.

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Wanpeng Li <wanpeng.li@hotmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/memory-failure.c

index 95882692e747c2a534488190287e5954fba35d39..16a0ec385320a06e09ddde61b804b51c63d952c6 100644 (file)
@@ -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))