Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Tweak x86 page freelists and add x86_select_freelist.



details:   https://anonhg.NetBSD.org/src/rev/94acc33352cd
branches:  trunk
changeset: 329872:94acc33352cd
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Thu Jun 12 19:02:35 2014 +0000

description:
Tweak x86 page freelists and add x86_select_freelist.

- Add 4G freelist to i386 -- there may be higher addresses if PAE.
- Add 64G and 1T freelists to amd64.
- Simplify freelist setup code and condense it into a table.
- Add x86_select_freelist to get a freelist guaranteed to yield
addresses no greater than a prescribed maximum address.

x86_select_freelist takes a uint64_t, not a paddr_t or bus_addr_t, so
that you can pass in, e.g., a 36-bit maximum address without needing
to write conditionals for i386/PAE.

No objections on port-x86:

https://mail-index.netbsd.org/port-i386/2014/05/21/msg003277.html
https://mail-index.netbsd.org/port-amd64/2014/05/21/msg002062.html

diffstat:

 sys/arch/amd64/include/vmparam.h |   10 +-
 sys/arch/i386/include/vmparam.h  |    7 +-
 sys/arch/x86/include/machdep.h   |    5 +-
 sys/arch/x86/x86/x86_machdep.c   |  207 +++++++++++++++-----------------------
 4 files changed, 97 insertions(+), 132 deletions(-)

diffs (truncated from 334 to 300 lines):

diff -r bc03ebe4bb66 -r 94acc33352cd sys/arch/amd64/include/vmparam.h
--- a/sys/arch/amd64/include/vmparam.h  Thu Jun 12 18:49:37 2014 +0000
+++ b/sys/arch/amd64/include/vmparam.h  Thu Jun 12 19:02:35 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmparam.h,v 1.34 2014/01/25 15:16:49 christos Exp $    */
+/*     $NetBSD: vmparam.h,v 1.35 2014/06/12 19:02:35 riastradh Exp $   */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -157,10 +157,12 @@
 #define VM_PHYSSEG_MAX         32      /* 1 "hole" + 31 free lists */
 #define VM_PHYSSEG_STRAT       VM_PSTRAT_BIGFIRST
 
-#define        VM_NFREELIST            3
+#define        VM_NFREELIST            5
 #define        VM_FREELIST_DEFAULT     0
-#define        VM_FREELIST_FIRST4G     1
-#define        VM_FREELIST_FIRST16     2
+#define        VM_FREELIST_FIRST1T     1
+#define        VM_FREELIST_FIRST64G    2
+#define        VM_FREELIST_FIRST4G     3
+#define        VM_FREELIST_FIRST16     4
 
 #else  /*      !__x86_64__     */
 
diff -r bc03ebe4bb66 -r 94acc33352cd sys/arch/i386/include/vmparam.h
--- a/sys/arch/i386/include/vmparam.h   Thu Jun 12 18:49:37 2014 +0000
+++ b/sys/arch/i386/include/vmparam.h   Thu Jun 12 19:02:35 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmparam.h,v 1.79 2014/01/28 17:46:01 christos Exp $    */
+/*     $NetBSD: vmparam.h,v 1.80 2014/06/12 19:02:35 riastradh Exp $   */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -135,8 +135,9 @@
 #define        VM_NFREELIST            1
 #else
 #define        VM_PHYSSEG_MAX          32      /* 1 "hole" + 31 free lists */
-#define        VM_NFREELIST            2
-#define        VM_FREELIST_FIRST16     1
+#define        VM_NFREELIST            3
+#define        VM_FREELIST_FIRST16     2
+#define        VM_FREELIST_FIRST4G     1
 #endif /* XEN */
 #define        VM_FREELIST_DEFAULT     0
 
