summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2007-05-05 19:50:28 +0000
committeralc <alc@FreeBSD.org>2007-05-05 19:50:28 +0000
commitb34f6f7ab1b2b31d561cfbfbc0b43a23c6d93a3e (patch)
tree7aa0cbd313dfa6ace4e0a35a84679f7d3492a165
parent5326cfc8d7152339e4530123781c6ad0d0a22261 (diff)
downloadFreeBSD-src-b34f6f7ab1b2b31d561cfbfbc0b43a23c6d93a3e.zip
FreeBSD-src-b34f6f7ab1b2b31d561cfbfbc0b43a23c6d93a3e.tar.gz
Define every architecture as either VM_PHYSSEG_DENSE or
VM_PHYSSEG_SPARSE depending on whether the physical address space is densely or sparsely populated with memory. The effect of this definition is to determine which of two implementations of vm_page_array and PHYS_TO_VM_PAGE() is used. The legacy implementation is obtained by defining VM_PHYSSEG_DENSE, and a new implementation that trades off time for space is obtained by defining VM_PHYSSEG_SPARSE. For now, all architectures except for ia64 and sparc64 define VM_PHYSSEG_DENSE. Defining VM_PHYSSEG_SPARSE on ia64 allows the entirety of my Itanium 2's memory to be used. Previously, only the first 1 GB could be used. Defining VM_PHYSSEG_SPARSE on sparc64 allows USIIIi-based systems to boot without crashing. This change is a combination of Nathan Whitehorn's patch and my own work in perforce. Discussed with: kmacy, marius, Nathan Whitehorn PR: 112194
-rw-r--r--sys/amd64/include/vmparam.h5
-rw-r--r--sys/arm/include/vmparam.h5
-rw-r--r--sys/i386/include/vmparam.h5
-rw-r--r--sys/ia64/ia64/machdep.c15
-rw-r--r--sys/ia64/include/vmparam.h5
-rw-r--r--sys/powerpc/include/vmparam.h5
-rw-r--r--sys/sparc64/include/vmparam.h5
-rw-r--r--sys/sun4v/include/vmparam.h5
-rw-r--r--sys/vm/vm_page.c8
-rw-r--r--sys/vm/vm_page.h22
10 files changed, 63 insertions, 17 deletions
diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h
index 47e111c..0fcb874 100644
--- a/sys/amd64/include/vmparam.h
+++ b/sys/amd64/include/vmparam.h
@@ -88,6 +88,11 @@
#define UMA_MD_SMALL_ALLOC
/*
+ * The physical address space is densely populated.
+ */
+#define VM_PHYSSEG_DENSE
+
+/*
* Virtual addresses of things. Derived from the page directory and
* page table indexes from pmap.h for precision.
* Because of the page that is both a PD and PT, it looks a little
diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h
index 19201cb..a22b397 100644
--- a/sys/arm/include/vmparam.h
+++ b/sys/arm/include/vmparam.h
@@ -73,6 +73,11 @@
#define VM_PHYSSEG_NOADD
/*
+ * The physical address space is densely populated.
+ */
+#define VM_PHYSSEG_DENSE
+
+/*
* we support 2 free lists:
*
* - DEFAULT for all systems
diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index 042470e..24765d3 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
@@ -82,6 +82,11 @@
/*
+ * The physical address space is densely populated.
+ */
+#define VM_PHYSSEG_DENSE
+
+/*
* Kernel physical load address.
*/
#ifndef KERNLOAD
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 9fe44a1..61ba826 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -702,21 +702,6 @@ ia64_init(void)
continue;
/*
- * Wimp out for now since we do not DTRT here with
- * pci bus mastering (no bounce buffering, for example).
- */
- if (pfn0 >= ia64_btop(0x100000000UL)) {
- printf("Skipping memory chunk start 0x%lx\n",
- md->md_phys);
- continue;
- }
- if (pfn1 >= ia64_btop(0x100000000UL)) {
- printf("Skipping memory chunk end 0x%lx\n",
- md->md_phys + md->md_pages * 4096);
- continue;
- }
-
- /*
* We have a memory descriptor that describes conventional
* memory that is for general use. We must determine if the
* loader has put the kernel in this region.
diff --git a/sys/ia64/include/vmparam.h b/sys/ia64/include/vmparam.h
index 8beeb2a..94801ef 100644
--- a/sys/ia64/include/vmparam.h
+++ b/sys/ia64/include/vmparam.h
@@ -113,6 +113,11 @@
#define UMA_MD_SMALL_ALLOC
/*
+ * The physical address space is sparsely populated.
+ */
+#define VM_PHYSSEG_SPARSE
+
+/*
* Manipulating region bits of an address.
*/
#define IA64_RR_BASE(n) (((u_int64_t) (n)) << 61)
diff --git a/sys/powerpc/include/vmparam.h b/sys/powerpc/include/vmparam.h
index f3625f0..0789ed0 100644
--- a/sys/powerpc/include/vmparam.h
+++ b/sys/powerpc/include/vmparam.h
@@ -107,6 +107,11 @@ struct pmap_physseg {
#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */
+/*
+ * The physical address space is densely populated.
+ */
+#define VM_PHYSSEG_DENSE
+
#define VM_NFREELIST 1
#define VM_FREELIST_DEFAULT 0
diff --git a/sys/sparc64/include/vmparam.h b/sys/sparc64/include/vmparam.h
index 99a9527..e372593 100644
--- a/sys/sparc64/include/vmparam.h
+++ b/sys/sparc64/include/vmparam.h
@@ -78,6 +78,11 @@
#define MAXSLP 20
/*
+ * The physical address space is sparsely populated.
+ */
+#define VM_PHYSSEG_SPARSE
+
+/*
* Address space layout.
*
* UltraSPARC I and II implement a 44 bit virtual address space. The address
diff --git a/sys/sun4v/include/vmparam.h b/sys/sun4v/include/vmparam.h
index 3b87bea..6d475f6 100644
--- a/sys/sun4v/include/vmparam.h
+++ b/sys/sun4v/include/vmparam.h
@@ -78,6 +78,11 @@
#define MAXSLP 20
/*
+ * The physical address space is densely populated.
+ */
+#define VM_PHYSSEG_DENSE
+
+/*
* Address space layout.
*
* UltraSPARC I and II implement a 44 bit virtual address space. The address
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index e97eca9..d4f8148 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -298,7 +298,15 @@ vm_page_startup(vm_offset_t vaddr)
* page).
*/
first_page = low_water / PAGE_SIZE;
+#ifdef VM_PHYSSEG_SPARSE
+ page_range = 0;
+ for (i = 0; phys_avail[i + 1] != 0; i += 2)
+ page_range += atop(phys_avail[i + 1] - phys_avail[i]);
+#elif defined(VM_PHYSSEG_DENSE)
page_range = high_water / PAGE_SIZE - first_page;
+#else
+#error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined."
+#endif
npages = (total - (page_range * sizeof(struct vm_page)) -
(end - new_end)) / PAGE_SIZE;
end = new_end;
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 1b75f38..0b1803f 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -240,6 +240,9 @@ extern struct pq_coloring page_queue_coloring;
#define ACT_MAX 64
#ifdef _KERNEL
+
+#include <vm/vm_param.h>
+
/*
* Each pageable resident page falls into one of four lists:
*
@@ -275,8 +278,23 @@ extern long first_page; /* first physical page number */
#define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr)
-#define PHYS_TO_VM_PAGE(pa) \
- (&vm_page_array[atop(pa) - first_page ])
+static __inline vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
+
+static __inline vm_page_t
+PHYS_TO_VM_PAGE(vm_paddr_t pa)
+{
+#ifdef VM_PHYSSEG_SPARSE
+ int i, j = 0;
+
+ for (i = 0; phys_avail[i + 1] <= pa || phys_avail[i] > pa; i += 2)
+ j += atop(phys_avail[i + 1] - phys_avail[i]);
+ return (&vm_page_array[j + atop(pa - phys_avail[i])]);
+#elif defined(VM_PHYSSEG_DENSE)
+ return (&vm_page_array[atop(pa) - first_page]);
+#else
+#error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined."
+#endif
+}
extern struct mtx vm_page_queue_mtx;
#define vm_page_lock_queues() mtx_lock(&vm_page_queue_mtx)
OpenPOWER on IntegriCloud