kernel address space and auto-sizing
Alan Cox
alc at rice.edu
Mon Feb 25 00:08:13 UTC 2013
After the fallout from the recent auto-sizing changes, I've been
reviewing the kernel address space configuration on all of our supported
architectures. This review turned up a couple of odd things on the AIM
platform:
1. Everywhere else, except for 32- and 64-bit AIM, VM_MAX_KERNEL_ADDRESS
denotes the end of the kernel map. Instead, 32- and 64-bit AIM define
VM_MAX_SAFE_KERNEL_ADDRESS and uses this to initialize the end of the
kernel map. On occasion, we use VM_MAX_KERNEL_ADDRESS to implement
auto-sizing based on the size of the kernel map, so this difference
interferes with that.
2. The size of the kmem submap on 32-bit AIM is hardwired to only 12
MB! ARM had the same issue. There, the consequences were much worse
because ARM, unlike 32-bit AIM, doesn't have a direct map, so
uma_small_alloc() can't be used on arm. However, even with
uma_small_alloc(), this 12 MB cap on the kmem submap still unnecessarily
limits multipage allocations by the kernel. Even with a direct map,
those come from the kmem submap.
The attached patch does the following things to AIM:
1. On 32-bit AIM, it redefines VM_MAX_KERNEL_ADDRESS to be the address
that should be the end of the kernel map and eliminates
VM_MAX_SAFE_KERNEL_ADDRESS. On 64-bit AIM, VM_MAX_KERNEL_ADDRESS and
VM_MAX_SAFE_KERNEL_ADDRESS were the same, so it simply eliminates
VM_MAX_SAFE_KERNEL_ADDRESS.
2. It enables auto-sizing of the kmem submap on 32-bit AIM, but places a
cap on its maximum size so that it will not consume the entire kernel
map. (64-bit AIM already has auto-sizing and a cap for the kmem submap.)
I would appreciate review and/or testing of this patch. In particular,
I'd like to see the output from two sysctl's before and after applying
the patch: vm.max_kernel_address, vm.kmem_size, and vm.kmem_size_max
Thanks,
Alan
P.S. On 64-bit AIM, the following bit of code in the pmap bootstrap
function was already a NOP because VM_MAX_KERNEL_ADDRESS and
VM_MAX_SAFE_KERNEL_ADDRESS were the same. I didn't touch it, but I
thought that I would mention it.
#ifndef __powerpc64__ /* KVA is in high memory on PPC64 */
PMAP_LOCK(kernel_pmap);
while (virtual_end < VM_MAX_KERNEL_ADDRESS &&
moea64_pvo_find_va(kernel_pmap, virtual_end+1) == NULL)
virtual_end += PAGE_SIZE;
PMAP_UNLOCK(kernel_pmap);
#endif
-------------- next part --------------
Index: powerpc/aim/mmu_oea.c
===================================================================
--- powerpc/aim/mmu_oea.c (revision 247166)
+++ powerpc/aim/mmu_oea.c (working copy)
@@ -934,7 +934,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart
* Set the start and end of kva.
*/
virtual_avail = VM_MIN_KERNEL_ADDRESS;
- virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS;
+ virtual_end = VM_MAX_KERNEL_ADDRESS;
/*
* Allocate a kernel stack with a guard page for thread0 and map it
Index: powerpc/aim/mmu_oea64.c
===================================================================
--- powerpc/aim/mmu_oea64.c (revision 247166)
+++ powerpc/aim/mmu_oea64.c (working copy)
@@ -872,7 +872,7 @@ moea64_late_bootstrap(mmu_t mmup, vm_offset_t kern
* Set the start and end of kva.
*/
virtual_avail = VM_MIN_KERNEL_ADDRESS;
- virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS;
+ virtual_end = VM_MAX_KERNEL_ADDRESS;
/*
* Map the entire KVA range into the SLB. We must not fault there.
Index: powerpc/include/vmparam.h
===================================================================
--- powerpc/include/vmparam.h (revision 247166)
+++ powerpc/include/vmparam.h (working copy)
@@ -93,11 +93,9 @@
#ifdef __powerpc64__
#define VM_MIN_KERNEL_ADDRESS 0xc000000000000000UL
#define VM_MAX_KERNEL_ADDRESS 0xc0000001c7ffffffUL
-#define VM_MAX_SAFE_KERNEL_ADDRESS VM_MAX_KERNEL_ADDRESS
#else
#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)KERNEL_SR << ADDR_SR_SHFT)
-#define VM_MAX_SAFE_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + 2*SEGMENT_LENGTH -1)
-#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + 3*SEGMENT_LENGTH - 1)
+#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + 2*SEGMENT_LENGTH - 1)
#endif
/*
@@ -188,13 +186,16 @@ struct pmap_physseg {
#define VM_KMEM_SIZE (12 * 1024 * 1024)
#endif
-#ifdef __powerpc64__
#ifndef VM_KMEM_SIZE_SCALE
#define VM_KMEM_SIZE_SCALE (3)
#endif
#ifndef VM_KMEM_SIZE_MAX
+#ifdef __powerpc64__
#define VM_KMEM_SIZE_MAX 0x1c0000000 /* 7 GB */
+#else
+#define VM_KMEM_SIZE_MAX ((VM_MAX_KERNEL_ADDRESS - \
+ VM_MIN_KERNEL_ADDRESS + 1) * 2 / 5)
#endif
#endif
More information about the freebsd-ppc
mailing list