kernel - Increase x86_64 & vkernel kvm, adjust vm_page_array mapping
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 15 Sep 2010 20:17:18 +0000 (13:17 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 15 Sep 2010 20:17:18 +0000 (13:17 -0700)
* Change the vm_page_array and dmesg space to not use the DMAP area.
  The space could not be accessed by userland kvm utilities due
  to that issue.

  TODO - reoptimize to use 2M super-pages.

* Auto-size NKPT to accomodate the above changes as vm_page_array[]
  is now mapped into the kernel page tables.

* Increase NKPDPE to 128 PDPs to accomodate machines with large
  amounts of ram.  This increases the kernel KVA space to 128G.

sys/platform/pc64/include/pmap.h
sys/platform/pc64/include/vmparam.h
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/pmap.c
sys/platform/vkernel64/include/pmap.h
sys/platform/vkernel64/platform/pmap.c

index 635b5e3..1250745 100644 (file)
        ((unsigned long)(l1) << PAGE_SHIFT))
 
 /*
- * Initial number of kernel page tables x 2
+ * NOTE: We no longer hardwire NKPT, it is calculated in create_pagetables()
  */
-#ifndef NKPT
-#define        NKPT            64
-#endif
-
 #define NKPML4E                1               /* number of kernel PML4 slots */
 /* NKPDPE defined in vmparam.h */
 
@@ -255,7 +251,6 @@ extern vm_offset_t clean_eva;
 extern vm_offset_t clean_sva;
 extern char *ptvmmap;          /* poor name! */
 
-void   init_paging(vm_paddr_t *);
 void   pmap_interlock_wait (struct vmspace *);
 void   pmap_bootstrap (vm_paddr_t *);
 void   *pmap_mapdev (vm_paddr_t, vm_size_t);
index f0bf737..3025517 100644 (file)
  *
  * The kernel address space can be up to (I think) 511 page directory
  * pages.  Each one represents 1G.  NKPDPE defines the size of the kernel
- * address space, curently set to 8G.
+ * address space, curently set to 128G.
  */
-#define NKPDPE                 8
+#define NKPDPE                 128
 #define        VM_MAX_KERNEL_ADDRESS   KVADDR(KPML4I, NPDPEPG-1, NPDEPG-1, NPTEPG-1)
 #define        VM_MIN_KERNEL_ADDRESS   KVADDR(KPML4I, NPDPEPG-NKPDPE, 0, 0)
 
index 378c5e0..955c217 100644 (file)
@@ -1640,14 +1640,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
        struct mdglobaldata *gd;
        u_int64_t msr;
 
-#if JG
-       /*
-        * This must be done before the first references
-        * to CPU_prvspace[0] are made.
-        */
-       init_paging(&physfree);
-#endif
-
        /*
         * Prevent lowering of the ipl if we call tsleep() early.
         */
index 17ff29b..cdcfa81 100644 (file)
@@ -2232,10 +2232,6 @@ start_all_aps(u_int boot_addr)
         * NOTE!  The idlestack for the BSP was setup by locore.  Finish
         * up, clean out the P==V mapping we did earlier.
         */
-#if JGXXX
-       for (x = 0; x < NKPT; x++)
-               PTD[x] = 0;
-#endif
        pmap_set_opt();
 
        /* number of APs actually started */
