diff options
Diffstat (limited to 'sys')
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); + } } /* |