Tentitive (untested) ISA DMA space allocation fix.

Matthew Dillon dillon at apollo.backplane.com
Sat Sep 13 13:36:09 PDT 2003


    Here is a tentitive patch for the ISA DMA space allocation problem.
    I'll be able to test it tonight when I get back from the DevSummit.

						-Matt

Index: vm/vm_page.c
===================================================================
RCS file: /cvs/src/sys/vm/vm_page.c,v
retrieving revision 1.9
diff -u -r1.9 vm_page.c
--- vm/vm_page.c	27 Aug 2003 01:43:08 -0000	1.9
+++ vm/vm_page.c	13 Sep 2003 17:33:26 -0000
@@ -152,11 +152,18 @@
  *
  *	Add a new page to the freelist for use by the system.
  *	Must be called at splhigh().
+ *
+ *	Zero'd pages are taken off the tail of the list, non-zero'd
+ *	pages are taken off the head, so new pages are added to both
+ *	ends in order to ensure that higher addresses are allocated
+ *	first and lower addresses (aka ISA dma space), which are entered
+ *	first, are allocated last.
  */
 vm_page_t
 vm_add_new_page(vm_offset_t pa)
 {
 	vm_page_t m;
+	static int flipflop;
 
 	++vmstats.v_page_count;
 	++vmstats.v_free_count;
@@ -165,7 +172,11 @@
 	m->flags = 0;
 	m->pc = (pa >> PAGE_SHIFT) & PQ_L2_MASK;
 	m->queue = m->pc + PQ_FREE;
-	TAILQ_INSERT_HEAD(&vm_page_queues[m->queue].pl, m, pageq);
+	if (flipflop)
+	    TAILQ_INSERT_TAIL(&vm_page_queues[m->queue].pl, m, pageq);
+	else
+	    TAILQ_INSERT_HEAD(&vm_page_queues[m->queue].pl, m, pageq);
+	flipflop = 1 - flipflop;	/* MP non-critical */
 	vm_page_queues[m->queue].lcnt++;
 	return (m);
 }
@@ -311,15 +322,19 @@
 	 */
 	vmstats.v_page_count = 0;
 	vmstats.v_free_count = 0;
-	for (i = 0; phys_avail[i + 1] && npages > 0; i += 2) {
+
+	for (i = 0; phys_avail[i + 1]; i += 2)
+		;
+	while (npages > 0 && i > 0) {
+		i -= 2;
 		pa = phys_avail[i];
 		if (i == biggestone)
 			last_pa = new_end;
 		else
 			last_pa = phys_avail[i + 1];
-		while (pa < last_pa && npages-- > 0) {
-			vm_add_new_page(pa);
-			pa += PAGE_SIZE;
+		while (last_pa > pa && npages-- > 0) {
+			last_pa -= PAGE_SIZE;
+			vm_add_new_page(last_pa);
 		}
 	}
 	return (mapped);





More information about the Kernel mailing list