diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 474ea4bd856d..bda972213c86 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -178,23 +178,16 @@ #define PHYS_TO_DMAP(x) ((x) | DMAP_MIN_ADDRESS) #define DMAP_TO_PHYS(x) ((x) & ~DMAP_MIN_ADDRESS) -/* virtual sizes (bytes) for various kernel submaps */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12 * 1024 * 1024) -#endif - /* - * How many physical pages per KVA page allocated. - * min(max(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), - * VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE #define VM_KMEM_SIZE_SCALE (1) #endif /* - * Ceiling on amount of kmem_map kva space. + * Optional ceiling (in bytes) on the size of the kmem arena: 60% of the + * kernel map. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX ((VM_MAX_KERNEL_ADDRESS - \ diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h index 8fa6988472f5..a93a92680a33 100644 --- a/sys/arm/include/vmparam.h +++ b/sys/arm/include/vmparam.h @@ -165,17 +165,22 @@ #define VM_MAX_KERNEL_ADDRESS (vm_max_kernel_address) /* - * Virtual size (bytes) for various kernel submaps. + * How many physical pages per kmem arena virtual page. */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12*1024*1024) -#endif #ifndef VM_KMEM_SIZE_SCALE -#define VM_KMEM_SIZE_SCALE (3) +#define VM_KMEM_SIZE_SCALE (3) #endif /* - * Ceiling on the size of the kmem submap: 40% of the kernel map. + * Optional floor (in bytes) on the size of the kmem arena. + */ +#ifndef VM_KMEM_SIZE_MIN +#define VM_KMEM_SIZE_MIN (12 * 1024 * 1024) +#endif + +/* + * Optional ceiling (in bytes) on the size of the kmem arena: 40% of the + * kernel map. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX ((vm_max_kernel_address - \ diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h index 19cdd8e115ef..c086d76d49aa 100644 --- a/sys/i386/include/vmparam.h +++ b/sys/i386/include/vmparam.h @@ -164,24 +164,23 @@ #define VM_MAX_ADDRESS VADDR(PTDPTDI, PTDPTDI) #define VM_MIN_ADDRESS ((vm_offset_t)0) -/* virtual sizes (bytes) for various kernel submaps */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12 * 1024 * 1024) -#endif - /* - * How many physical pages per KVA page allocated. - * min(max(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), - * VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE #define VM_KMEM_SIZE_SCALE (3) #endif /* - * Ceiling on the amount of kmem_map KVA space: 40% of the entire KVA space - * rounded to the nearest multiple of the superpage size. + * Optional floor (in bytes) on the size of the kmem arena. + */ +#ifndef VM_KMEM_SIZE_MIN +#define VM_KMEM_SIZE_MIN (12 * 1024 * 1024) +#endif + +/* + * Optional ceiling (in bytes) on the size of the kmem arena: 40% of the + * kernel map rounded to the nearest multiple of the superpage size. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX (((((VM_MAX_KERNEL_ADDRESS - \ diff --git a/sys/ia64/include/vmparam.h b/sys/ia64/include/vmparam.h index 1fda472a273e..edae4c4689f7 100644 --- a/sys/ia64/include/vmparam.h +++ b/sys/ia64/include/vmparam.h @@ -189,19 +189,11 @@ #define USRSTACK VM_MAXUSER_ADDRESS #define IA64_BACKINGSTORE (USRSTACK - (2 * MAXSSIZ) - PAGE_SIZE) -/* virtual sizes (bytes) for various kernel submaps */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12 * 1024 * 1024) -#endif - /* - * How many physical pages per KVA page allocated. - * min(max(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), - * VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE -#define VM_KMEM_SIZE_SCALE (4) /* XXX 8192 byte pages */ +#define VM_KMEM_SIZE_SCALE (4) #endif /* initial pagein size of beginning of executable file */ diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index bab745623d09..a5d25ea55032 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -684,41 +684,47 @@ kmem_reclaim(vmem_t *vm, int flags) pagedaemon_wakeup(); } +CTASSERT(VM_KMEM_SIZE_SCALE >= 1); + /* - * Initialize the kernel memory arena. + * Initialize the kernel memory (kmem) arena. */ void kmeminit(void) { u_long mem_size, tmp; - + /* - * Try to auto-tune the kernel memory size, so that it is - * more applicable for a wider range of machine sizes. The - * VM_KMEM_SIZE_MAX is dependent on the maximum KVA space - * available. + * Calculate the amount of kernel virtual address (KVA) space that is + * preallocated to the kmem arena. In order to support a wide range + * of machines, it is a function of the physical memory size, + * specifically, * - * Note that the kmem arena is also used by the zone allocator, - * so make sure that there is enough space. + * min(max(physical memory size / VM_KMEM_SIZE_SCALE, + * VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX) + * + * Every architecture must define an integral value for + * VM_KMEM_SIZE_SCALE. However, the definitions of VM_KMEM_SIZE_MIN + * and VM_KMEM_SIZE_MAX, which represent respectively the floor and + * ceiling on this preallocation, are optional. Typically, + * VM_KMEM_SIZE_MAX is itself a function of the available KVA space on + * a given architecture. */ - vm_kmem_size = VM_KMEM_SIZE; mem_size = cnt.v_page_count; -#if defined(VM_KMEM_SIZE_SCALE) vm_kmem_size_scale = VM_KMEM_SIZE_SCALE; -#endif TUNABLE_INT_FETCH("vm.kmem_size_scale", &vm_kmem_size_scale); - if (vm_kmem_size_scale > 0 && - (mem_size / vm_kmem_size_scale) > (vm_kmem_size / PAGE_SIZE)) - vm_kmem_size = (mem_size / vm_kmem_size_scale) * PAGE_SIZE; + if (vm_kmem_size_scale < 1) + vm_kmem_size_scale = VM_KMEM_SIZE_SCALE; + + vm_kmem_size = (mem_size / vm_kmem_size_scale) * PAGE_SIZE; #if defined(VM_KMEM_SIZE_MIN) vm_kmem_size_min = VM_KMEM_SIZE_MIN; #endif TUNABLE_ULONG_FETCH("vm.kmem_size_min", &vm_kmem_size_min); - if (vm_kmem_size_min > 0 && vm_kmem_size < vm_kmem_size_min) { + if (vm_kmem_size_min > 0 && vm_kmem_size < vm_kmem_size_min) vm_kmem_size = vm_kmem_size_min; - } #if defined(VM_KMEM_SIZE_MAX) vm_kmem_size_max = VM_KMEM_SIZE_MAX; @@ -727,15 +733,17 @@ kmeminit(void) if (vm_kmem_size_max > 0 && vm_kmem_size >= vm_kmem_size_max) vm_kmem_size = vm_kmem_size_max; - /* Allow final override from the kernel environment */ - TUNABLE_ULONG_FETCH("vm.kmem_size", &vm_kmem_size); - /* - * Limit kmem virtual size to twice the physical memory. - * This allows for kmem map sparseness, but limits the size - * to something sane. Be careful to not overflow the 32bit - * ints while doing the check or the adjustment. + * Alternatively, the amount of KVA space that is preallocated to the + * kmem arena can be set statically at compile-time or manually + * through the kernel environment. However, it is still limited to + * twice the physical memory size, which has been sufficient to handle + * the most severe cases of external fragmentation in the kmem arena. */ +#if defined(VM_KMEM_SIZE) + vm_kmem_size = VM_KMEM_SIZE; +#endif + TUNABLE_ULONG_FETCH("vm.kmem_size", &vm_kmem_size); if (vm_kmem_size / 2 / PAGE_SIZE > mem_size) vm_kmem_size = 2 * mem_size * PAGE_SIZE; diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h index 4e1f03c55185..8922924faa76 100644 --- a/sys/mips/include/vmparam.h +++ b/sys/mips/include/vmparam.h @@ -108,22 +108,23 @@ #define VM_NRESERVLEVEL 0 #endif -/* virtual sizes (bytes) for various kernel submaps */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12 * 1024 * 1024) -#endif - /* - * How many physical pages per KVA page allocated. - * min(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE #define VM_KMEM_SIZE_SCALE (3) #endif /* - * Ceiling on the amount of kmem_map KVA space: 40% of the entire KVA space. + * Optional floor (in bytes) on the size of the kmem arena. + */ +#ifndef VM_KMEM_SIZE_MIN +#define VM_KMEM_SIZE_MIN (12 * 1024 * 1024) +#endif + +/* + * Optional ceiling (in bytes) on the size of the kmem arena: 40% of the + * kernel map. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX ((VM_MAX_KERNEL_ADDRESS - \ diff --git a/sys/powerpc/include/vmparam.h b/sys/powerpc/include/vmparam.h index e8e22cd76bcb..2d50f94c9dcd 100644 --- a/sys/powerpc/include/vmparam.h +++ b/sys/powerpc/include/vmparam.h @@ -172,21 +172,23 @@ struct pmap_physseg { #define SGROWSIZ (128UL*1024) /* amount to grow stack */ #endif -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (12 * 1024 * 1024) -#endif - /* - * How many physical pages per KVA page allocated. - * min(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE -#define VM_KMEM_SIZE_SCALE (3) +#define VM_KMEM_SIZE_SCALE (3) #endif /* - * Ceiling on the amount of kmem_map KVA space: 40% of the entire KVA space. + * Optional floor (in bytes) on the size of the kmem arena. + */ +#ifndef VM_KMEM_SIZE_MIN +#define VM_KMEM_SIZE_MIN (12 * 1024 * 1024) +#endif + +/* + * Optional ceiling (in bytes) on the size of the kmem arena: 40% of the + * usable KVA space. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX ((VM_MAX_SAFE_KERNEL_ADDRESS - \ diff --git a/sys/sparc64/include/vmparam.h b/sys/sparc64/include/vmparam.h index 3cd744cb912c..b1c90d290a8b 100644 --- a/sys/sparc64/include/vmparam.h +++ b/sys/sparc64/include/vmparam.h @@ -198,24 +198,22 @@ #define USRSTACK (VM_MAX_USER_ADDRESS) /* - * Virtual size (bytes) for various kernel submaps. - */ -#ifndef VM_KMEM_SIZE -#define VM_KMEM_SIZE (16*1024*1024) -#endif - -/* - * How many physical pages per KVA page allocated. - * min(max(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), - * VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX) - * is the total KVA space allocated for kmem_map. + * How many physical pages per kmem arena virtual page. */ #ifndef VM_KMEM_SIZE_SCALE #define VM_KMEM_SIZE_SCALE (tsb_kernel_ldd_phys == 0 ? 3 : 2) #endif /* - * Ceiling on amount of kmem_map kva space. + * Optional floor (in bytes) on the size of the kmem arena. + */ +#ifndef VM_KMEM_SIZE_MIN +#define VM_KMEM_SIZE_MIN (16 * 1024 * 1024) +#endif + +/* + * Optional ceiling (in bytes) on the size of the kmem arena: 60% of the + * kernel map. */ #ifndef VM_KMEM_SIZE_MAX #define VM_KMEM_SIZE_MAX ((VM_MAX_KERNEL_ADDRESS - \