|
@@ -30,6 +30,7 @@
|
|
|
#include <linux/pagevec.h>
|
|
|
#include <linux/blkdev.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/ratelimit.h>
|
|
|
#include <linux/oom.h>
|
|
|
#include <linux/notifier.h>
|
|
|
#include <linux/topology.h>
|
|
@@ -1736,6 +1737,45 @@ static inline bool should_suppress_show_mem(void)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static DEFINE_RATELIMIT_STATE(nopage_rs,
|
|
|
+ DEFAULT_RATELIMIT_INTERVAL,
|
|
|
+ DEFAULT_RATELIMIT_BURST);
|
|
|
+
|
|
|
+void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...)
|
|
|
+{
|
|
|
+ va_list args;
|
|
|
+ unsigned int filter = SHOW_MEM_FILTER_NODES;
|
|
|
+
|
|
|
+ if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This documents exceptions given to allocations in certain
|
|
|
+ * contexts that are allowed to allocate outside current's set
|
|
|
+ * of allowed nodes.
|
|
|
+ */
|
|
|
+ if (!(gfp_mask & __GFP_NOMEMALLOC))
|
|
|
+ if (test_thread_flag(TIF_MEMDIE) ||
|
|
|
+ (current->flags & (PF_MEMALLOC | PF_EXITING)))
|
|
|
+ filter &= ~SHOW_MEM_FILTER_NODES;
|
|
|
+ if (in_interrupt() || !(gfp_mask & __GFP_WAIT))
|
|
|
+ filter &= ~SHOW_MEM_FILTER_NODES;
|
|
|
+
|
|
|
+ if (fmt) {
|
|
|
+ printk(KERN_WARNING);
|
|
|
+ va_start(args, fmt);
|
|
|
+ vprintk(fmt, args);
|
|
|
+ va_end(args);
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_warning("%s: page allocation failure: order:%d, mode:0x%x\n",
|
|
|
+ current->comm, order, gfp_mask);
|
|
|
+
|
|
|
+ dump_stack();
|
|
|
+ if (!should_suppress_show_mem())
|
|
|
+ show_mem(filter);
|
|
|
+}
|
|
|
+
|
|
|
static inline int
|
|
|
should_alloc_retry(gfp_t gfp_mask, unsigned int order,
|
|
|
unsigned long pages_reclaimed)
|
|
@@ -2178,27 +2218,7 @@ rebalance:
|
|
|
}
|
|
|
|
|
|
nopage:
|
|
|
- if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
|
|
|
- unsigned int filter = SHOW_MEM_FILTER_NODES;
|
|
|
-
|
|
|
- /*
|
|
|
- * This documents exceptions given to allocations in certain
|
|
|
- * contexts that are allowed to allocate outside current's set
|
|
|
- * of allowed nodes.
|
|
|
- */
|
|
|
- if (!(gfp_mask & __GFP_NOMEMALLOC))
|
|
|
- if (test_thread_flag(TIF_MEMDIE) ||
|
|
|
- (current->flags & (PF_MEMALLOC | PF_EXITING)))
|
|
|
- filter &= ~SHOW_MEM_FILTER_NODES;
|
|
|
- if (in_interrupt() || !wait)
|
|
|
- filter &= ~SHOW_MEM_FILTER_NODES;
|
|
|
-
|
|
|
- pr_warning("%s: page allocation failure. order:%d, mode:0x%x\n",
|
|
|
- current->comm, order, gfp_mask);
|
|
|
- dump_stack();
|
|
|
- if (!should_suppress_show_mem())
|
|
|
- show_mem(filter);
|
|
|
- }
|
|
|
+ warn_alloc_failed(gfp_mask, order, NULL);
|
|
|
return page;
|
|
|
got_pg:
|
|
|
if (kmemcheck_enabled)
|