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