lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 4 May 2009 12:14:54 +0400 From: Cyrill Gorcunov <gorcunov@...il.com> To: David Rientjes <rientjes@...gle.com> Cc: Pekka Enberg <penberg@...helsinki.fi>, Ingo Molnar <mingo@...e.hu>, Jack Steiner <steiner@....com>, Andrew Morton <akpm@...ux-foundation.org>, "H. Peter Anvin" <hpa@...or.com>, Thomas Gleixner <tglx@...utronix.de>, LKML <linux-kernel@...r.kernel.org>, Christoph Lameter <cl@...ux-foundation.org> Subject: Re: introducing __GFP_PANIC [David Rientjes - Sun, May 03, 2009 at 01:58:49PM -0700] | On Mon, 4 May 2009, Cyrill Gorcunov wrote: | | > @@ -1685,7 +1687,9 @@ nopage: | > dump_stack(); | > show_mem(); | > } | > - return page; | > + if (unlikely(gfp_mask & __GFP_PANIC)) | > + panic("Out of memory: panic due to __GFP_PANIC\n"); | > + return NULL; | > got_pg: | > if (kmemcheck_enabled) | > kmemcheck_pagealloc_alloc(page, order, gfp_mask); | > | | If we really want a __GFP_PANIC flag for this purpose, I'd recommend also | emitting the order and gfpmask in the panic() message since it may not be | immediately obvious from the caller. | Thanks for note, David! Here is an updated version for review. I hope I've covered all cases. Complains are welcome :) -- Cyrill --- mm: introduce __GFP_PANIC Sometime we need that memory obtained via kmalloc should always be granted. If there is no enough memory we just can't go further. For such a case we introduce __GFP_PANIC panic modificator. If memory can't be granted -- we just panic. Note that __GFP_PANIC implicitly turn off failslab facility on such kind calls. Signed-off-by: Cyrill Gorcunov <gorcunov@...nvz.org> --- include/linux/gfp.h | 13 ++++++++++--- include/linux/slab_def.h | 1 + mm/failslab.c | 3 +++ mm/page_alloc.c | 17 +++++++++++++++-- 4 files changed, 29 insertions(+), 5 deletions(-) Index: linux-2.6.git/include/linux/gfp.h ===================================================================== --- linux-2.6.git.orig/include/linux/gfp.h +++ linux-2.6.git/include/linux/gfp.h @@ -7,6 +7,7 @@ #include <linux/topology.h> struct vm_area_struct; +void oom_panic(gfp_t gfp_mask, unsigned int order); /* * GFP bitmasks.. @@ -58,7 +59,9 @@ struct vm_area_struct; #define __GFP_NOTRACK ((__force gfp_t)0) #endif -#define __GFP_BITS_SHIFT 22 /* Room for 22 __GFP_FOO bits */ +#define __GFP_PANIC ((__force gfp_t)0x400000u) /* Panic on page alloction failure */ + +#define __GFP_BITS_SHIFT 23 /* Room for 23 __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ @@ -196,8 +199,10 @@ __alloc_pages_nodemask(gfp_t gfp_mask, u static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order) { - if (unlikely(order >= MAX_ORDER)) + if (unlikely(order >= MAX_ORDER)) { + oom_panic(gfp_mask, order); return NULL; + } /* Unknown node is current node */ if (nid < 0) @@ -212,8 +217,10 @@ extern struct page *alloc_pages_current( static inline struct page * alloc_pages(gfp_t gfp_mask, unsigned int order) { - if (unlikely(order >= MAX_ORDER)) + if (unlikely(order >= MAX_ORDER)) { + oom_panic(gfp_mask, order); return NULL; + } return alloc_pages_current(gfp_mask, order); } Index: linux-2.6.git/include/linux/slab_def.h ===================================================================== --- linux-2.6.git.orig/include/linux/slab_def.h +++ linux-2.6.git/include/linux/slab_def.h @@ -143,6 +143,7 @@ static __always_inline void *kmalloc(siz i++; #include <linux/kmalloc_sizes.h> #undef CACHE + oom_panic(flags, get_order(size)); return NULL; found: #ifdef CONFIG_ZONE_DMA Index: linux-2.6.git/mm/failslab.c ===================================================================== --- linux-2.6.git.orig/mm/failslab.c +++ linux-2.6.git/mm/failslab.c @@ -17,6 +17,9 @@ bool should_failslab(size_t size, gfp_t if (gfpflags & __GFP_NOFAIL) return false; + if (gfpflags & __GFP_PANIC) + return false; + if (failslab.ignore_gfp_wait && (gfpflags & __GFP_WAIT)) return false; Index: linux-2.6.git/mm/page_alloc.c ===================================================================== --- linux-2.6.git.orig/mm/page_alloc.c +++ linux-2.6.git/mm/page_alloc.c @@ -1185,6 +1185,8 @@ static int should_fail_alloc_page(gfp_t return 0; if (gfp_mask & __GFP_NOFAIL) return 0; + if (gfp_mask & __GFP_PANIC) + return 0; if (fail_page_alloc.ignore_gfp_highmem && (gfp_mask & __GFP_HIGHMEM)) return 0; if (fail_page_alloc.ignore_gfp_wait && (gfp_mask & __GFP_WAIT)) @@ -1472,6 +1474,16 @@ try_next_zone: return page; } +void oom_panic(gfp_t gfp_mask, unsigned int order) +{ + if (likely(!(gfp_mask & __GFP_PANIC))) + return; + + panic("Out of memory: panic due to __GFP_PANIC.\n" + "%s order:%d, mode:0x%x\n", current->comm, + order, gfp_mask); +} + /* * This is the 'heart' of the zoned buddy allocator. */ @@ -1506,7 +1518,7 @@ restart: * Happens if we have an empty zonelist as a result of * GFP_THISNODE being used on a memoryless node */ - return NULL; + goto nopage; } page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order, @@ -1685,7 +1697,8 @@ nopage: dump_stack(); show_mem(); } - return page; + oom_panic(gfp_mask, order); + return NULL; got_pg: if (kmemcheck_enabled) kmemcheck_pagealloc_alloc(page, order, gfp_mask); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists