Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch For amd64, introduce a third free list distinct fro...



details:   https://anonhg.NetBSD.org/src/rev/ad17263586e8
branches:  trunk
changeset: 749246:ad17263586e8
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Nov 22 21:41:03 2009 +0000

description:
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.

diffstat:

 sys/arch/amd64/include/vmparam.h |    7 +-
 sys/arch/x86/x86/x86_machdep.c   |  102 ++++++++++++++++++++++++++++++++++----
 2 files changed, 93 insertions(+), 16 deletions(-)

diffs (204 lines):

diff -r e5ad72e23877 -r ad17263586e8 sys/arch/amd64/include/vmparam.h
--- a/sys/arch/amd64/include/vmparam.h  Sun Nov 22 21:18:42 2009 +0000
+++ b/sys/arch/amd64/include/vmparam.h  Sun Nov 22 21:41:03 2009 +0000
@@ -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>
 
diff -r e5ad72e23877 -r ad17263586e8 sys/arch/x86/x86/x86_machdep.c
--- a/sys/arch/x86/x86/x86_machdep.c    Sun Nov 22 21:18:42 2009 +0000
+++ b/sys/arch/x86/x86/x86_machdep.c    Sun Nov 22 21:41:03 2009 +0000
@@ -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),



Home | Main Index | Thread Index | Old Index