Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Use 4K pages on ARM_MMU_EXTENDED platforms (all armv[67]...



details:   https://anonhg.NetBSD.org/src/rev/40919b737301
branches:  trunk
changeset: 467256:40919b737301
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sat Jan 18 14:40:03 2020 +0000

description:
Use 4K pages on ARM_MMU_EXTENDED platforms (all armv[67] except RPI) by
creating a new pool l1ttpl for the userland L1 translation table which
needs to be 8KB and 8KB aligned.

Limit the pool to maxproc and add hooks to allow the sysctl changing of
maxproc to adjust the pool.

This comes at a 5% performance penalty for build.sh -j8 kernel on a
Tegra TK1.

diffstat:

 sys/arch/arm/arm32/cpu.c           |   13 ++-
 sys/arch/arm/arm32/pmap.c          |  178 +++++++++++++++++++++++++++++-------
 sys/arch/arm/include/arm32/param.h |    6 +-
 sys/arch/arm/include/arm32/pmap.h  |    6 +-
 sys/arch/arm/include/arm32/pte.h   |    4 +-
 sys/arch/arm/include/cpu.h         |    6 +-
 sys/arch/arm/include/types.h       |    3 +-
 sys/kern/init_sysctl.c             |   11 +-
 8 files changed, 180 insertions(+), 47 deletions(-)

diffs (truncated from 409 to 300 lines):

diff -r fd405ce4eb20 -r 40919b737301 sys/arch/arm/arm32/cpu.c
--- a/sys/arch/arm/arm32/cpu.c  Sat Jan 18 14:07:31 2020 +0000
+++ b/sys/arch/arm/arm32/cpu.c  Sat Jan 18 14:40:03 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.c,v 1.140 2020/01/15 08:34:04 mrg Exp $    */
+/*     $NetBSD: cpu.c,v 1.141 2020/01/18 14:40:04 skrll Exp $  */
 
 /*
  * Copyright (c) 1995 Mark Brinicombe.
@@ -46,7 +46,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.140 2020/01/15 08:34:04 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.141 2020/01/18 14:40:04 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -886,3 +886,12 @@
            "pfr: [0]=%#x [1]=%#x\n",
            cpu_processor_features[0], cpu_processor_features[1]);
 }
+
+#ifdef _ARM_ARCH_6
+int
+cpu_maxproc_hook(int nmaxproc)
+{
+
+       return pmap_maxproc_set(nmaxproc);
+}
+#endif
diff -r fd405ce4eb20 -r 40919b737301 sys/arch/arm/arm32/pmap.c
--- a/sys/arch/arm/arm32/pmap.c Sat Jan 18 14:07:31 2020 +0000
+++ b/sys/arch/arm/arm32/pmap.c Sat Jan 18 14:40:03 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.379 2020/01/18 07:52:33 skrll Exp $ */
+/*     $NetBSD: pmap.c,v 1.380 2020/01/18 14:40:04 skrll Exp $ */
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -221,7 +221,7 @@
 #include <arm/db_machdep.h>
 #endif
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.379 2020/01/18 07:52:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.380 2020/01/18 14:40:04 skrll Exp $");
 
 //#define PMAP_DEBUG
 #ifdef PMAP_DEBUG
@@ -745,6 +745,7 @@
 
 static struct l2_bucket *pmap_get_l2_bucket(pmap_t, vaddr_t);
 static struct l2_bucket *pmap_alloc_l2_bucket(pmap_t, vaddr_t);
+static int             pmap_l1tt_ctor(void *, void *, int);
 static void            pmap_free_l2_bucket(pmap_t, struct l2_bucket *, u_int);
 static int             pmap_l2ptp_ctor(void *, void *, int);
 static int             pmap_l2dtable_ctor(void *, void *, int);
@@ -778,6 +779,20 @@
 #endif
 static vaddr_t         kernel_pt_lookup(paddr_t);
 
+#ifdef ARM_MMU_EXTENDED
+
+static struct pool_cache pmap_l1tt_cache;
+
+static void *pmap_l1tt_alloc(struct pool *, int);
+static void pmap_l1tt_free(struct pool *, void *);
+
+static struct pool_allocator pmap_l1tt_allocator = {
+       .pa_alloc = pmap_l1tt_alloc,
+       .pa_free = pmap_l1tt_free,
+       .pa_pagesz = L1TT_SIZE,
+};
+
+#endif
 
 /*
  * Misc variables
@@ -1290,6 +1305,29 @@
        return (oflags);
 }
 
+
+#if defined(ARM_MMU_EXTENDED)
+int
+pmap_maxproc_set(int nmaxproc)
+{
+       static const char pmap_l1ttpool_warnmsg[] =
+           "WARNING: l1ttpool limit reached; increase kern.maxproc";
+
+//     pool_cache_setlowat(&pmap_l1tt_cache, nmaxproc);
+
+       /*
+        * Set the hard limit on the pmap_l1tt_cache to the number
+        * of processes the kernel is to support.  Log the limit
+        * reached message max once a minute.
+        */
+       pool_cache_sethardlimit(&pmap_l1tt_cache, nmaxproc,
+           pmap_l1ttpool_warnmsg, 60);
+
+       return 0;
+}
+
+#endif
+
 /*
  * Allocate an L1 translation table for the specified pmap.
  * This is called at pmap creation time.
@@ -1298,33 +1336,11 @@
 pmap_alloc_l1(pmap_t pm)
 {
 #ifdef ARM_MMU_EXTENDED
-#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
-       struct vm_page *pg;
-       bool ok __diagused;
-       for (;;) {
-#ifdef PMAP_NEED_ALLOC_POOLPAGE
-               pg = arm_pmap_alloc_poolpage(UVM_PGA_ZERO);
-#else
-               pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
-#endif
-               if (pg != NULL)
-                       break;
-               uvm_wait("pmapl1alloc");
-       }
-       pm->pm_l1_pa = VM_PAGE_TO_PHYS(pg);
-       vaddr_t va = pmap_direct_mapped_phys(pm->pm_l1_pa, &ok, 0);
-       KASSERT(ok);
-       KASSERT(va >= KERNEL_BASE);
-
-#else
-       KASSERTMSG(kernel_map != NULL, "pm %p", pm);
-       vaddr_t va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
-           UVM_KMF_WIRED|UVM_KMF_ZERO);
-       KASSERT(va);
-       pmap_extract(pmap_kernel(), va, &pm->pm_l1_pa);
-#endif
+       vaddr_t va = (vaddr_t)pool_cache_get_paddr(&pmap_l1tt_cache, PR_WAITOK,
+           &pm->pm_l1_pa);
+
        pm->pm_l1 = (pd_entry_t *)va;
-       PTE_SYNC_RANGE(pm->pm_l1, PAGE_SIZE / sizeof(pt_entry_t));
+       PTE_SYNC_RANGE(pm->pm_l1, L1TT_SIZE / sizeof(pt_entry_t));
 #else
        struct l1_ttable *l1;
        uint8_t domain;
@@ -1369,12 +1385,8 @@
 pmap_free_l1(pmap_t pm)
 {
 #ifdef ARM_MMU_EXTENDED
-#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
-       struct vm_page *pg = PHYS_TO_VM_PAGE(pm->pm_l1_pa);
-       uvm_pagefree(pg);
-#else
-       uvm_km_free(kernel_map, (vaddr_t)pm->pm_l1, PAGE_SIZE, UVM_KMF_WIRED);
-#endif
+       pool_cache_put_paddr(&pmap_l1tt_cache, (void *)pm->pm_l1, pm->pm_l1_pa);
+
        pm->pm_l1 = NULL;
        pm->pm_l1_pa = 0;
 #else
@@ -1671,6 +1683,24 @@
        pmap_free_l2_dtable(l2);
 }
 
+#if defined(ARM_MMU_EXTENDED)
+/*
+ * Pool cache constructors for L1 translation tables
+ */
+
+static int
+pmap_l1tt_ctor(void *arg, void *v, int flags)
+{
+#ifndef PMAP_INCLUDE_PTE_SYNC
+#error not supported
+#endif
+
+       memset(v, 0, L1TT_SIZE);
+       PTE_SYNC_RANGE(v, L1TT_SIZE / sizeof(pt_entry_t));
+       return 0;
+}
+#endif
+
 /*
  * Pool cache constructors for L2 descriptor tables, metadata and pmap
  * structures.
@@ -6484,6 +6514,17 @@
        pool_setlowat(&pmap_pv_pool, (PAGE_SIZE / sizeof(struct pv_entry)) * 2);
 
 #ifdef ARM_MMU_EXTENDED
+       /*
+        * Initialise the L1 pool and cache.
+        */
+
+       pool_cache_bootstrap(&pmap_l1tt_cache, L1TT_SIZE, L1TT_SIZE,
+           0, 0, "l1ttpl", &pmap_l1tt_allocator, IPL_NONE, pmap_l1tt_ctor,
+            NULL, NULL);
+
+       int error __diagused = pmap_maxproc_set(maxproc);
+       KASSERT(error == 0);
+
        pmap_tlb_info_evcnt_attach(&pmap_tlb0_info);
 #endif
 