index fef9c60..67d720d 100644 (file)
@@ -429,11 +429,22 @@ create_pagetables(vm_paddr_t *firstaddr)
 {
        int i;
 
-       /* we are running (mostly) V=P at this point */
+       /*
+        * We are running (mostly) V=P at this point
+        *
+        * Calculate NKPT - number of kernel page tables.  We have to
+        * accomodoate prealloction of the vm_page_array, dump bitmap,
+        * MSGBUF_SIZE, and other stuff.  Be generous.
+        *
+        * Maxmem is in pages.
+        */
+       nkpt = (Maxmem * (sizeof(struct vm_page) * 2) + MSGBUF_SIZE) / NBPDR;
 
-       /* Allocate pages */
-       KPTbase = allocpages(firstaddr, NKPT);
-       KPTphys = allocpages(firstaddr, NKPT);
+       /*
+        * Allocate pages
+        */
+       KPTbase = allocpages(firstaddr, nkpt);
+       KPTphys = allocpages(firstaddr, nkpt);
        KPML4phys = allocpages(firstaddr, 1);
        KPDPphys = allocpages(firstaddr, NKPML4E);
 
@@ -471,11 +482,11 @@ create_pagetables(vm_paddr_t *firstaddr)
         * and another block is placed at KERNBASE to map the kernel binary,
         * data, bss, and initial pre-allocations.
         */
-       for (i = 0; i < NKPT; i++) {
+       for (i = 0; i < nkpt; i++) {
                ((pd_entry_t *)KPDbase)[i] = KPTbase + (i << PAGE_SHIFT);
                ((pd_entry_t *)KPDbase)[i] |= PG_RW | PG_V;
        }
-       for (i = 0; i < NKPT; i++) {
+       for (i = 0; i < nkpt; i++) {
                ((pd_entry_t *)KPDphys)[i] = KPTphys + (i << PAGE_SHIFT);
                ((pd_entry_t *)KPDphys)[i] |= PG_RW | PG_V;
        }
@@ -537,12 +548,6 @@ create_pagetables(vm_paddr_t *firstaddr)
        ((pdp_entry_t *)KPML4phys)[KPML4I] |= PG_RW | PG_V | PG_U;
 }
 
-void
-init_paging(vm_paddr_t *firstaddr)
-{
-       create_pagetables(firstaddr);
-}
-
 /*
  *     Bootstrap the system enough to run with virtual memory.
  *
@@ -598,7 +603,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
        kernel_pmap.pm_count = 1;
        kernel_pmap.pm_active = (cpumask_t)-1 & ~CPUMASK_LOCK;
        TAILQ_INIT(&kernel_pmap.pm_pvlist);
-       nkpt = NKPT;
 
        /*
         * Reserve some special page table entries/VA space for temporary
@@ -608,11 +612,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
        v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
 
        va = virtual_start;
-#ifdef JG
-       pte = (pt_entry_t *) pmap_pte(&kernel_pmap, va);
-#else
        pte = vtopte(va);
-#endif
 
        /*
         * CMAP1/CMAP2 are used for zeroing and copying pages.
@@ -1011,16 +1011,35 @@ pmap_kmodify_nc(vm_offset_t va)
 }
 
 /*
- *     Used to map a range of physical addresses into kernel
- *     virtual address space.
+ * Used to map a range of physical addresses into kernel virtual
+ * address space during the low level boot, typically to map the
+ * dump bitmap, message buffer, and vm_page_array.
  *
- *     For now, VM is already on, we only need to map the
- *     specified memory.
+ * These mappings are typically made at some pointer after the end of the
+ * kernel text+data.
+ *
+ * We could return PHYS_TO_DMAP(start) here and not allocate any
+ * via (*virtp), but then kmem from userland and kernel dumps won't
+ * have access to the related pointers.
  */
 vm_offset_t
 pmap_map(vm_offset_t *virtp, vm_paddr_t start, vm_paddr_t end, int prot)
 {
-       return PHYS_TO_DMAP(start);
+       vm_offset_t va;
+       vm_offset_t va_start;
+
+       /*return PHYS_TO_DMAP(start);*/
+
+       va_start = *virtp;
+       va = va_start;
+
+       while (start < end) {
+               pmap_kenter_quick(va, start);
+               va += PAGE_SIZE;
+               start += PAGE_SIZE;
+       }
+       *virtp = va;
+       return va_start;
 }
 
 
index 4a0691b..244e43c 100644 (file)
        ((unsigned long)(l2) << PDRSHIFT) | \
        ((unsigned long)(l1) << PAGE_SHIFT))
 
-/* Initial number of kernel page tables. */
-#ifndef NKPT
-#define        NKPT            32
-#endif
-
+/*
+ * Initial number of kernel page tables.  NKPT is now calculated in the
+ * pmap code.
+ *
+ * Give NKPDPE a generous value, allowing the kernel to map up to 128G.
+ */
 #define NKPML4E                1               /* number of kernel PML4 slots */
-#define NKPDPE         howmany(NKPT, NPDEPG)/* number of kernel PDP slots */
+#define NKPDPE         128             /* number of kernel PDP slots */
 
 #define        NUPML4E         (NPML4EPG/2)    /* number of userland PML4 pages */
 #define        NUPDPE          (NUPML4E*NPDPEPG)/* number of userland PDP pages */
index d799607..c753203 100644 (file)
@@ -392,12 +392,22 @@ create_pagetables(vm_paddr_t *firstaddr, int64_t ptov_offset)
        int kpml4i = pmap_pml4e_index(ptov_offset);
        int kpdpi = pmap_pdpe_index(ptov_offset);
 
+       /*
+         * Calculate NKPT - number of kernel page tables.  We have to
+         * accomodoate prealloction of the vm_page_array, dump bitmap,
+         * MSGBUF_SIZE, and other stuff.  Be generous.
+         *
+         * Maxmem is in pages.
+         */
+        nkpt = (Maxmem * (sizeof(struct vm_page) * 2) + MSGBUF_SIZE) / NBPDR;
 
-       /* Allocate pages */
+       /*
+        * Allocate pages
+        */
        KPML4phys = allocpages(firstaddr, 1);
        KPDPphys = allocpages(firstaddr, NKPML4E);
        KPDphys = allocpages(firstaddr, NKPDPE);
-       KPTphys = allocpages(firstaddr, NKPT);
+       KPTphys = allocpages(firstaddr, nkpt);
 
        KPML4virt = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys);
        KPDPvirt = (pdp_entry_t *)PHYS_TO_DMAP(KPDPphys);
@@ -407,10 +417,10 @@ create_pagetables(vm_paddr_t *firstaddr, int64_t ptov_offset)
        bzero(KPML4virt, 1 * PAGE_SIZE);
        bzero(KPDPvirt, NKPML4E * PAGE_SIZE);
        bzero(KPDvirt, NKPDPE * PAGE_SIZE);
-       bzero(KPTvirt, NKPT * PAGE_SIZE);
+       bzero(KPTvirt, nkpt * PAGE_SIZE);
 
        /* Now map the page tables at their location within PTmap */
-       for (i = 0; i < NKPT; i++) {
+       for (i = 0; i < nkpt; i++) {
                KPDvirt[i] = KPTphys + (i << PAGE_SHIFT);
                KPDvirt[i] |= VPTE_R | VPTE_W | VPTE_V;
        }
@@ -468,7 +478,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr, int64_t ptov_offset)
        kernel_pmap.pm_count = 1;
        kernel_pmap.pm_active = (cpumask_t)-1;  /* don't allow deactivation */
        TAILQ_INIT(&kernel_pmap.pm_pvlist);
-       nkpt = NKPT;
 
        /*
         * Reserve some special page table entries/VA space for temporary