Module Name:    src
Committed By:   bouyer
Date:           Sun Nov 22 21:41:03 UTC 2009

Modified Files:
        src/sys/arch/amd64/include: vmparam.h
        src/sys/arch/x86/x86: x86_machdep.c

Log Message:
For amd64, introduce a third free list distinct from the default free list
for memory between 16M and 4G. On large memory machine, this avoids
the 32bit-accessible memory being eaten by various kernel early allocation,
causing 32bit bus_dma(9) memory allocation to fail at boot time.
Tested on a system with 48GB RAM; based on netbsd-5 patch proposed on
port-amd64 3 days ago.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/amd64/include/vmparam.h
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/x86/x86/x86_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/include/vmparam.h
diff -u src/sys/arch/amd64/include/vmparam.h:1.21 src/sys/arch/amd64/include/vmparam.h:1.22
--- src/sys/arch/amd64/include/vmparam.h:1.21	Fri Mar  6 20:31:47 2009
+++ src/sys/arch/amd64/include/vmparam.h	Sun Nov 22 21:41:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.21 2009/03/06 20:31:47 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.22 2009/11/22 21:41:03 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -152,9 +152,10 @@
 #define VM_PHYSSEG_STRAT	VM_PSTRAT_BIGFIRST
 #define VM_PHYSSEG_NOADD		/* can't add RAM after vm_mem_init */
 
-#define	VM_NFREELIST		2
+#define	VM_NFREELIST		3
 #define	VM_FREELIST_DEFAULT	0
-#define	VM_FREELIST_FIRST16	1
+#define	VM_FREELIST_FIRST4G	1
+#define	VM_FREELIST_FIRST16	2
 
 #include <x86/pmap_pv.h>
 

Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.36 src/sys/arch/x86/x86/x86_machdep.c:1.37
--- src/sys/arch/x86/x86/x86_machdep.c:1.36	Sat Nov 21 03:11:02 2009
+++ src/sys/arch/x86/x86/x86_machdep.c	Sun Nov 22 21:41:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_machdep.c,v 1.36 2009/11/21 03:11:02 rmind Exp $	*/
+/*	$NetBSD: x86_machdep.c,v 1.37 2009/11/22 21:41:03 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.36 2009/11/21 03:11:02 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.37 2009/11/22 21:41:03 bouyer Exp $");
 
 #include "opt_modular.h"
 
@@ -632,6 +632,9 @@
 	uint64_t seg_start, seg_end;
 	uint64_t seg_start1, seg_end1;
 	int first16q, x;
+#ifdef VM_FREELIST_FIRST4G
+	int first4gq;
+#endif
 
 	/*
 	 * If we have 16M of RAM or less, just put it all on
@@ -640,11 +643,28 @@
 	 * all of the ISA DMA'able memory won't be eaten up
 	 * first-off).
 	 */
-	if (avail_end <= (16 * 1024 * 1024))
+#define ADDR_16M (16 * 1024 * 1024)
+
+	if (avail_end <= ADDR_16M)
 		first16q = VM_FREELIST_DEFAULT;
 	else
 		first16q = VM_FREELIST_FIRST16;
 
+#ifdef VM_FREELIST_FIRST4G
+	/*
+	 * If we have 4G of RAM or less, just put it all on
+	 * the default free list.  Otherwise, put the first
+	 * 4G of RAM on a lower priority free list (so that
+	 * all of the 32bit PCI DMA'able memory won't be eaten up
+	 * first-off).
+	 */
+#define ADDR_4G (4ULL * 1024 * 1024 * 1024)
+	if (avail_end <= ADDR_4G)
+		first4gq = VM_FREELIST_DEFAULT;
+	else
+		first4gq = VM_FREELIST_FIRST4G;
+#endif /* defined(VM_FREELIST_FIRST4G) */
+
 	/* Make sure the end of the space used by the kernel is rounded. */
 	first_avail = round_page(first_avail);
 