@@ -6535,6 +6576,75 @@
        }
 }
 
+
+#if defined(ARM_MMU_EXTENDED)
+static void *
+pmap_l1tt_alloc(struct pool *pp, int flags)
+{
+       struct pglist plist;
+       vaddr_t va;
+
+       const int waitok = flags & PR_WAITOK;
+
+       int error = uvm_pglistalloc(L1TT_SIZE, 0, -1, L1TT_SIZE, 0, &plist, 1,
+           waitok);
+       if (error)
+               panic("Cannot allocate L1TT physical pages, %d", error);
+
+       struct vm_page *pg = TAILQ_FIRST(&plist);
+#if !defined( __HAVE_MM_MD_DIRECT_MAPPED_PHYS)
+
+       /* Allocate a L1 translation table VA */
+       va = uvm_km_alloc(kernel_map, L1TT_SIZE, L1TT_SIZE, UVM_KMF_VAONLY);
+       if (va == 0)
+               panic("Cannot allocate L1TT KVA");
+
+       const vaddr_t eva = va + L1TT_SIZE;
+       vaddr_t mva = va;
+       while (pg && mva < eva) {
+               paddr_t pa = VM_PAGE_TO_PHYS(pg);
+
+               pmap_kenter_pa(mva, pa,
+                   VM_PROT_READ|VM_PROT_WRITE, PMAP_KMPAGE|PMAP_PTE);
+
+               mva += PAGE_SIZE;
+               pg = TAILQ_NEXT(pg, pageq.queue);
+       }
+       KASSERTMSG(pg == NULL && mva == eva, "pg %p mva %" PRIxVADDR
+           " eva %" PRIxVADDR, pg, mva, eva);
+#else
+       bool ok;
+       paddr_t pa = VM_PAGE_TO_PHYS(pg);
+       va = pmap_direct_mapped_phys(pa, &ok, 0);
+       KASSERT(ok);
+       KASSERT(va >= KERNEL_BASE);
+#endif
+
+       return (void *)va;
+}
+
+static void
+pmap_l1tt_free(struct pool *pp, void *v)
+{
+       vaddr_t va = (vaddr_t)v;
+
+#if !defined( __HAVE_MM_MD_DIRECT_MAPPED_PHYS)
+       uvm_km_free(kernel_map, va, L1TT_SIZE, 0);
+#else
+       paddr_t pa;
+
+       bool ok = pmap_extract(pmap_kernel(), va, &pa);
+       KASSERT(ok);
+       const paddr_t epa = pa + L1TT_SIZE;
+
+       for (; pa < epa; pa += PAGE_SIZE) {
+               struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
+               uvm_pagefree(pg);
+       }
+#endif
+}
+#endif
+
 /*
  * pmap_postinit()
  *
diff -r fd405ce4eb20 -r 40919b737301 sys/arch/arm/include/arm32/param.h
--- a/sys/arch/arm/include/arm32/param.h        Sat Jan 18 14:07:31 2020 +0000
+++ b/sys/arch/arm/include/arm32/param.h        Sat Jan 18 14:40:03 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.27 2019/06/19 09:53:39 skrll Exp $ */
+/*     $NetBSD: param.h,v 1.28 2020/01/18 14:40:04 skrll Exp $ */
 
 /*
  * Copyright (c) 1994,1995 Mark Brinicombe.
@@ -46,12 +46,8 @@
  * this file. */
 
 #ifndef PGSHIFT
-#if defined(_ARM_ARCH_6)
-#define        PGSHIFT         13              /* LOG2(NBPG) */
-#else
 #define        PGSHIFT         12              /* LOG2(NBPG) */
 #endif
-#endif
 #define        NBPG            (1 << PGSHIFT)  /* bytes/page */



Home | Main Index | Thread Index | Old Index