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