@@ -696,18 +716,19 @@
 
 		/* First hunk */
 		if (seg_start != seg_end) {
-			if (seg_start < (16 * 1024 * 1024) &&
+			if (seg_start < ADDR_16M &&
 			    first16q != VM_FREELIST_DEFAULT) {
 				uint64_t tmp;
 
-				if (seg_end > (16 * 1024 * 1024))
-					tmp = (16 * 1024 * 1024);
+				if (seg_end > ADDR_16M)
+					tmp = ADDR_16M;
 				else
 					tmp = seg_end;
 
 				if (tmp != seg_start) {
 #ifdef DEBUG_MEMLOAD
-					printf("loading 0x%"PRIx64"-0x%"PRIx64
+					printf("loading first16q 0x%"PRIx64
+					    "-0x%"PRIx64
 					    " (0x%"PRIx64"-0x%"PRIx64")\n",
 					    seg_start, tmp,
 					    (uint64_t)atop(seg_start),
@@ -720,9 +741,36 @@
 				seg_start = tmp;
 			}
 
+#ifdef VM_FREELIST_FIRST4G
+			if (seg_start < ADDR_4G &&
+			    first4gq != VM_FREELIST_DEFAULT) {
+				uint64_t tmp;
+
+				if (seg_end > ADDR_4G)
+					tmp = ADDR_4G;
+				else
+					tmp = seg_end;
+
+				if (tmp != seg_start) {
+#ifdef DEBUG_MEMLOAD
+					printf("loading first4gq 0x%"PRIx64
+					    "-0x%"PRIx64
+					    " (0x%"PRIx64"-0x%"PRIx64")\n",
+					    seg_start, tmp,
+					    (uint64_t)atop(seg_start),
+					    (uint64_t)atop(tmp));
+#endif
+					uvm_page_physload(atop(seg_start),
+					    atop(tmp), atop(seg_start),
+					    atop(tmp), first4gq);
+				}
+				seg_start = tmp;
+			}
+#endif /* defined(VM_FREELIST_FIRST4G) */
+
 			if (seg_start != seg_end) {
 #ifdef DEBUG_MEMLOAD
-				printf("loading 0x%"PRIx64"-0x%"PRIx64
+				printf("loading default 0x%"PRIx64"-0x%"PRIx64
 				    " (0x%"PRIx64"-0x%"PRIx64")\n",
 				    seg_start, seg_end,
 				    (uint64_t)atop(seg_start),
@@ -736,18 +784,19 @@
 
 		/* Second hunk */
 		if (seg_start1 != seg_end1) {
-			if (seg_start1 < (16 * 1024 * 1024) &&
+			if (seg_start1 < ADDR_16M &&
 			    first16q != VM_FREELIST_DEFAULT) {
 				uint64_t tmp;
 
-				if (seg_end1 > (16 * 1024 * 1024))
-					tmp = (16 * 1024 * 1024);
+				if (seg_end1 > ADDR_16M)
+					tmp = ADDR_16M;
 				else
 					tmp = seg_end1;
 
 				if (tmp != seg_start1) {
 #ifdef DEBUG_MEMLOAD
-					printf("loading 0x%"PRIx64"-0x%"PRIx64
+					printf("loading first16q 0x%"PRIx64
+					    "-0x%"PRIx64
 					    " (0x%"PRIx64"-0x%"PRIx64")\n",
 					    seg_start1, tmp,
 					    (uint64_t)atop(seg_start1),
@@ -760,9 +809,36 @@
 				seg_start1 = tmp;
 			}
 
+#ifdef VM_FREELIST_FIRST4G
+			if (seg_start1 < ADDR_4G &&
+			    first4gq != VM_FREELIST_DEFAULT) {
+				uint64_t tmp;
+
+				if (seg_end1 > ADDR_4G)
+					tmp = ADDR_4G;
+				else
+					tmp = seg_end1;
+
+				if (tmp != seg_start1) {
+#ifdef DEBUG_MEMLOAD
+					printf("loading first4gq 0x%"PRIx64
+					    "-0x%"PRIx64
+					    " (0x%"PRIx64"-0x%"PRIx64")\n",
+					    seg_start1, tmp,
+					    (uint64_t)atop(seg_start1),
+					    (uint64_t)atop(tmp));
+#endif
+					uvm_page_physload(atop(seg_start1),
+					    atop(tmp), atop(seg_start1),
+					    atop(tmp), first4gq);
+				}
+				seg_start1 = tmp;
+			}
+#endif /* defined(VM_FREELIST_FIRST4G) */
+
 			if (seg_start1 != seg_end1) {
 #ifdef DEBUG_MEMLOAD
-				printf("loading 0x%"PRIx64"-0x%"PRIx64
+				printf("loading default 0x%"PRIx64"-0x%"PRIx64
 				    " (0x%"PRIx64"-0x%"PRIx64")\n",
 				    seg_start1, seg_end1,
 				    (uint64_t)atop(seg_start1),

Reply via email to