diff -r bc03ebe4bb66 -r 94acc33352cd sys/arch/x86/include/machdep.h
--- a/sys/arch/x86/include/machdep.h    Thu Jun 12 18:49:37 2014 +0000
+++ b/sys/arch/x86/include/machdep.h    Thu Jun 12 19:02:35 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.6 2013/04/12 16:59:41 christos Exp $ */
+/* $NetBSD: machdep.h,v 1.7 2014/06/12 19:02:35 riastradh Exp $ */
 /*
  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -28,6 +28,8 @@
 #ifndef _X86_MACHDEP_H_
 #define _X86_MACHDEP_H_
 
+#include <sys/kcore.h>
+
 extern phys_ram_seg_t mem_clusters[];
 extern int mem_cluster_cnt;
 
@@ -42,6 +44,7 @@
 int    initx86_parse_memmap(struct btinfo_memmap *, struct extent *);
 int    initx86_fake_memmap(struct extent *);
 int    initx86_load_memmap(paddr_t first_avail);
+int    x86_select_freelist(uint64_t);
 
 void   x86_startup(void);
 void   x86_sysctl_machdep_setup(struct sysctllog **);
diff -r bc03ebe4bb66 -r 94acc33352cd sys/arch/x86/x86/x86_machdep.c
--- a/sys/arch/x86/x86/x86_machdep.c    Thu Jun 12 18:49:37 2014 +0000
+++ b/sys/arch/x86/x86/x86_machdep.c    Thu Jun 12 19:02:35 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: x86_machdep.c,v 1.64 2014/04/01 07:16:18 dsl Exp $     */
+/*     $NetBSD: x86_machdep.c,v 1.65 2014/06/12 19:02:35 riastradh 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.64 2014/04/01 07:16:18 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.65 2014/06/12 19:02:35 riastradh Exp $");
 
 #include "opt_modular.h"
 #include "opt_physmem.h"
@@ -686,44 +686,55 @@
 extern vaddr_t module_start, module_end;
 #endif
 
+static struct {
+       int freelist;
+       uint64_t limit;
+} x86_freelists[VM_NFREELIST] = {
+       { VM_FREELIST_DEFAULT, 0 },
+#ifdef VM_FREELIST_FIRST1T
+       /* 40-bit addresses needed for modern graphics.  */
+       { VM_FREELIST_FIRST1T,  1ULL * 1024 * 1024 * 1024 * 1024 },
+#endif
+#ifdef VM_FREELIST_FIRST64G
+       /* 36-bit addresses needed for oldish graphics.  */
+       { VM_FREELIST_FIRST64G, 64ULL * 1024 * 1024 * 1024 },
+#endif
+#ifdef VM_FREELIST_FIRST4G
+       /* 32-bit addresses needed for PCI 32-bit DMA and old graphics.  */
+       { VM_FREELIST_FIRST4G,  4ULL * 1024 * 1024 * 1024 },
+#endif
+       /* 24-bit addresses needed for ISA DMA and ancient graphics.  */
+       { VM_FREELIST_FIRST16,  16 * 1024 * 1024 },
+};
+
+int
+x86_select_freelist(uint64_t maxaddr)
+{
+       unsigned int i;
+
+       if (avail_end <= maxaddr)
+               return VM_NFREELIST;
+
+       for (i = 0; i < __arraycount(x86_freelists); i++) {
+               if ((x86_freelists[i].limit - 1) <= maxaddr)
+                       return x86_freelists[i].freelist;
+       }
+
+       panic("no freelist for maximum address %"PRIx64, maxaddr);
+}
+
 int
 initx86_load_memmap(paddr_t first_avail)
 {
        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
-        * the default free list.  Otherwise, put the first
-        * 16M of RAM on a lower priority free list (so that
-        * all of the ISA DMA'able memory won't be eaten up
-        * first-off).
-        */
-#define ADDR_16M (16 * 1024 * 1024)
+       int x;
+       unsigned i;
 
-       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) */
+       for (i = 0; i < __arraycount(x86_freelists); i++) {
+               if (avail_end < x86_freelists[i].limit)
+                       x86_freelists[i].freelist = VM_FREELIST_DEFAULT;
+       }
 
        /* Make sure the end of the space used by the kernel is rounded. */
        first_avail = round_page(first_avail);
@@ -776,58 +787,32 @@
 
                /* First hunk */
                if (seg_start != seg_end) {
-                       if (seg_start < ADDR_16M &&
-                           first16q != VM_FREELIST_DEFAULT) {
+                       i = __arraycount(x86_freelists);
+                       while (i--) {
                                uint64_t tmp;
 
-                               if (seg_end > ADDR_16M)
-                                       tmp = ADDR_16M;
-                               else
-                                       tmp = seg_end;
-
-                               if (tmp != seg_start) {
+                               if (x86_freelists[i].limit <= seg_start)
+                                       continue;
+                               if (x86_freelists[i].freelist ==
+                                   VM_FREELIST_DEFAULT)
+                                       continue;
+                               tmp = MIN(x86_freelists[i].limit, seg_end);
+                               if (tmp == seg_start)
+                                       continue;
 #ifdef DEBUG_MEMLOAD
-                                       printf("loading first16q 0x%"PRIx64
-                                           "-0x%"PRIx64
-                                           " (0x%"PRIx64"-0x%"PRIx64")\n",
-                                           seg_start, tmp,
-                                           (uint64_t)atop(seg_start),
-                                           (uint64_t)atop(tmp));
+                               printf("loading freelist %d"
+                                   " 0x%"PRIx64"-0x%"PRIx64
+                                   " (0x%"PRIx64"-0x%"PRIx64")\n",
+                                   x86_freelists[i].freelist, 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), first16q);
-                               }
+                               uvm_page_physload(atop(seg_start), atop(tmp),
+                                   atop(seg_start), atop(tmp),
+                                   x86_freelists[i].freelist);
                                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 default 0x%"PRIx64"-0x%"PRIx64
@@ -844,58 +829,32 @@
 
                /* Second hunk */
                if (seg_start1 != seg_end1) {
-                       if (seg_start1 < ADDR_16M &&
-                           first16q != VM_FREELIST_DEFAULT) {
+                       i = __arraycount(x86_freelists);
+                       while (i--) {
                                uint64_t tmp;
 
-                               if (seg_end1 > ADDR_16M)
-                                       tmp = ADDR_16M;
-                               else
-                                       tmp = seg_end1;
-
-                               if (tmp != seg_start1) {
+                               if (x86_freelists[i].limit <= seg_start1)
+                                       continue;
+                               if (x86_freelists[i].freelist ==
+                                   VM_FREELIST_DEFAULT)
+                                       continue;
+                               tmp = MIN(x86_freelists[i].limit, seg_end1);
+                               if (tmp == seg_start1)
+                                       continue;
 #ifdef DEBUG_MEMLOAD
-                                       printf("loading first16q 0x%"PRIx64
-                                           "-0x%"PRIx64
-                                           " (0x%"PRIx64"-0x%"PRIx64")\n",
-                                           seg_start1, tmp,
-                                           (uint64_t)atop(seg_start1),
-                                           (uint64_t)atop(tmp));
+                               printf("loading freelist %u"
+                                   " 0x%"PRIx64"-0x%"PRIx64
+                                   " (0x%"PRIx64"-0x%"PRIx64")\n",
+                                   x86_freelists[i].freelist, 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), first16q);
-                               }
+                               uvm_page_physload(atop(seg_start1), atop(tmp),
+                                   atop(seg_start1), atop(tmp),



Home | Main Index | Thread Index | Old Index