summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThordur I. Bjornsson <thib@cvs.openbsd.org>2010-06-27 03:03:50 +0000
committerThordur I. Bjornsson <thib@cvs.openbsd.org>2010-06-27 03:03:50 +0000
commit8a46d785199bcae03d0469a55b99e08fe33263fa (patch)
tree9b784b445528b5c78da12077fd065ae9030cf6d7
parentb109c783d06f4af76ff573fa020fbe9d1d855f7b (diff)
uvm constraints. Add two mandatory MD symbols, uvm_md_constraints
which contains the constraints for DMA/memory allocation for each architecture, and dma_constraints which contains the range of addresses that are dma accessable by the system. This is based on ariane@'s physcontig diff, with lots of bugfixes and additions the following additions by my self: Introduce a new function pool_set_constraints() which sets the address range for which we allocate pages for the pool from, this is now used for the mbuf/mbuf cluster pools to keep them dma accessible. The !direct archs no longer stuff pages into the kernel object in uvm_km_getpage_pla but rather do a pmap_extract() in uvm_km_putpages. Tested heavily by my self on i386, amd64 and sparc64. Some tests on alpha and SGI. "commit it" beck, art, oga, deraadt "i like the diff" deraadt
-rw-r--r--sys/arch/alpha/alpha/machdep.c9
-rw-r--r--sys/arch/amd64/amd64/machdep.c12
-rw-r--r--sys/arch/arm/arm/arm32_machdep.c6
-rw-r--r--sys/arch/armish/armish/armish_machdep.c6
-rw-r--r--sys/arch/aviion/aviion/machdep.c5
-rw-r--r--sys/arch/beagle/beagle/beagle_machdep.c6
-rw-r--r--sys/arch/gumstix/gumstix/gumstix_machdep.c5
-rw-r--r--sys/arch/hp300/hp300/machdep.c6
-rw-r--r--sys/arch/hppa/hppa/machdep.c5
-rw-r--r--sys/arch/i386/i386/machdep.c10
-rw-r--r--sys/arch/landisk/landisk/machdep.c5
-rw-r--r--sys/arch/loongson/loongson/machdep.c10
-rw-r--r--sys/arch/luna88k/luna88k/machdep.c5
-rw-r--r--sys/arch/mac68k/mac68k/machdep.c5
-rw-r--r--sys/arch/macppc/macppc/machdep.c6
-rw-r--r--sys/arch/mvme68k/mvme68k/machdep.c6
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c9
-rw-r--r--sys/arch/palm/palm/palm_machdep.c6
-rw-r--r--sys/arch/sgi/sgi/machdep.c7
-rw-r--r--sys/arch/socppc/socppc/machdep.c6
-rw-r--r--sys/arch/sparc/include/vmparam.h5
-rw-r--r--sys/arch/sparc/sparc/machdep.c5
-rw-r--r--sys/arch/sparc64/include/vmparam.h5
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c5
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_machdep.c6
-rw-r--r--sys/kern/subr_pool.c43
-rw-r--r--sys/kern/uipc_mbuf.c9
-rw-r--r--sys/sys/pool.h9
-rw-r--r--sys/uvm/uvm.h43
-rw-r--r--sys/uvm/uvm_extern.h18
-rw-r--r--sys/uvm/uvm_km.c305
-rw-r--r--sys/uvm/uvm_page.c43
-rw-r--r--sys/uvm/uvm_page.h4
-rw-r--r--sys/uvm/uvm_pglist.c3
-rw-r--r--sys/uvm/uvm_pmemrange.c61
35 files changed, 461 insertions, 238 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index 0f43e75e31f..ed2a1f98fd3 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.123 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.124 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -143,6 +143,13 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range isa_constraint = { 0x0, 0x00ffffffUL };
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = {
+ &isa_constraint,
+ NULL
+};
+
struct vm_map *exec_map = NULL;
struct vm_map *phys_map = NULL;
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index bbdf79e4ded..68bb5bc526b 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.111 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.112 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -94,6 +94,7 @@
#include <dev/cons.h>
#include <stand/boot/bootarg.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <uvm/uvm_page.h>
#include <uvm/uvm_swap.h>
@@ -207,6 +208,15 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+/* UVM constraint ranges. */
+struct uvm_constraint_range isa_constraint = { 0x0, 0x00ffffffUL };
+struct uvm_constraint_range dma_constraint = { 0x0, 0xffffffffUL };
+struct uvm_constraint_range *uvm_md_constraints[] = {
+ &isa_constraint,
+ &dma_constraint,
+ NULL,
+};
+
#ifdef DEBUG
int sigdebug = 0;
pid_t sigpid = 0;
diff --git a/sys/arch/arm/arm/arm32_machdep.c b/sys/arch/arm/arm/arm32_machdep.c
index b90be48c651..d3e6e5b96e3 100644
--- a/sys/arch/arm/arm/arm32_machdep.c
+++ b/sys/arch/arm/arm/arm32_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arm32_machdep.c,v 1.33 2010/06/09 15:44:17 miod Exp $ */
+/* $OpenBSD: arm32_machdep.c,v 1.34 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: arm32_machdep.c,v 1.42 2003/12/30 12:33:15 pk Exp $ */
/*
@@ -54,6 +54,7 @@
#include <sys/msg.h>
#include <sys/msgbuf.h>
#include <sys/device.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <sys/sysctl.h>
@@ -86,6 +87,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
int cold = 1;
pv_addr_t kernelstack;
diff --git a/sys/arch/armish/armish/armish_machdep.c b/sys/arch/armish/armish/armish_machdep.c
index cc818b5b826..399cd56e14f 100644
--- a/sys/arch/armish/armish/armish_machdep.c
+++ b/sys/arch/armish/armish/armish_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: armish_machdep.c,v 1.14 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: armish_machdep.c,v 1.15 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
@@ -91,6 +91,7 @@
#include <sys/termios.h>
#include <sys/kcore.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
@@ -175,6 +176,9 @@ pv_addr_t minidataclean;
paddr_t msgbufphys;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
diff --git a/sys/arch/aviion/aviion/machdep.c b/sys/arch/aviion/aviion/machdep.c
index 4d58c533bb5..9c01103039a 100644
--- a/sys/arch/aviion/aviion/machdep.c
+++ b/sys/arch/aviion/aviion/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.37 2010/04/24 18:46:51 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.38 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 2007 Miodrag Vallat.
*
@@ -148,6 +148,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* Info for CTL_HW
*/
diff --git a/sys/arch/beagle/beagle/beagle_machdep.c b/sys/arch/beagle/beagle/beagle_machdep.c
index cdf623921c9..9b2952d8256 100644
--- a/sys/arch/beagle/beagle/beagle_machdep.c
+++ b/sys/arch/beagle/beagle/beagle_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: beagle_machdep.c,v 1.4 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: beagle_machdep.c,v 1.5 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
@@ -122,6 +122,7 @@
#include <sys/reboot.h>
#include <sys/termios.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
@@ -207,6 +208,9 @@ pv_addr_t minidataclean;
vaddr_t msgbufphys;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
diff --git a/sys/arch/gumstix/gumstix/gumstix_machdep.c b/sys/arch/gumstix/gumstix/gumstix_machdep.c
index a3e278b83df..43edb526dcb 100644
--- a/sys/arch/gumstix/gumstix/gumstix_machdep.c
+++ b/sys/arch/gumstix/gumstix/gumstix_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gumstix_machdep.c,v 1.2 2009/07/26 18:48:55 miod Exp $ */
+/* $OpenBSD: gumstix_machdep.c,v 1.3 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
@@ -239,6 +239,9 @@ pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
extern struct user *proc0paddr;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/* Prototypes */
#define BOOT_STRING_MAGIC 0x4f425344
diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c
index 9e7f020213f..bec60a33c4d 100644
--- a/sys/arch/hp300/hp300/machdep.c
+++ b/sys/arch/hp300/hp300/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.126 2009/08/11 19:17:16 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.127 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.121 1999/03/26 23:41:29 mycroft Exp $ */
/*
@@ -114,6 +114,10 @@ int bufpages = 0;
int bufcachepercent = BUFCACHEPERCENT;
int physmem; /* size of physical memory, in pages */
+
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* safepri is a safe priority for sleep to set for a spin-wait
* during autoconfiguration or after a panic.
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c
index c2a74de56ea..2cc6fe47640 100644
--- a/sys/arch/hppa/hppa/machdep.c
+++ b/sys/arch/hppa/hppa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.188 2010/06/27 00:04:44 jsing Exp $ */
+/* $OpenBSD: machdep.c,v 1.189 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
@@ -202,6 +202,9 @@ pid_t sigpid = 0;
#define SDB_FOLLOW 0x01
#endif
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* Whatever CPU types we support
*/
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 2bf83682dc7..aa57e7c8821 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.473 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.474 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -195,6 +195,14 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range isa_constraint = { 0x0, 0x00ffffffUL };
+struct uvm_constraint_range dma_constraint = { 0x0, 0xffffffffUL };
+struct uvm_constraint_range *uvm_md_constraints[] = {
+ &isa_constraint,
+ &dma_constraint,
+ NULL
+};
+
extern int boothowto;
int physmem;
diff --git a/sys/arch/landisk/landisk/machdep.c b/sys/arch/landisk/landisk/machdep.c
index fb083fc9b62..23f01445da0 100644
--- a/sys/arch/landisk/landisk/machdep.c
+++ b/sys/arch/landisk/landisk/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.21 2010/06/26 23:24:43 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.22 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
/*-
@@ -115,6 +115,9 @@ int led_blink;
extern u_int32_t getramsize(void);
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* safepri is a safe priority for sleep to set for a spin-wait
* during autoconfiguration or after a panic.
diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c
index 95f32216b09..9bb545d41f5 100644
--- a/sys/arch/loongson/loongson/machdep.c
+++ b/sys/arch/loongson/loongson/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.20 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.21 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -94,6 +94,14 @@ char pmon_bootp[80];
int bufpages = BUFPAGES;
int bufcachepercent = BUFCACHEPERCENT;
+/*
+ * Even though the system is 64bit, the hardware is constrained to up
+ * to 2G of contigous physical memory (direct 2GB DMA area), so there
+ * is no particular constraint. paddr_t is long so:
+ */
+struct uvm_constraint_range dma_constraint = { 0x0, 0xffffffffUL };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
vm_map_t exec_map;
vm_map_t phys_map;
diff --git a/sys/arch/luna88k/luna88k/machdep.c b/sys/arch/luna88k/luna88k/machdep.c
index 20425fae49f..3e37e07e8a0 100644
--- a/sys/arch/luna88k/luna88k/machdep.c
+++ b/sys/arch/luna88k/luna88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.70 2010/06/09 15:44:17 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.71 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -197,6 +197,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* Info for CTL_HW
*/
diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c
index 384485b82aa..22622ab2289 100644
--- a/sys/arch/mac68k/mac68k/machdep.c
+++ b/sys/arch/mac68k/mac68k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.153 2009/08/11 19:17:16 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.154 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.207 1998/07/08 04:39:34 thorpej Exp $ */
/*
@@ -184,6 +184,9 @@ int bufcachepercent = BUFCACHEPERCENT;
int physmem; /* size of physical memory, in pages */
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* safepri is a safe priority for sleep to set for a spin-wait
* during autoconfiguration or after a panic.
diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c
index ec714434d25..44cd0be02a6 100644
--- a/sys/arch/macppc/macppc/machdep.c
+++ b/sys/arch/macppc/macppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.117 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.118 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -52,6 +52,7 @@
#include <sys/core.h>
#include <sys/kcore.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <dev/cons.h>
@@ -106,6 +107,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
struct bat battable[16];
struct vm_map *exec_map = NULL;
diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c
index c61381d1a69..eb245c57da6 100644
--- a/sys/arch/mvme68k/mvme68k/machdep.c
+++ b/sys/arch/mvme68k/mvme68k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.120 2009/08/11 19:17:16 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.121 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -141,6 +141,10 @@ int bufpages = 0;
int bufcachepercent = BUFCACHEPERCENT;
int physmem; /* size of physical memory, in pages */
+
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
/*
* safepri is a safe priority for sleep to set for a spin-wait
* during autoconfiguration or after a panic.
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index 9ae417ec3e5..90b9bb0aee4 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.235 2009/08/11 19:17:16 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.236 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -162,6 +162,13 @@ int bufpages = 0;
int bufcachepercent = BUFCACHEPERCENT;
/*
+ * 32 or 34 bit physical address bus depending upon the CPU flavor.
+ * 32 bit DMA. "I am not aware of any system where the upper 2 bits
+ * have ever been used" - miod@
+struct uvm_constraint_range dma_constraint = { 0x0, 0xffffffffUL};
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
+/*
* Info for CTL_HW
*/
char machine[] = MACHINE; /* cpu "architecture" */
diff --git a/sys/arch/palm/palm/palm_machdep.c b/sys/arch/palm/palm/palm_machdep.c
index 2fb6cc3e176..5b3700a44a3 100644
--- a/sys/arch/palm/palm/palm_machdep.c
+++ b/sys/arch/palm/palm/palm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: palm_machdep.c,v 1.3 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: palm_machdep.c,v 1.4 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
@@ -123,6 +123,7 @@
#include <sys/termios.h>
#include <sys/kcore.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
@@ -213,6 +214,9 @@ pv_addr_t minidataclean;
paddr_t msgbufphys;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index 5510a7b6d3c..14742f0e9c4 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.103 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.104 2010/06/27 03:03:48 thib Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -47,6 +47,7 @@
#include <sys/sem.h>
#endif
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <machine/db_machdep.h>
@@ -95,6 +96,10 @@ char cpu_model[30];
int bufpages = BUFPAGES;
int bufcachepercent = BUFCACHEPERCENT;
+/* low 32 bits range. */
+struct uvm_constraint_range dma_constraint = { 0x0, 0x7fffffff };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
vm_map_t exec_map;
vm_map_t phys_map;
diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c
index c1bdc1d4b61..9e0aec76061 100644
--- a/sys/arch/socppc/socppc/machdep.c
+++ b/sys/arch/socppc/socppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.24 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.25 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -48,6 +48,7 @@
#include <sys/tty.h>
#include <sys/user.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <machine/bat.h>
@@ -85,6 +86,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
struct bat battable[16];
struct vm_map *exec_map = NULL;
diff --git a/sys/arch/sparc/include/vmparam.h b/sys/arch/sparc/include/vmparam.h
index a7ba9e169b3..53a6ba9c401 100644
--- a/sys/arch/sparc/include/vmparam.h
+++ b/sys/arch/sparc/include/vmparam.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmparam.h,v 1.34 2010/04/22 19:02:47 oga Exp $ */
+/* $OpenBSD: vmparam.h,v 1.35 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: vmparam.h,v 1.13 1997/07/12 16:20:03 perry Exp $ */
/*
@@ -130,9 +130,6 @@ struct vm_page_md {
#define VM_NFREELIST 1
#define VM_FREELIST_DEFAULT 0
-/* No UVM_IO_RANGES required: IOMMU takes care of this. */
-#define UVM_IO_RANGES {}
-
#if defined (_KERNEL) && !defined(_LOCORE)
struct vm_map;
#define dvma_mapin(map,va,len,canwait) dvma_mapin_space(map,va,len,canwait,0)
diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c
index 3ee479bbd41..d1543fe59e8 100644
--- a/sys/arch/sparc/sparc/machdep.c
+++ b/sys/arch/sparc/sparc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.124 2009/08/29 15:27:33 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.125 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */
/*
@@ -119,6 +119,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
int physmem;
/* sysctl settable */
diff --git a/sys/arch/sparc64/include/vmparam.h b/sys/arch/sparc64/include/vmparam.h
index b3eca0ba6a4..3d9e6d8fad8 100644
--- a/sys/arch/sparc64/include/vmparam.h
+++ b/sys/arch/sparc64/include/vmparam.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmparam.h,v 1.19 2010/04/22 19:02:49 oga Exp $ */
+/* $OpenBSD: vmparam.h,v 1.20 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: vmparam.h,v 1.18 2001/05/01 02:19:19 thorpej Exp $ */
/*
@@ -145,9 +145,6 @@
#define VM_NFREELIST 1
#define VM_FREELIST_DEFAULT 0
-/* No UVM_IO_RANGES required: IOMMU takes care of this. */
-#define UVM_IO_RANGES {}
-
#define __HAVE_VM_PAGE_MD
/*
* For each struct vm_page, there is a list of all currently valid virtual
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index 4e60b5d04de..0a0d305b8d8 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.123 2010/03/29 19:21:58 oga Exp $ */
+/* $OpenBSD: machdep.c,v 1.124 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */
/*-
@@ -175,6 +175,9 @@ int bufpages = 0;
#endif
int bufcachepercent = BUFCACHEPERCENT;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
int physmem;
extern caddr_t msgbufaddr;
diff --git a/sys/arch/zaurus/zaurus/zaurus_machdep.c b/sys/arch/zaurus/zaurus/zaurus_machdep.c
index 09ac248fece..622079282c0 100644
--- a/sys/arch/zaurus/zaurus/zaurus_machdep.c
+++ b/sys/arch/zaurus/zaurus/zaurus_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_machdep.c,v 1.33 2010/06/10 17:54:13 deraadt Exp $ */
+/* $OpenBSD: zaurus_machdep.c,v 1.34 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
@@ -123,6 +123,7 @@
#include <sys/termios.h>
#include <sys/kcore.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
@@ -221,6 +222,9 @@ pv_addr_t minidataclean;
paddr_t msgbufphys;
+struct uvm_constraint_range dma_constraint = { 0x0, (paddr_t)-1 };
+struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
+
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c
index ba56aaf367e..a8c7771c468 100644
--- a/sys/kern/subr_pool.c
+++ b/sys/kern/subr_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_pool.c,v 1.92 2010/06/17 16:11:20 miod Exp $ */
+/* $OpenBSD: subr_pool.c,v 1.93 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */
/*-
@@ -94,6 +94,12 @@ struct pool_item {
((pp)->pr_nitems < (pp)->pr_minitems)
/*
+ * Default constraint range for pools, that cover the whole
+ * address space.
+ */
+struct uvm_constraint_range pool_full_range = { 0x0, (paddr_t)-1 };
+
+/*
* Every pool gets a unique serial number assigned to it. If this counter
* wraps, we're screwed, but we shouldn't create so many pools anyway.
*/
@@ -393,6 +399,10 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags,
pool_setipl(&phpool, IPL_HIGH);
}
+ /* pglistalloc/constraint parameters */
+ pp->pr_crange = &pool_full_range;
+ pp->pr_pa_nsegs = 0;
+
/* Insert this into the list of all pools. */
TAILQ_INSERT_HEAD(&pool_head, pp, pr_poollist);
}
@@ -999,6 +1009,21 @@ done:
}
void
+pool_set_constraints(struct pool *pp, struct uvm_constraint_range *range,
+ int nsegs)
+{
+ /*
+ * Subsequent changes to the constrictions are only
+ * allowed to make them _more_ strict.
+ */
+ KASSERT(pp->pr_crange->ucr_high >= range->ucr_high &&
+ pp->pr_crange->ucr_low <= range->ucr_low);
+
+ pp->pr_crange = range;
+ pp->pr_pa_nsegs = nsegs;
+}
+
+void
pool_set_ctordtor(struct pool *pp, int (*ctor)(void *, void *, int),
void (*dtor)(void *, void *), void *arg)
{
@@ -1452,15 +1477,15 @@ pool_allocator_free(struct pool *pp, void *v)
void *
pool_page_alloc(struct pool *pp, int flags, int *slowdown)
{
- boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE;
+ int kfl = (flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT;
- return (uvm_km_getpage(waitok, slowdown));
+ return (uvm_km_getpage_pla(kfl, slowdown, pp->pr_crange->ucr_low,
+ pp->pr_crange->ucr_high, 0, 0));
}
void
pool_page_free(struct pool *pp, void *v)
{
-
uvm_km_putpage(v);
}
@@ -1472,7 +1497,9 @@ pool_large_alloc(struct pool *pp, int flags, int *slowdown)
int s;
s = splvm();
- va = uvm_km_kmemalloc(kmem_map, NULL, pp->pr_alloc->pa_pagesz, kfl);
+ va = uvm_km_kmemalloc_pla(kmem_map, NULL, pp->pr_alloc->pa_pagesz, kfl,
+ pp->pr_crange->ucr_low, pp->pr_crange->ucr_high,
+ 0, 0, pp->pr_pa_nsegs);
splx(s);
return ((void *)va);
@@ -1493,8 +1520,10 @@ pool_large_alloc_ni(struct pool *pp, int flags, int *slowdown)
{
int kfl = (flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT;
- return ((void *)uvm_km_kmemalloc(kernel_map, uvm.kernel_object,
- pp->pr_alloc->pa_pagesz, kfl));
+ return ((void *)uvm_km_kmemalloc_pla(kernel_map, uvm.kernel_object,
+ pp->pr_alloc->pa_pagesz, kfl,
+ pp->pr_crange->ucr_low, pp->pr_crange->ucr_high,
+ 0, 0, pp->pr_pa_nsegs));
}
void
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index a7033c1ddb4..99c1decbb06 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.137 2010/06/07 19:47:25 blambert Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.138 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -90,6 +90,7 @@
#include <machine/cpu.h>
+#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
struct mbstat mbstat; /* mbuf stats */
@@ -137,13 +138,15 @@ mbinit(void)
pool_init(&mbpool, MSIZE, 0, 0, 0, "mbpl", NULL);
pool_setlowat(&mbpool, mblowat);
+ pool_set_constraints(&mbpool, &dma_constraint, 1);
for (i = 0; i < nitems(mclsizes); i++) {
snprintf(mclnames[i], sizeof(mclnames[0]), "mcl%dk",
mclsizes[i] >> 10);
- pool_init(&mclpools[i], mclsizes[i], 0, 0, 0, mclnames[i],
- NULL);
+ pool_init(&mclpools[i], mclsizes[i], 0, 0, 0,
+ mclnames[i], NULL);
pool_setlowat(&mclpools[i], mcllowat);
+ pool_set_constraints(&mclpools[i], &dma_constraint, 1);
}
nmbclust_update();
diff --git a/sys/sys/pool.h b/sys/sys/pool.h
index 94360d43224..e49d075d407 100644
--- a/sys/sys/pool.h
+++ b/sys/sys/pool.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pool.h,v 1.33 2009/08/13 13:49:20 thib Exp $ */
+/* $OpenBSD: pool.h,v 1.34 2010/06/27 03:03:48 thib Exp $ */
/* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */
/*-
@@ -131,6 +131,10 @@ struct pool {
unsigned long pr_npagefree; /* # of pages released */
unsigned int pr_hiwat; /* max # of pages in pool */
unsigned long pr_nidle; /* # of idle pages */
+
+ /* Physical memory configuration. */
+ struct uvm_constraint_range *pr_crange;
+ int pr_pa_nsegs;
};
#ifdef _KERNEL
@@ -144,6 +148,9 @@ void pool_setipl(struct pool *, int);
void pool_setlowat(struct pool *, int);
void pool_sethiwat(struct pool *, int);
int pool_sethardlimit(struct pool *, u_int, const char *, int);
+struct uvm_constraint_range; /* XXX */
+void pool_set_constraints(struct pool *,
+ struct uvm_constraint_range *, int);
void pool_set_ctordtor(struct pool *, int (*)(void *, void *, int),
void(*)(void *, void *), void *);
diff --git a/sys/uvm/uvm.h b/sys/uvm/uvm.h
index 9814120fd39..258a16c8f3c 100644
--- a/sys/uvm/uvm.h
+++ b/sys/uvm/uvm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm.h,v 1.39 2010/06/09 08:26:21 thib Exp $ */
+/* $OpenBSD: uvm.h,v 1.40 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm.h,v 1.24 2000/11/27 08:40:02 chs Exp $ */
/*
@@ -68,33 +68,28 @@
#include <machine/vmparam.h>
/*
- * UVM_IO_RANGES: paddr_t pairs, describing the lowest and highest address
- * that should be reserved. These ranges (which may overlap) will have their
- * use counter increased, causing them to be avoided if an allocation can be
- * satisfied from another range of memory.
+ * uvm_constraint_range's:
+ * MD code is allowed to setup constraint ranges for memory allocators, the
+ * primary use for this is to keep allocation for certain memory consumers
+ * such as mbuf pools withing address ranges that are reachable by devices
+ * that perform DMA.
*
- * UVM_IO_RANGES actually results into a call to uvm_pmr_use_inc() per range
- * at uvm initialization. uvm_pmr_use_inc() can also be called after uvm_init()
- * has completed.
+ * It is also to discourge memory allocations from being satisfied from ranges
+ * such as the ISA memory range, if they can be satisfied with allocation
+ * from other ranges.
*
- * Note: the upper bound is specified in the same way as to uvm_pglistalloc.
- * Ex: a memory range of 16 bit is specified as: { 0, 0xffff }.
- * Default: no special ranges in use.
+ * the MD ranges are defined in arch/ARCH/ARCH/machdep.c
*/
-#ifndef UVM_IO_RANGES
-#define UVM_IO_RANGES \
- { \
- { 0, 0x00ffffffUL }, /* ISA memory */ \
- { 0, 0xffffffffUL }, /* 32-bit PCI memory */ \
- }
-#endif
-
-/* UVM IO ranges are described in an array of struct uvm_io_ranges. */
-struct uvm_io_ranges {
- paddr_t low;
- paddr_t high;
+struct uvm_constraint_range {
+ paddr_t ucr_low;
+ paddr_t ucr_high;
};
+/* Constraint ranges, set by MD code. */
+extern struct uvm_constraint_range isa_constraint;
+extern struct uvm_constraint_range dma_constraint;
+extern struct uvm_constraint_range *uvm_md_constraints[];
+
/*
* uvm structure (vm global state: collected in one structure for ease
* of reference...)
@@ -103,7 +98,7 @@ struct uvm_io_ranges {
struct uvm {
/* vm_page related parameters */
- /* vm_page queues */
+ /* vm_page queues */
struct pglist page_active; /* allocated pages, in use */
struct pglist page_inactive_swp;/* pages inactive (reclaim or free) */
struct pglist page_inactive_obj;/* pages inactive (reclaim or free) */
diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h
index 7941d55963f..e9ea11298e5 100644
--- a/sys/uvm/uvm_extern.h
+++ b/sys/uvm/uvm_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_extern.h,v 1.86 2010/06/09 08:26:21 thib Exp $ */
+/* $OpenBSD: uvm_extern.h,v 1.87 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */
/*
@@ -205,6 +205,7 @@ typedef int vm_prot_t;
#define UVM_KMF_NOWAIT 0x1 /* matches M_NOWAIT */
#define UVM_KMF_VALLOC 0x2 /* allocate VA only */
#define UVM_KMF_CANFAIL 0x4 /* caller handles failure */
+#define UVM_KMF_ZERO 0x08 /* zero pages */
#define UVM_KMF_TRYLOCK UVM_FLAG_TRYLOCK /* try locking only */
/*
@@ -517,8 +518,11 @@ vaddr_t uvm_km_alloc1(vm_map_t, vsize_t, vsize_t, boolean_t);
void uvm_km_free(vm_map_t, vaddr_t, vsize_t);
void uvm_km_free_wakeup(vm_map_t, vaddr_t,
vsize_t);
-vaddr_t uvm_km_kmemalloc(vm_map_t, struct uvm_object *,
- vsize_t, int);
+vaddr_t uvm_km_kmemalloc_pla(struct vm_map *,
+ struct uvm_object *, vsize_t, int, paddr_t,
+ paddr_t, paddr_t, paddr_t, int);
+#define uvm_km_kmemalloc(map, obj, sz, flags) \
+ uvm_km_kmemalloc_pla(map, obj, sz, flags, 0, (paddr_t)-1, 0, 0, 0)
struct vm_map *uvm_km_suballoc(vm_map_t, vaddr_t *,
vaddr_t *, vsize_t, int,
boolean_t, vm_map_t);
@@ -528,7 +532,13 @@ vaddr_t uvm_km_valloc_wait(vm_map_t, vsize_t);
vaddr_t uvm_km_valloc_align(struct vm_map *, vsize_t, vsize_t, int);
vaddr_t uvm_km_valloc_prefer_wait(vm_map_t, vsize_t,
voff_t);
-void *uvm_km_getpage(boolean_t, int *);
+void *uvm_km_getpage_pla(boolean_t, int *, paddr_t, paddr_t,
+ paddr_t, paddr_t);
+/* Wrapper around old function prototype. */
+#define uvm_km_getpage(waitok, slowdown) \
+ uvm_km_getpage_pla(((waitok) ? 0 : UVM_KMF_NOWAIT), (slowdown), \
+ (paddr_t)0, (paddr_t)-1, 0, 0)
+
void uvm_km_putpage(void *);
/* uvm_map.c */
diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c
index e00ee709591..19d22bb269e 100644
--- a/sys/uvm/uvm_km.c
+++ b/sys/uvm/uvm_km.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_km.c,v 1.76 2010/02/12 01:35:14 tedu Exp $ */
+/* $OpenBSD: uvm_km.c,v 1.77 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm_km.c,v 1.42 2001/01/14 02:10:01 thorpej Exp $ */
/*
@@ -326,7 +326,6 @@ uvm_km_pgremove_intrsafe(vaddr_t start, vaddr_t end)
}
}
-
/*
* uvm_km_kmemalloc: lower level kernel memory allocator for malloc()
*
@@ -337,20 +336,29 @@ uvm_km_pgremove_intrsafe(vaddr_t start, vaddr_t end)
* => we return KVA of memory allocated
* => flags: NOWAIT, VALLOC - just allocate VA, TRYLOCK - fail if we can't
* lock the map
+ * => low, high, alignment, boundary, nsegs are the corresponding parameters
+ * to uvm_pglistalloc
+ * => flags: ZERO - correspond to uvm_pglistalloc flags
*/
vaddr_t
-uvm_km_kmemalloc(struct vm_map *map, struct uvm_object *obj, vsize_t size,
- int flags)
+uvm_km_kmemalloc_pla(struct vm_map *map, struct uvm_object *obj, vsize_t size,
+ int flags, paddr_t low, paddr_t high, paddr_t alignment, paddr_t boundary,
+ int nsegs)
{
vaddr_t kva, loopva;
voff_t offset;
struct vm_page *pg;
+ struct pglist pgl;
+ int pla_flags;
UVMHIST_FUNC("uvm_km_kmemalloc"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist," (map=%p, obj=%p, size=0x%lx, flags=%d)",
map, obj, size, flags);
KASSERT(vm_map_pmap(map) == pmap_kernel());
+ /* UVM_KMF_VALLOC => !UVM_KMF_ZERO */
+ KASSERT(!(flags & UVM_KMF_VALLOC) ||
+ !(flags & UVM_KMF_ZERO));
/*
* setup for call
@@ -358,6 +366,8 @@ uvm_km_kmemalloc(struct vm_map *map, struct uvm_object *obj, vsize_t size,
size = round_page(size);
kva = vm_map_min(map); /* hint */
+ if (nsegs == 0)
+ nsegs = atop(size);
/*
* allocate some virtual space
@@ -394,28 +404,31 @@ uvm_km_kmemalloc(struct vm_map *map, struct uvm_object *obj, vsize_t size,
* now allocate and map in the memory... note that we are the only ones
* whom should ever get a handle on this area of VM.
*/
+ TAILQ_INIT(&pgl);
+ pla_flags = 0;
+ if ((flags & UVM_KMF_NOWAIT) ||
+ ((flags & UVM_KMF_CANFAIL) &&
+ uvmexp.swpgonly - uvmexp.swpages <= atop(size)))
+ pla_flags |= UVM_PLA_NOWAIT;
+ else
+ pla_flags |= UVM_PLA_WAITOK;
+ if (flags & UVM_KMF_ZERO)
+ pla_flags |= UVM_PLA_ZERO;
+ if (uvm_pglistalloc(size, low, high, alignment, boundary, &pgl, nsegs,
+ pla_flags) != 0) {
+ /* Failed. */
+ uvm_unmap(map, kva, kva + size);
+ return (0);
+ }
loopva = kva;
while (loopva != kva + size) {
- pg = uvm_pagealloc(obj, offset, NULL, 0);
- if (pg) {
- atomic_clearbits_int(&pg->pg_flags, PG_BUSY);
- UVM_PAGE_OWN(pg, NULL);
- }
-
- if (__predict_false(pg == NULL)) {
- if ((flags & UVM_KMF_NOWAIT) ||
- ((flags & UVM_KMF_CANFAIL) &&
- uvmexp.swpgonly == uvmexp.swpages)) {
- /* free everything! */
- uvm_unmap(map, kva, kva + size);
- return (0);
- } else {
- uvm_wait("km_getwait2"); /* sleep here */
- continue;
- }
- }
-
+ pg = TAILQ_FIRST(&pgl);
+ TAILQ_REMOVE(&pgl, pg, pageq);
+ uvm_pagealloc_pg(pg, obj, offset, NULL);
+ atomic_clearbits_int(&pg->pg_flags, PG_BUSY);
+ UVM_PAGE_OWN(pg, NULL);
+
/*
* map it in: note that we call pmap_enter with the map and
* object unlocked in case we are kmem_map.
@@ -432,6 +445,7 @@ uvm_km_kmemalloc(struct vm_map *map, struct uvm_object *obj, vsize_t size,
loopva += PAGE_SIZE;
offset += PAGE_SIZE;
}
+ KASSERT(TAILQ_EMPTY(&pgl));
pmap_update(pmap_kernel());
UVMHIST_LOG(maphist,"<- done (kva=0x%lx)", kva,0,0,0);
@@ -666,7 +680,7 @@ int uvm_km_pages_free; /* number of pages currently on free list */
* uvm_km_page allocator, __HAVE_PMAP_DIRECT arch
* On architectures with machine memory direct mapped into a portion
* of KVM, we have very little work to do. Just get a physical page,
- * and find and return its VA. We use the poolpage functions for this.
+ * and find and return its VA.
*/
void
uvm_km_page_init(void)
@@ -674,34 +688,6 @@ uvm_km_page_init(void)
/* nothing */
}
-void *
-uvm_km_getpage(boolean_t waitok, int *slowdown)
-{
- struct vm_page *pg;
- vaddr_t va;
-
- *slowdown = 0;
- again:
- pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE);
- if (__predict_false(pg == NULL)) {
- if (waitok) {
- uvm_wait("plpg");
- goto again;
- } else
- return (NULL);
- }
- va = pmap_map_direct(pg);
- if (__predict_false(va == 0))
- uvm_pagefree(pg);
- return ((void *)va);
-}
-
-void
-uvm_km_putpage(void *v)
-{
- uvm_pagefree(pmap_unmap_direct((vaddr_t)v));
-}
-
#else
/*
* uvm_km_page allocator, non __HAVE_PMAP_DIRECT archs
@@ -714,13 +700,24 @@ uvm_km_putpage(void *v)
* not zero filled.
*/
-struct mutex uvm_km_mtx;
-int uvm_km_pages_lowat; /* allocate more when reserve drops below this */
-struct km_page {
- struct km_page *next;
-} *uvm_km_pages_head;
+#define UVM_KM_PAGES_LOWAT_MAX (2048)
+#define UVM_KM_PAGES_HIWAT_MAX (4 * UVM_KM_PAGES_LOWAT_MAX)
+
+struct uvm_km_pages {
+ struct mutex mtx;
+
+ /* Low and high water mark for addresses. */
+ int lowat;
+ int hiwat;
-struct proc *uvm_km_proc;
+ /* Kernel address pool. */
+ int free;
+ vaddr_t page[UVM_KM_PAGES_HIWAT_MAX];
+
+ struct proc *km_proc;
+};
+
+struct uvm_km_pages uvm_km_pages;
void uvm_km_createthread(void *);
void uvm_km_thread(void *);
@@ -734,31 +731,36 @@ void uvm_km_thread(void *);
void
uvm_km_page_init(void)
{
- struct km_page *page;
int lowat_min;
int i;
- mtx_init(&uvm_km_mtx, IPL_VM);
- if (!uvm_km_pages_lowat) {
+ mtx_init(&uvm_km_pages.mtx, IPL_VM);
+ if (!uvm_km_pages.lowat) {
/* based on physmem, calculate a good value here */
- uvm_km_pages_lowat = physmem / 256;
- if (uvm_km_pages_lowat > 2048)
- uvm_km_pages_lowat = 2048;
+ uvm_km_pages.lowat = physmem / 256;
lowat_min = physmem < atop(16 * 1024 * 1024) ? 32 : 128;
- if (uvm_km_pages_lowat < lowat_min)
- uvm_km_pages_lowat = lowat_min;
+ if (uvm_km_pages.lowat < lowat_min)
+ uvm_km_pages.lowat = lowat_min;
}
-
- for (i = 0; i < uvm_km_pages_lowat * 4; i++) {
- page = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE);
- page->next = uvm_km_pages_head;
- uvm_km_pages_head = page;
+ if (uvm_km_pages.lowat > UVM_KM_PAGES_LOWAT_MAX)
+ uvm_km_pages.lowat = UVM_KM_PAGES_LOWAT_MAX;
+ uvm_km_pages.hiwat = 4 * uvm_km_pages.lowat;
+ if (uvm_km_pages.hiwat > UVM_KM_PAGES_HIWAT_MAX)
+ uvm_km_pages.hiwat = UVM_KM_PAGES_HIWAT_MAX;
+
+ for (i = 0; i < uvm_km_pages.hiwat; i++) {
+ uvm_km_pages.page[i] = (vaddr_t)uvm_km_kmemalloc(kernel_map,
+ NULL, PAGE_SIZE, UVM_KMF_NOWAIT|UVM_KMF_VALLOC);
+ if (uvm_km_pages.page[i] == NULL)
+ break;
}
- uvm_km_pages_free = i;
+ uvm_km_pages.free = i;
+ for ( ; i < UVM_KM_PAGES_HIWAT_MAX; i++)
+ uvm_km_pages.page[i] = NULL;
/* tone down if really high */
- if (uvm_km_pages_lowat > 512)
- uvm_km_pages_lowat = 512;
+ if (uvm_km_pages.lowat > 512)
+ uvm_km_pages.lowat = 512;
kthread_create_deferred(uvm_km_createthread, NULL);
}
@@ -766,7 +768,7 @@ uvm_km_page_init(void)
void
uvm_km_createthread(void *arg)
{
- kthread_create(uvm_km_thread, NULL, &uvm_km_proc, "kmthread");
+ kthread_create(uvm_km_thread, NULL, &uvm_km_pages.km_proc, "kmthread");
}
/*
@@ -778,74 +780,123 @@ uvm_km_createthread(void *arg)
void
uvm_km_thread(void *arg)
{
- struct km_page *head, *tail, *page;
- int i, want;
-
- for (i = want = 16; ; ) {
- if (i < want || uvm_km_pages_free >= uvm_km_pages_lowat)
- tsleep(&uvm_km_pages_head, PVM, "kmalloc", 0);
- for (i = 0; i < want; i++) {
- page = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE);
- if (i == 0)
- head = tail = page;
- if (page == NULL)
- break;
- page->next = head;
- head = page;
+ vaddr_t pg[16];
+ int i;
+
+ for (;;) {
+ mtx_enter(&uvm_km_pages.mtx);
+ if (uvm_km_pages.free >= uvm_km_pages.lowat) {
+ msleep(&uvm_km_pages.km_proc, &uvm_km_pages.mtx,
+ PVM, "kmalloc", 0);
+ }
+
+ for (i = 0; i < nitems(pg); i++) {
+ pg[i] = (vaddr_t)uvm_km_kmemalloc(kernel_map, NULL,
+ PAGE_SIZE, UVM_KMF_VALLOC);
}
- if (head != NULL) {
- mtx_enter(&uvm_km_mtx);
- tail->next = uvm_km_pages_head;
- uvm_km_pages_head = head;
- uvm_km_pages_free += i;
- mtx_leave(&uvm_km_mtx);
+
+ mtx_enter(&uvm_km_pages.mtx);
+ for (i = 0; i < nitems(pg); i++) {
+ if (uvm_km_pages.free == nitems(uvm_km_pages.page))
+ break;
+ else
+ uvm_km_pages.page[uvm_km_pages.free++] = pg[i];
}
- if (uvm_km_pages_free)
- wakeup(&uvm_km_pages_free);
+
+ wakeup(&uvm_km_pages.free);
+ mtx_leave(&uvm_km_pages.mtx);
+
+ /* Cleanup left-over pages (if any). */
+ for (; i < nitems(pg); i++)
+ uvm_km_free_wakeup(kernel_map, pg[i], PAGE_SIZE);
}
}
+#endif
-
-/*
- * Allocate one page. We can sleep for more if the caller
- * permits it. Wake up the thread if we've dropped below lowat.
- */
void *
-uvm_km_getpage(boolean_t waitok, int *slowdown)
+uvm_km_getpage_pla(int flags, int *slowdown, paddr_t low, paddr_t high,
+ paddr_t alignment, paddr_t boundary)
{
- struct km_page *page = NULL;
+ struct pglist pgl;
+ int pla_flags;
+ struct vm_page *pg;
+ vaddr_t va;
*slowdown = 0;
- mtx_enter(&uvm_km_mtx);
- for (;;) {
- page = uvm_km_pages_head;
- if (page) {
- uvm_km_pages_head = page->next;
- uvm_km_pages_free--;
- break;
+ pla_flags = (flags & UVM_KMF_NOWAIT) ? UVM_PLA_NOWAIT : UVM_PLA_WAITOK;
+ if (flags & UVM_KMF_ZERO)
+ pla_flags |= UVM_PLA_ZERO;
+ TAILQ_INIT(&pgl);
+ if (uvm_pglistalloc(PAGE_SIZE, low, high, alignment, boundary, &pgl,
+ 1, pla_flags) != 0)
+ return NULL;
+ pg = TAILQ_FIRST(&pgl);
+ KASSERT(pg != NULL && TAILQ_NEXT(pg, pageq) == NULL);
+ TAILQ_REMOVE(&pgl, pg, pageq);
+
+#ifdef __HAVE_PMAP_DIRECT
+ va = pmap_map_direct(pg);
+ if (__predict_false(va == 0))
+ uvm_pagefree(pg);
+
+#else /* !__HAVE_PMAP_DIRECT */
+ mtx_enter(&uvm_km_pages.mtx);
+ while (uvm_km_pages.free == 0) {
+ if (flags & UVM_KMF_NOWAIT) {
+ mtx_leave(&uvm_km_pages.mtx);
+ uvm_pagefree(pg);
+ return NULL;
}
- if (!waitok)
- break;
- msleep(&uvm_km_pages_free, &uvm_km_mtx, PVM, "getpage", 0);
+ msleep(&uvm_km_pages.free, &uvm_km_pages.mtx, PVM, "getpage",
+ 0);
}
- mtx_leave(&uvm_km_mtx);
- if (uvm_km_pages_free < uvm_km_pages_lowat) {
- if (curproc != uvm_km_proc)
- *slowdown = 1;
- wakeup(&uvm_km_pages_head);
+
+ va = uvm_km_pages.page[--uvm_km_pages.free];
+ if (uvm_km_pages.free < uvm_km_pages.lowat &&
+ curproc != uvm_km_pages.km_proc) {
+ *slowdown = 1;
+ wakeup(&uvm_km_pages.km_proc);
}
- return (page);
+ mtx_leave(&uvm_km_pages.mtx);
+
+
+ atomic_setbits_int(&pg->pg_flags, PG_FAKE);
+ UVM_PAGE_OWN(pg, NULL);
+
+ pmap_enter(kernel_map->pmap, va, VM_PAGE_TO_PHYS(pg), UVM_PROT_RW,
+ PMAP_WIRED | VM_PROT_READ | VM_PROT_WRITE);
+ pmap_update(kernel_map->pmap);
+
+#endif /* !__HAVE_PMAP_DIRECT */
+ return ((void *)va);
}
void
uvm_km_putpage(void *v)
{
- struct km_page *page = v;
+ vaddr_t va = (vaddr_t)v;
+ struct vm_page *pg;
+
+#ifdef __HAVE_PMAP_DIRECT
+ pg = pmap_unmap_direct(va);
+#else /* !__HAVE_PMAP_DIRECT */
+ paddr_t pa;
+ if (!pmap_extract(pmap_kernel(), va, &pa))
+ panic("lost pa");
+ pg = PHYS_TO_VM_PAGE(pa);
+
+ KASSERT(pg != NULL);
- mtx_enter(&uvm_km_mtx);
- page->next = uvm_km_pages_head;
- uvm_km_pages_head = page;
- uvm_km_pages_free++;
- mtx_leave(&uvm_km_mtx);
+ pmap_remove(kernel_map->pmap, va, va + PAGE_SIZE);
+ pmap_update(kernel_map->pmap);
+
+ mtx_enter(&uvm_km_pages.mtx);
+ if (uvm_km_pages.free < uvm_km_pages.hiwat)
+ uvm_km_pages.page[uvm_km_pages.free++] = va;
+ else
+ uvm_km_free_wakeup(kernel_map, va, PAGE_SIZE);
+ mtx_leave(&uvm_km_pages.mtx);
+#endif /* !__HAVE_PMAP_DIRECT */
+
+ uvm_pagefree(pg);
}
-#endif
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c
index d40e6a41abb..6a038d8d015 100644
--- a/sys/uvm/uvm_page.c
+++ b/sys/uvm/uvm_page.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_page.c,v 1.100 2010/04/22 19:02:55 oga Exp $ */
+/* $OpenBSD: uvm_page.c,v 1.101 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */
/*
@@ -777,6 +777,33 @@ uvm_shutdown(void)
}
/*
+ * Perform insert of a given page in the specified anon of obj.
+ * This is basically, uvm_pagealloc, but with the page already given.
+ */
+void
+uvm_pagealloc_pg(struct vm_page *pg, struct uvm_object *obj, voff_t off,
+ struct vm_anon *anon)
+{
+ int flags;
+
+ flags = PG_BUSY | PG_FAKE;
+ pg->offset = off;
+ pg->uobject = obj;
+ pg->uanon = anon;
+
+ if (anon) {
+ anon->an_page = pg;
+ flags |= PQ_ANON;
+ } else if (obj)
+ uvm_pageinsert(pg);
+ atomic_setbits_int(&pg->pg_flags, flags);
+#if defined(UVM_PAGE_TRKOWN)
+ pg->owner_tag = NULL;
+#endif
+ UVM_PAGE_OWN(pg, "new alloc");
+}
+
+/*
* uvm_pagealloc_strat: allocate vm_page from a particular free list.
*
* => return null if no pages free
@@ -836,23 +863,11 @@ uvm_pagealloc(struct uvm_object *obj, voff_t off, struct vm_anon *anon,
pg = TAILQ_FIRST(&pgl);
KASSERT(pg != NULL && TAILQ_NEXT(pg, pageq) == NULL);
- pg->offset = off;
- pg->uobject = obj;
- pg->uanon = anon;
+ uvm_pagealloc_pg(pg, obj, off, anon);
KASSERT((pg->pg_flags & PG_DEV) == 0);
atomic_setbits_int(&pg->pg_flags, PG_BUSY|PG_CLEAN|PG_FAKE);
if (flags & UVM_PGA_ZERO)
atomic_clearbits_int(&pg->pg_flags, PG_CLEAN);
- if (anon) {
- anon->an_page = pg;
- atomic_setbits_int(&pg->pg_flags, PQ_ANON);
- } else if (obj)
- uvm_pageinsert(pg);
-
-#if defined(UVM_PAGE_TRKOWN)
- pg->owner_tag = NULL;
-#endif
- UVM_PAGE_OWN(pg, "new alloc");
UVMHIST_LOG(pghist, "allocated pg %p/%lx", pg,
(u_long)VM_PAGE_TO_PHYS(pg), 0, 0);
diff --git a/sys/uvm/uvm_page.h b/sys/uvm/uvm_page.h
index eda9030fe63..c8e2b04fd36 100644
--- a/sys/uvm/uvm_page.h
+++ b/sys/uvm/uvm_page.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_page.h,v 1.42 2010/04/22 19:02:55 oga Exp $ */
+/* $OpenBSD: uvm_page.h,v 1.43 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm_page.h,v 1.19 2000/12/28 08:24:55 chs Exp $ */
/*
@@ -249,6 +249,8 @@ void uvm_pagewait(struct vm_page *, int);
void uvm_pagewake(struct vm_page *);
void uvm_pagewire(struct vm_page *);
void uvm_pagezero(struct vm_page *);
+void uvm_pagealloc_pg(struct vm_page *, struct uvm_object *,
+ voff_t, struct vm_anon *);
int uvm_page_lookup_freelist(struct vm_page *);
diff --git a/sys/uvm/uvm_pglist.c b/sys/uvm/uvm_pglist.c
index 94b68efba13..17fd8751bec 100644
--- a/sys/uvm/uvm_pglist.c
+++ b/sys/uvm/uvm_pglist.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pglist.c,v 1.37 2010/06/10 08:48:36 thib Exp $ */
+/* $OpenBSD: uvm_pglist.c,v 1.38 2010/06/27 03:03:49 thib Exp $ */
/* $NetBSD: uvm_pglist.c,v 1.13 2001/02/18 21:19:08 chs Exp $ */
/*-
@@ -77,7 +77,6 @@ u_long uvm_pglistalloc_npages;
* UVM_PLA_NOWAIT fail if allocation fails
* UVM_PLA_WAITOK wait for memory to become avail
* UVM_PLA_ZERO return zeroed memory
- * UVM_PLA_TRYCONTIG caller (device) prefers p-linear memory
*/
int
diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c
index 54d3f6960d6..d4c6bd87789 100644
--- a/sys/uvm/uvm_pmemrange.c
+++ b/sys/uvm/uvm_pmemrange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmemrange.c,v 1.14 2010/06/23 09:36:03 thib Exp $ */
+/* $OpenBSD: uvm_pmemrange.c,v 1.15 2010/06/27 03:03:49 thib Exp $ */
/*
* Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl>
@@ -109,7 +109,6 @@ void uvm_pmr_assertvalid(struct uvm_pmemrange *pmr);
#define uvm_pmr_assertvalid(pmr) do {} while (0)
#endif
-
int uvm_pmr_get1page(psize_t, int, struct pglist *,
paddr_t, paddr_t);
@@ -1305,7 +1304,26 @@ uvm_pmr_split(paddr_t pageno)
KASSERT(pmr->low < pageno);
KASSERT(pmr->high > pageno);
+ /*
+ * uvm_pmr_allocpmr() calls into malloc() which in turn calls into
+ * uvm_kmemalloc which calls into pmemrange, making the locking
+ * a bit hard, so we just race!
+ */
+ uvm_unlock_fpageq();
drain = uvm_pmr_allocpmr();
+ uvm_lock_fpageq();
+ pmr = uvm_pmemrange_find(pageno);
+ if (pmr == NULL || !(pmr->low < pageno)) {
+ /*
+ * We lost the race since someone else ran this or a related
+ * function, however this should be triggered very rarely so
+ * we just leak the pmr.
+ */
+ printf("uvm_pmr_split: lost one pmr\n");
+ uvm_unlock_fpageq();
+ return;
+ }
+
drain->low = pageno;
drain->high = pmr->high;
drain->use = pmr->use;
@@ -1379,37 +1397,29 @@ void
uvm_pmr_use_inc(paddr_t low, paddr_t high)
{
struct uvm_pmemrange *pmr;
+ paddr_t sz;
- /*
- * If high+1 == 0 and low == 0, then you are increasing use
- * of the whole address space, which won't make any difference.
- * Skip in that case.
- */
+ /* pmr uses page numbers, translate low and high. */
high++;
- if (high == 0 && low == 0)
- return;
-
- /*
- * pmr uses page numbers, translate low and high.
- */
- low = atop(round_page(low));
high = atop(trunc_page(high));
+ low = atop(round_page(low));
uvm_pmr_split(low);
uvm_pmr_split(high);
uvm_lock_fpageq();
-
/* Increase use count on segments in range. */
RB_FOREACH(pmr, uvm_pmemrange_addr, &uvm.pmr_control.addr) {
if (PMR_IS_SUBRANGE_OF(pmr->low, pmr->high, low, high)) {
TAILQ_REMOVE(&uvm.pmr_control.use, pmr, pmr_use);
pmr->use++;
+ sz += pmr->high - pmr->low;
uvm_pmemrange_use_insert(&uvm.pmr_control.use, pmr);
}
uvm_pmr_assertvalid(pmr);
}
-
uvm_unlock_fpageq();
+
+ KASSERT(sz >= high - low);
}
/*
@@ -1420,19 +1430,21 @@ uvm_pmr_use_inc(paddr_t low, paddr_t high)
* (And if called in between, you're dead.)
*/
struct uvm_pmemrange *
-uvm_pmr_allocpmr()
+uvm_pmr_allocpmr(void)
{
struct uvm_pmemrange *nw;
int i;
+ /* We're only ever hitting the !uvm.page_init_done case for now. */
if (!uvm.page_init_done) {
nw = (struct uvm_pmemrange *)
uvm_pageboot_alloc(sizeof(struct uvm_pmemrange));
- bzero(nw, sizeof(struct uvm_pmemrange));
} else {
nw = malloc(sizeof(struct uvm_pmemrange),
- M_VMMAP, M_NOWAIT | M_ZERO);
+ M_VMMAP, M_NOWAIT);
}
+ KASSERT(nw != NULL);
+ bzero(nw, sizeof(struct uvm_pmemrange));
RB_INIT(&nw->addr);
for (i = 0; i < UVM_PMR_MEMTYPE_MAX; i++) {
RB_INIT(&nw->size[i]);
@@ -1441,8 +1453,6 @@ uvm_pmr_allocpmr()
return nw;
}
-static const struct uvm_io_ranges uvm_io_ranges[] = UVM_IO_RANGES;
-
/*
* Initialization of pmr.
* Called by uvm_page_init.
@@ -1458,15 +1468,18 @@ uvm_pmr_init(void)
TAILQ_INIT(&uvm.pmr_control.use);
RB_INIT(&uvm.pmr_control.addr);
+ /* By default, one range for the entire address space. */
new_pmr = uvm_pmr_allocpmr();
new_pmr->low = 0;
- new_pmr->high = atop((paddr_t)-1) + 1;
+ new_pmr->high = atop((paddr_t)-1) + 1;
RB_INSERT(uvm_pmemrange_addr, &uvm.pmr_control.addr, new_pmr);
uvm_pmemrange_use_insert(&uvm.pmr_control.use, new_pmr);
- for (i = 0; i < nitems(uvm_io_ranges); i++)
- uvm_pmr_use_inc(uvm_io_ranges[i].low, uvm_io_ranges[i].high);
+ for (i = 0; uvm_md_constraints[i] != NULL; i++) {
+ uvm_pmr_use_inc(uvm_md_constraints[i]->ucr_low,
+ uvm_md_constraints[i]->ucr_high);
+ }
}
/*