Messages in this thread Patch in this message | | | From | (Kip Rugger) | Subject | [PATCH] fork failures on ix86, try 2 | Date | 8 Jul 1998 02:23:07 -0500 |
| |
In article <199807080150.SAA15896@dm.cobaltmicro.com>, David S. Miller <davem@dm.cobaltmicro.com> wrote: > From: rugger@rugger.nodomain.ca (Kip Rugger) > Date: 7 Jul 1998 20:32:58 -0500 > >[ BTW: nice email address, how do you expect people to respond to you? ]
hopefully reads kbr@pangea.ca
> > Recent 2.1 kernels suffer memory fragmentation, eventually requests > >4kB start failing. Among these are the requests made by fork for > an 8kB kernel stack. > > This little hack changes fork to use the vmalloc service, so that > the 8kB fork request can be satisfied with 2 non-contiguous 4kB > pages. > >This patch is broken and will kill performance. > >It would be one thing to, when gfp() fails, use vmalloc() as a backup >plan. Doing it all the time is totally unacceptable.
Agreed.
> >Later, >David S. Miller >davem@dm.cobaltmicro.com > >- >To unsubscribe from this list: send the line "unsubscribe linux-kernel" in >the body of a message to majordomo@vger.rutgers.edu >
===========================================================================
diff -ru /user/linux/linux-2.1.108/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- /user/linux/linux-2.1.108/include/asm-i386/processor.h Tue Jul 7 10:54:58 1998 +++ linux/include/asm-i386/processor.h Wed Jul 8 00:50:23 1998 @@ -217,9 +217,21 @@ /* * NOTE! The task struct and the stack go together */ + #define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) +({ \ + struct task_struct * ts; \ + ts = (struct task_struct *) __get_free_pages(GFP_KERNEL,1); \ + if (!ts) ts = vmalloc(8192); \ + ts; \ +}) + +#define free_task_struct(p) do { \ + if (VMALLOC_VMADDR(p) < VMALLOC_START) \ + free_pages((unsigned long)(p),1); \ + else \ + vfree(p); \ + } while(0) #define init_task (init_task_union.task) #define init_stack (init_task_union.stack) diff -ru /user/linux/linux-2.1.108/kernel/exit.c linux/kernel/exit.c --- /user/linux/linux-2.1.108/kernel/exit.c Fri May 15 15:26:11 1998 +++ linux/kernel/exit.c Tue Jul 7 13:15:03 1998 @@ -23,6 +23,7 @@ #ifdef CONFIG_BSD_PROCESS_ACCT #include <linux/acct.h> #endif +#include <linux/vmalloc.h> #include <asm/uaccess.h> #include <asm/pgtable.h> diff -ru /user/linux/linux-2.1.108/kernel/fork.c linux/kernel/fork.c --- /user/linux/linux-2.1.108/kernel/fork.c Tue Jul 7 10:47:02 1998 +++ linux/kernel/fork.c Tue Jul 7 13:14:40 1998 @@ -23,6 +23,7 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/module.h> +#include <linux/vmalloc.h> #include <asm/system.h> #include <asm/pgtable.h> diff -ru /user/linux/linux-2.1.108/mm/vmalloc.c linux/mm/vmalloc.c --- /user/linux/linux-2.1.108/mm/vmalloc.c Sat Jul 4 21:32:01 1998 +++ linux/mm/vmalloc.c Tue Jul 7 19:50:42 1998 @@ -159,10 +159,13 @@ if (!area) return NULL; addr = (void *) VMALLOC_START; + if ((unsigned long)addr & PAGE_SIZE) addr += PAGE_SIZE; for (p = &vmlist; (tmp = *p) ; p = &tmp->next) { if (size + (unsigned long) addr < (unsigned long) tmp->addr) break; addr = (void *) (tmp->size + (unsigned long) tmp->addr); + /* ugly hack to allocate kernel stacks on 8k boundaries */ + if ((unsigned long)addr & PAGE_SIZE) addr += PAGE_SIZE; } area->addr = addr; area->size = size + PAGE_SIZE; ======= end of patch - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |