As suggested in the thread "Subtle MM bug (really 830MB barrier
question)", it would be beneficial on 32-bit hardware for mmap()
allocations without MAP_FIXED to grow downward from TASK_SIZE, rather than
upwards from TASK_UNMAPPED_BASE.  This would allow both brk()-using and
mmap()-using programs to access almost 3GB (TASK_SIZE - some overhead).

So here is my first ever attempt at a kernel patch.  It compiles and boots
and seems to work OK.  Any comments would be very welcome, but please
excuse my ignorance of many things. :-)

A few comments:

(1) I have no idea how much room to allow for the stack on i386, so I
arbitrarily picked 128MB.

(2) I also have no idea what happens on architectures other than i386, so
I defined TASK_UNMAPPED_CEILING in include/asm-i386/processor.h.  Then in
mm/mmap.c, if TASK_UNMAPPED_CEILING is undefined, get_unmapped_area()
behaves as before.  I used #ifdef to do this, is that an OK style?

(3) The (original) search upwards version of get_unmapped_area() only
calls find_vma() once, and then it uses ->vm_next in the main loop to get
the next vm_area_struct.  My search downwards version calls find_vma()
once every loop, as there is no ->vm_previous member in vm_area_struct.
Is the overhead of calling find_vma() every loop a problem, and if so, is
there a better solution than modifying vm_area_struct to make it a doubly
linked list?

(4) Lastly, there is the question of when get_unmapped_area() should just
fail.  I notice that executables on i386 are loaded at 128MB, so I defined
TASK_UNMAPPED_FLOOR to be 128MB and I stop there.  Is this the right place
to stop, and if so is there some other #define I should be referencing
instead of adding one?

Cheers,
Wayne


diff -ru linux-2.4.0-pre3/include/asm-i386/processor.h 
linux-2.4.0-pre3-hack/include/asm-i386/processor.h
--- linux-2.4.0-pre3/include/asm-i386/processor.h       Thu Jan 11 12:56:05 2001
+++ linux-2.4.0-pre3-hack/include/asm-i386/processor.h  Fri Jan 12 13:51:16 2001
@@ -260,10 +260,22 @@
  */
 #define TASK_SIZE      (PAGE_OFFSET)

-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
+/*
+ * When looking for a free chunk of vm space during mmap's, the kernel
+ * will search upwards from TASK_UNMAPPED_BASE (the usual algorithm),
+ * unless TASK_UNMAPPED_CEILING is defined, in which case it will
+ * search downwards from TASK_UNMAPPED_CEILING to TASK_UNMAPPED_FLOOR.
  */
 #define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
+/*
+ * We need to allow room for the stack to grow downard from TASK_SIZE,
+ * I really have no idea how large it can get, so I arbitrarily picked
+ * 128MB.  Also, I'm not so sure where to stop searching and give up,
+ * so I pick 128MB, which seems to be where exectuables get loaded.
+ */
+#define TASK_UNMAPPED_CEILING   (TASK_SIZE - 128 * 1024 * 1024)
+#define TASK_UNMAPPED_FLOOR     (128 * 1024 * 1024)

 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
diff -ru linux-2.4.0-pre3/mm/mmap.c linux-2.4.0-pre3-hack/mm/mmap.c
--- linux-2.4.0-pre3/mm/mmap.c  Sat Dec 30 12:35:19 2000
+++ linux-2.4.0-pre3-hack/mm/mmap.c     Fri Jan 12 13:54:02 2001
@@ -382,6 +382,22 @@

        if (len > TASK_SIZE)
                return 0;
+#ifdef TASK_UNMAPPED_CEILING
+       if (!addr)
+               addr = TASK_UNMAPPED_CEILING - len;
+
+       do {
+               /* align addr downards; PAGE_ALIGN aligns it upwards */
+               addr = addr&PAGE_MASK;
+               vmm = find_vma(current->mm,addr);
+               /* At this point:  (!vmm || addr < vmm->vm_end). */
+               if (!vmm || addr + len <= vmm->vm_start)
+                       return addr;
+               addr = vmm->vm_start - len;
+       } while (addr >= TASK_UNMAPPED_FLOOR);
+
+       return 0;
+#else
        if (!addr)
                addr = TASK_UNMAPPED_BASE;
        addr = PAGE_ALIGN(addr);
@@ -394,6 +410,7 @@
                        return addr;
                addr = vmm->vm_end;
        }
+#endif
 }
 #endif


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to