Subject: bootstrap page allocation - proposed change
To: None <tech-kern@netbsd.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-kern
Date: 12/01/1999 00:14:27
The problem is quite i386 specific, but it points to a uvm problem.
uvm_page_physget() is used to get memory for vm page structures and
md pmap stuff. It "steals" physical pages from one of the
"vm_physmem[]" banks - the problem is that its search order does not
necesserarily match the port specific notion of how valuable pages
in the individual ranges are.
On i386, the vm_page tables are typically taken from the first 640k
because this is the smallest chunk of physical memory available. With
a large kernel, this might eat up last piece of memory below 16M,
leaving no space for ISA DMA bounce buffers.
The "free_list" attribute of the memory ranges already specifies
a preference, so it could be used to prefer "less valuable" memory
in uvm_page_physget() as well.
any problems with this?
best regards
Matthias
Index: uvm_page.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_page.c,v
retrieving revision 1.27
diff -u -r1.27 uvm_page.c
--- uvm_page.c 1999/11/30 18:34:23 1.27
+++ uvm_page.c 1999/11/30 22:46:29
@@ -457,9 +457,12 @@
* => return false if out of memory.
*/
-boolean_t
-uvm_page_physget(paddrp)
+static boolean_t uvm_page_physget_freelist __P((paddr_t *, int));
+
+static boolean_t
+uvm_page_physget_freelist(paddrp, freelist)
paddr_t *paddrp;
+ int freelist;
{
int lcv, x;
@@ -474,6 +477,9 @@
if (vm_physmem[lcv].pgs)
panic("vm_page_physget: called _after_ bootstrap");
+ if (vm_physmem[lcv].free_list != freelist)
+ continue;
+
/* try from front */
if (vm_physmem[lcv].avail_start == vm_physmem[lcv].start &&
vm_physmem[lcv].avail_start < vm_physmem[lcv].avail_end) {
@@ -543,6 +549,18 @@
}
return (FALSE); /* whoops! */
+}
+
+boolean_t
+uvm_page_physget(paddrp)
+ paddr_t *paddrp;
+{
+ int i;
+
+ for (i = 0; i < VM_NFREELIST; i++)
+ if (uvm_page_physget_freelist(paddrp, i) == TRUE)
+ return (TRUE);
+ return (FALSE);
}
#endif /* PMAP_STEAL_MEMORY */