Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86 Back out the recent pmap changes until I can fi...



details:   https://anonhg.NetBSD.org/src/rev/cdcae3d98676
branches:  trunk
changeset: 849880:cdcae3d98676
user:      ad <ad%NetBSD.org@localhost>
date:      Tue Mar 17 21:02:56 2020 +0000

description:
Back out the recent pmap changes until I can figure out what is going on
with pmap_page_remove()  (to pmap.c rev 1.365).

diffstat:

 sys/arch/x86/include/pmap.h    |    6 +-
 sys/arch/x86/include/pmap_pv.h |   19 +-
 sys/arch/x86/x86/pmap.c        |  949 ++++++++++++----------------------------
 3 files changed, 297 insertions(+), 677 deletions(-)

diffs (truncated from 1623 to 300 lines):

diff -r 0957b145df34 -r cdcae3d98676 sys/arch/x86/include/pmap.h
--- a/sys/arch/x86/include/pmap.h       Tue Mar 17 18:40:35 2020 +0000
+++ b/sys/arch/x86/include/pmap.h       Tue Mar 17 21:02:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.113 2020/03/14 18:24:10 ad Exp $    */
+/*     $NetBSD: pmap.h,v 1.114 2020/03/17 21:02:56 ad Exp $    */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -248,8 +248,6 @@
  * (the other object locks are only used when uvm_pagealloc is called)
  */
 
-struct pv_page;
-
 struct pmap {
        struct uvm_object pm_obj[PTP_LEVELS-1];/* objects for lvl >= 1) */
        LIST_ENTRY(pmap) pm_list;       /* list of all pmaps */
@@ -258,11 +256,11 @@
        struct vm_page *pm_ptphint[PTP_LEVELS-1];
                                        /* pointer to a PTP in our pmap */
        struct pmap_statistics pm_stats;  /* pmap stats */
-       struct pv_entry *pm_pve;        /* spare pv_entry */
 
 #if !defined(__x86_64__)
        vaddr_t pm_hiexec;              /* highest executable mapping */
 #endif /* !defined(__x86_64__) */
+       struct lwp *pm_remove_all;      /* who's emptying the pmap */
 
        union descriptor *pm_ldt;       /* user-set LDT */
        size_t pm_ldt_len;              /* size of LDT in bytes */
diff -r 0957b145df34 -r cdcae3d98676 sys/arch/x86/include/pmap_pv.h
--- a/sys/arch/x86/include/pmap_pv.h    Tue Mar 17 18:40:35 2020 +0000
+++ b/sys/arch/x86/include/pmap_pv.h    Tue Mar 17 21:02:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap_pv.h,v 1.15 2020/03/15 15:58:24 ad Exp $  */
+/*     $NetBSD: pmap_pv.h,v 1.16 2020/03/17 21:02:56 ad Exp $  */
 
 /*-
  * Copyright (c)2008 YAMAMOTO Takashi,
@@ -34,7 +34,6 @@
 #include <sys/rbtree.h>
 
 struct vm_page;
-struct pmap_page;
 
 /*
  * structures to track P->V mapping
@@ -52,14 +51,14 @@
 };
 
 /*
- * pv_entry: plug pv_pte into lists.  32 bytes on i386, 64 on amd64.
+ * pv_entry: plug pv_pte into lists.
  */
 
 struct pv_entry {
        struct pv_pte pve_pte;          /* should be the first member */
        LIST_ENTRY(pv_entry) pve_list;  /* on pmap_page::pp_pvlist */
        rb_node_t pve_rb;               /* red-black tree node */
-       struct pmap_page *pve_pp;       /* backpointer to mapped page */
+       uintptr_t pve_padding;          /* unused */
 };
 #define        pve_next        pve_list.le_next
 
@@ -72,13 +71,16 @@
                /* PTPs */
                rb_tree_t rb;
 
-               /* PTPs, when being freed */
+               /* PTPs */
                LIST_ENTRY(vm_page) link;
 
-               /* Non-PTPs (i.e. normal pages) */
+               /* Non-PTPs */
                struct {
+                       /* PP_EMBEDDED */
                        struct pv_pte pte;
+
                        LIST_HEAD(, pv_entry) pvlist;
+                       uint8_t flags;
                        uint8_t attrs;
                } s;
        } pp_u;
