Messages in this thread Patches in this message | | | Date | Tue, 13 Apr 1999 03:46:35 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | [real fix] Re: [patch] fix for cc1 Out of memory [Re: [TESTCASE] `Out of memory for cc1'] |
| |
On Mon, 12 Apr 1999, Linus Torvalds wrote:
>Think about it. free_pgtables() only gets rid of page directories that >have no mappings, and as such they must be clear. No?
Yes.
>Think something on the order of (written on-the-fly, I won't guarantee >this is correct, but I think you'll get the idea).
Fine I understood the whole point of starting with a PGD gap and then shrinking the size according to prev/next vmas.
But I couldn't find anything wrong in shm (except that everything there is a tricky hack).
So I tried to reproduce the bug without shm and I am been succesfully:
#include <sys/types.h> #include <sys/mman.h>
/* try attaching a single segment to multiple addresses */ #define segsize 0x10000 #define attaches 128 #define base_addr 0x01000000 main () { int i; char* addr; char* result; for (i=0, addr = (char*)base_addr; i<attaches; i++, addr += segsize) { if ((result = mmap(addr, segsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0)) != addr) { printf("not fixed %p\n", result); break; } #if 0 printf("%p %p\n", result, result+segsize); #endif bzero(result, segsize); } for (i=0, addr = (char*)base_addr; i<attaches; i++, addr += segsize) { munmap(addr, segsize); #if 0 printf("%p %p\n", addr, addr+segsize); #endif } exit(result == (char*)(-1)); }
The one above is MikeG testcase converted by me from using shm vma to ANON|FIXED mmap vma.
And now that I understood the point (thanks to you ;) of free_pgtables() I am been able to understand it and to find the bug. Here it is the bug-fix for 2.2.5:
Index: mmap.c =================================================================== RCS file: /var/cvs/linux/mm/mmap.c,v retrieving revision 1.1.2.15 diff -u -r1.1.2.15 mmap.c --- mmap.c 1999/04/09 16:53:46 1.1.2.15 +++ linux/mm/mmap.c 1999/04/13 01:29:08 @@ -565,8 +565,8 @@ if (!prev) goto no_mmaps; if (prev->vm_end > start) { - if (last > prev->vm_end) - last = prev->vm_end; + if (last > prev->vm_start) + last = prev->vm_start; goto no_mmaps; } }
Well, while the above is the standalone-bugfix, I think that if prev is null we just know that mm->mmap will be after our start-end space. The same is true for next, if we have a next it will be after us. So I think this second patch will improve the code:
Index: mm/mmap.c =================================================================== RCS file: /var/cvs/linux/mm/mmap.c,v retrieving revision 1.1.2.15 diff -u -r1.1.2.15 mmap.c --- mmap.c 1999/04/09 16:53:46 1.1.2.15 +++ linux/mm/mmap.c 1999/04/13 01:42:52 @@ -564,26 +564,19 @@ prev = mm->mmap; if (!prev) goto no_mmaps; - if (prev->vm_end > start) { - if (last > prev->vm_end) - last = prev->vm_end; - goto no_mmaps; - } + if (last > prev->vm_start) + last = prev->vm_start; + goto no_mmaps; } - for (;;) { + { struct vm_area_struct *next = prev->vm_next; if (next) { - if (next->vm_start < start) { - prev = next; - continue; - } if (last > next->vm_start) last = next->vm_start; } if (prev->vm_end > first) first = prev->vm_end + PGDIR_SIZE - 1; - break; } no_mmaps: first = first >> PGDIR_SHIFT;
but I have not tested this second patch because it's really late and I need to sleep some hour also this night ;).
Andrea Arcangeli
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |