Re: %u-order allocation failed

From: Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz)
Date: Sat Oct 06 2001 - 09:44:43 EST


On Sat, 6 Oct 2001, Rik van Riel wrote:

> On Sat, 6 Oct 2001, Mikulas Patocka wrote:
>
> > Buddy allocator is broken - kill it. Or at least do not misuse it for
> > anything except kernel or driver initialization.
>
> Please send patches to get rid of the buddy allocator while
> still making it possible to allocate contiguous chunks of
> memory.
>
> If you have any idea on how to fix things, this would be a
> good time to let us know.

Here goes the fix. (note that I didn't try to compile it so there may be
bugs, but you see the point).

kmalloc should be fixed too (used badly for example in select.c - and yes
- I have seen real world bugreports for poll randomly failing with
ENOMEM), but it will be hard to audit all drivers that they do not try to
use dma on kmallocated memory.

Mikulas

diff -u -r linux-orig/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- linux-orig/include/asm-i386/processor.h Sat Oct 6 16:21:50 2001
+++ linux/include/asm-i386/processor.h Sat Oct 6 16:31:15 2001
@@ -448,7 +448,7 @@
 #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
 
 #define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL | __GFP_VMALLOC,1))
 #define free_task_struct(p) free_pages((unsigned long) (p), 1)
 #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
 
diff -u -r linux-orig/include/linux/mm.h linux/include/linux/mm.h
--- linux-orig/include/linux/mm.h Sat Oct 6 16:21:59 2001
+++ linux/include/linux/mm.h Sat Oct 6 16:28:12 2001
@@ -550,6 +550,7 @@
 #define __GFP_IO 0x40 /* Can start low memory physical IO? */
 #define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */
 #define __GFP_FS 0x100 /* Can call down to low-level FS? */
+#define __GFP_VMALLOC 0x200 /* Can vmalloc pages if buddy allocator fails */
 
 #define GFP_NOHIGHIO (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
 #define GFP_NOIO (__GFP_HIGH | __GFP_WAIT)
diff -u -r linux-orig/mm/page_alloc.c linux/mm/page_alloc.c
--- linux-orig/mm/page_alloc.c Sat Oct 6 16:21:47 2001
+++ linux/mm/page_alloc.c Sat Oct 6 16:36:28 2001
@@ -18,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/slab.h>
 #include <linux/compiler.h>
+#include <linux/vmalloc.h>
 
 int nr_swap_pages;
 int nr_active_pages;
@@ -421,9 +422,9 @@
         struct page * page;
 
         page = alloc_pages(gfp_mask, order);
- if (!page)
- return 0;
- return (unsigned long) page_address(page);
+ if (page) return (unsigned long) page_address(page);
+ if (gfp_mask & __GFP_VMALLOC) return (unsigned long)__vmalloc(PAGE_SIZE << order, gfp_mask, PAGE_KERNEL);
+ return 0;
 }
 
 unsigned long get_zeroed_page(unsigned int gfp_mask)
@@ -447,6 +448,10 @@
 
 void free_pages(unsigned long addr, unsigned int order)
 {
+ if (addr >= VMALLOC_START && addr < VMALLOC_END) {
+ vfree((void *)addr);
+ return;
+ }
         if (addr != 0)
                 __free_pages(virt_to_page(addr), order);
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 07 2001 - 21:00:41 EST