lkml.org 
[lkml]   [2001]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: %u-order allocation failed
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);
}
\
 
 \ /
  Last update: 2005-03-22 13:04    [W:0.108 / U:1.516 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site