@@ -87,6 +89,7 @@
 #define        pp_link         pp_u.link
 #define        pp_pte          pp_u.s.pte
 #define pp_pvlist      pp_u.s.pvlist
+#define        pp_pflags       pp_u.s.flags
 #define        pp_attrs        pp_u.s.attrs
 };
 
@@ -94,6 +97,10 @@
 #define PP_ATTRS_A     0x02    /* Accessed */
 #define PP_ATTRS_W     0x04    /* Writable */
 
+/* pp_flags */
+#define        PP_EMBEDDED     1
+#define        PP_FREEING      2
+
 #define        PMAP_PAGE_INIT(pp) \
 do { \
        LIST_INIT(&(pp)->pp_pvlist); \
diff -r 0957b145df34 -r cdcae3d98676 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Tue Mar 17 18:40:35 2020 +0000
+++ b/sys/arch/x86/x86/pmap.c   Tue Mar 17 21:02:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.372 2020/03/17 18:40:35 ad Exp $    */
+/*     $NetBSD: pmap.c,v 1.373 2020/03/17 21:02:56 ad Exp $    */
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017, 2019, 2020 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.372 2020/03/17 18:40:35 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.373 2020/03/17 21:02:56 ad Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -139,8 +139,6 @@
 #include "opt_svs.h"
 #include "opt_kaslr.h"
 
-#define        __MUTEX_PRIVATE /* for assertions */
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
@@ -226,39 +224,23 @@
 /*
  * Locking
  *
- * We have the following locks that we must deal with, listed in the order
- * that they are acquired:
- *
- * pg->uobject->vmobjlock, pg->uanon->an_lock
+ * We have the following locks that we must contend with, listed in the
+ * order that they must be acquired:
  *
- *     For managed pages, these per-object locks are taken by the VM system
- *     before calling into the pmap module - either a read or write hold. 
- *     The lock hold prevent pages from changing identity while the pmap is
- *     operating on them.  For example, the same lock is held across a call
- *     to pmap_remove() and the following call to pmap_update(), so that a
- *     page does not gain a new identity while its TLB visibility is stale.
- *
- * pmap->pm_lock
+ * - pg->uobject->vmobjlock, pg->uanon->an_lock
+ *   These per-object locks are taken by the VM system before calling into
+ *   the pmap module.  Holding them prevents concurrent operations on the
+ *   given page or set of pages.
  *
- *     This lock protects the fields in the pmap structure including the
- *     non-kernel PDEs in the PDP, the PTEs, and PTPs and connected data
- *     structures.  For modifying unmanaged kernel PTEs it is not needed as
- *     kernel PDEs are never freed, and the kernel is expected to be self
- *     consistent (and the lock can't be taken for unmanaged kernel PTEs,
- *     because they can be modified from interrupt context).
- *
- * pmaps_lock
+ * - pmap->pm_lock (per pmap)
+ *   This lock protects the fields in the pmap structure including the
+ *   non-kernel PDEs in the PDP, the PTEs, and the PVE radix tree.  For
+ *   modifying kernel PTEs it is not required as kernel PDEs are never
+ *   freed, and the kernel is expected to be self consistent.
  *
- *     This lock protects the list of active pmaps (headed by "pmaps"). 
- *     It's acqired when adding or removing pmaps or adjusting kernel PDEs.
- *
- * pp_lock
- *
- *     This per-page lock protects PV entry lists and the embedded PV entry
- *     in each vm_page, allowing for concurrent operation on pages by
- *     different pmaps.  This is a spin mutex at IPL_VM, because at the
- *     points it is taken context switching is usually not tolerable, and
- *     spin mutexes must block out interrupts that could take kernel_lock.
+ * - pmaps_lock
+ *   This lock protects the list of active pmaps (headed by "pmaps"). We
+ *   lock it when adding or removing pmaps from this list.
  */
 
 /* uvm_object is abused here to index pmap_pages; make assertions happy. */
@@ -335,8 +317,6 @@
 #endif
 
 #define        VM_PAGE_TO_PP(pg)       (&(pg)->mdpage.mp_pp)
-#define        PMAP_CHECK_PP(pp) \
-    KASSERTMSG((pp)->pp_lock.mtx_ipl._ipl == IPL_VM, "bad pmap_page %p", pp)
 
 /*
  * Other data structures
@@ -543,17 +523,6 @@
 }
 
 /*
- * Return true if the pmap page has an embedded PV entry.
- */
-static inline bool
-pv_pte_embedded(struct pmap_page *pp)
-{
-
-       KASSERT(mutex_owned(&pp->pp_lock));
-       return (bool)((vaddr_t)pp->pp_pte.pte_ptp | pp->pp_pte.pte_va);
-}
-
-/*
  * pv_pte_first, pv_pte_next: PV list iterator.
  */
 static struct pv_pte *
@@ -561,7 +530,7 @@
 {
 
        KASSERT(mutex_owned(&pp->pp_lock));
-       if (pv_pte_embedded(pp)) {
+       if ((pp->pp_pflags & PP_EMBEDDED) != 0) {
                return &pp->pp_pte;
        }
        return pve_to_pvpte(LIST_FIRST(&pp->pp_pvlist));
@@ -574,6 +543,7 @@
        KASSERT(mutex_owned(&pp->pp_lock));
        KASSERT(pvpte != NULL);
        if (pvpte == &pp->pp_pte) {
+               KASSERT((pp->pp_pflags & PP_EMBEDDED) != 0);
                return pve_to_pvpte(LIST_FIRST(&pp->pp_pvlist));
        }
        return pve_to_pvpte(LIST_NEXT(pvpte_to_pve(pvpte), pve_list));
@@ -635,61 +605,6 @@
 }
 
 /*
- * pmap_ptp_init: initialize new page table page
- */
-static inline void
-pmap_ptp_init(struct vm_page *ptp)
-{
-
-       ptp->uanon = (struct vm_anon *)(vaddr_t)~0L;
-       rb_tree_init(&VM_PAGE_TO_PP(ptp)->pp_rb, &pmap_rbtree_ops);
-       PMAP_CHECK_PP(VM_PAGE_TO_PP(ptp));
-}
-
-/*
- * pmap_ptp_fini: finalize a page table page
- */
-static inline void
-pmap_ptp_fini(struct vm_page *ptp)
-{
-
-       KASSERT(RB_TREE_MIN(&VM_PAGE_TO_PP(ptp)->pp_rb) == NULL);
-       PMAP_CHECK_PP(VM_PAGE_TO_PP(ptp));
-       ptp->uanon = NULL;
-}
-
-/*
- * pmap_ptp_range_set: abuse ptp->uanon to record minimum VA of PTE
- */
-static inline void
-pmap_ptp_range_set(struct vm_page *ptp, vaddr_t va)
-{
-       vaddr_t *min = (vaddr_t *)&ptp->uanon;
-
-       if (va < *min) {
-               *min = va;
-       }
-}
-
-/*
- * pmap_ptp_range_clip: abuse ptp->uanon to clip range of PTEs to remove
- */
-static inline void
-pmap_ptp_range_clip(struct vm_page *ptp, vaddr_t *startva, pt_entry_t **pte)
-{
-       vaddr_t sclip;
-
-       if (ptp == NULL) {
-               return;
-       }
-
-       sclip = (vaddr_t)ptp->uanon;
-       sclip = (*startva < sclip ? sclip : *startva);
-       *pte += (sclip - *startva) / PAGE_SIZE;
-       *startva = sclip;
-}
-
-/*
  * pmap_map_ptes: map a pmap's PTEs into KVM and lock them in
  *
  * there are several pmaps involved.  some or all of them might be same.
@@ -741,9 +656,7 @@
                 * often the case during exit(), when we have switched
                 * to the kernel pmap in order to destroy a user pmap.
                 */
-               if (__predict_false(ci->ci_tlbstate != TLBSTATE_VALID)) {
-                       pmap_reactivate(pmap);
-               }
+               pmap_reactivate(pmap);
                *pmap2 = NULL;
        } else {



Home | Main Index | Thread Index | Old Index