On Fri, 2009-05-08 at 10:29 -0400, Christoph Lameter wrote:On Fri, 8 May 2009, Pekka Enberg wrote:
On Fri, 8 May 2009, Pekka Enberg wrote:Better make sure that GFP_PANIC is only used during early boot then.On Fri, 2009-05-08 at 10:20 -0400, Christoph Lameter wrote:+#define GFP_PANIC (__GFP_NOFAIL | __GFP_NORETRY | __GFP_NOMEMALLOC)So this means not retrying the allocation a couple of times? Not delvingIf you do GFP_KERNEL|GFP_PANIC, we will cond_resched() and retry if we
into reserve pools? Such behavior is good for a allocation that causes a
panic if it fails?
made some progress. So yes, I think the behavior is good for early-boot
call-sites that can't really fail anyway.
If memory is low on boot (due to node hotplug or some such thing, powerpc
may do evil tricks here) then the panic may trigger after the patch.
We would have just delved into the reserves a bit before.
Nah, it's probably better to drop __GFP_NOMEMALLOC instead. Does this
look better?
Pekka
From c91c70265545f2fcc727b4a0d37162b5aa0f5ecf Mon Sep 17 00:00:00 2001From: Cyrill Gorcunov <gorcunov@xxxxxxxxxx>
Date: Fri, 8 May 2009 15:44:50 +0300
Subject: [PATCH] mm: Introduce GFP_PANIC for non-failing allocations
This patch introduces a GFP_PANIC flag that can be used as an annotation
that a call to kmalloc() or alloc_pages() is expected to never fail.
This is useful in early boot code, for example.
To save one GFP flag bit, use a combination of __GFP_NOFAIL,
__GFP_NOREPEAT, and __GFP_NOMEMALLOC to make sure we always end up in
the "nopage" path of the page allocator if an allocation fails.
Signed-off-by: Cyrill Gorcunov <gorcunov@xxxxxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxxxxxx>
---
include/linux/gfp.h | 1 +
mm/page_alloc.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 0bbc15f..b34e6e5 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -70,6 +70,7 @@ struct vm_area_struct;
#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \
__GFP_HARDWALL | __GFP_HIGHMEM | \
__GFP_MOVABLE)
+#define GFP_PANIC (__GFP_NOFAIL | __GFP_NORETRY)
#ifdef CONFIG_NUMA
#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e2f2699..de7f666 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1556,7 +1556,8 @@ nofail_alloc:
zonelist, high_zoneidx, ALLOC_NO_WATERMARKS);
if (page)
goto got_pg;
- if (gfp_mask & __GFP_NOFAIL) {
+ /* GFP_PANIC sets both flags */
+ if ((gfp_mask & __GFP_NOFAIL) && !(gfp_mask & __GFP_NORETRY)) {
congestion_wait(WRITE, HZ/50);
@@ -1670,6 +1671,9 @@ nopage:
dump_stack();
show_mem();
}
+ if (unlikely(gfp_mask & GFP_PANIC))
+ panic("Out of memory: %s order: %d, gfp_mask:0x%x\n",
+ p->comm, order, gfp_mask);