contigmalloc for low address in SI_SUB_KMEM

qhwt at qhwt at
Tue Sep 9 20:48:34 PDT 2003

On Wed, Sep 03, 2003 at 09:22:47AM -0700, Matthew Dillon wrote:
>     I am almost certain that the problem is that all of the low (ISA DMA)
>     memory is being allocated due to the large slab cluster size.
>     The solution is to try to figure out why that is occuring.  Long ago
>     we 'fixed' FreeBSD by having it allocate higher physical addresses
>     first, leaving lower ones available for contigmalloc during booting.
>     Somehow this feature must have gotten broken.

I'm slowly beginning to understand what's happening there; pmap_init()
tries to allocate about 1.7Mbytes of memory block via kmem_alloc(),
and as kmem_alloc() calls vm_page_grab() with VM_ALLOC_ZERO, lower
addresses are consumed first(because free blocks are queued in descending
order at the bottom of vm_page_startup(), I suppose).

My workaround at the moment is to allocate some amount of memory by
kmem_alloc() in vm_mem_init() before pmap_init(), and mem_free() it

Index: vm_init.c
RCS file: /home/source/dragonfly/cvs/src/sys/vm/vm_init.c,v
retrieving revision 1.4
diff -u -r1.4 vm_init.c
--- vm_init.c	27 Aug 2003 01:43:08 -0000	1.4
+++ vm_init.c	9 Sep 2003 16:41:47 -0000
@@ -95,11 +95,15 @@
  *	The start and end address of physical memory is passed in.
+extern vm_map_t kernel_map;
 static void
 	void *dummy;
+	vm_offset_t m;
+	vm_size_t size = 0x10000;
 	 * Initializes resident memory structures. From here on, all physical
 	 * memory is accounted for, and we use only virtual addresses.
@@ -114,6 +118,8 @@
 	kmem_init(virtual_avail, virtual_end);
+	m = kmem_alloc(kernel_map, size);
 	pmap_init(avail_start, avail_end);
+	kmem_free(kernel_map, m, size);

More information about the Bugs mailing list