Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86/x86 - pmap_extract(): This needs to take the pm...



details:   https://anonhg.NetBSD.org/src/rev/43531c438cdc
branches:  trunk
changeset: 746041:43531c438cdc
user:      ad <ad%NetBSD.org@localhost>
date:      Fri Mar 20 19:06:14 2020 +0000

description:
- pmap_extract(): This needs to take the pmap's lock, to allow for
  concurrent removal of pages (a new requirement).

- pmap_remove_pv(): Keep hold time of pp_lock as short as possible.

- pmap_get_ptp(): Don't re-init struct pmap_page for PD PTPs.  Would
  have no ill effects but is wrong regardless.

diffstat:

 sys/arch/x86/x86/pmap.c |  49 +++++++++++++++----------------------------------
 1 files changed, 15 insertions(+), 34 deletions(-)

diffs (117 lines):

diff -r e9170f9396ac -r 43531c438cdc sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Fri Mar 20 19:03:13 2020 +0000
+++ b/sys/arch/x86/x86/pmap.c   Fri Mar 20 19:06:14 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.378 2020/03/19 18:58:14 ad Exp $    */
+/*     $NetBSD: pmap.c,v 1.379 2020/03/20 19:06:14 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.378 2020/03/19 18:58:14 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.379 2020/03/20 19:06:14 ad Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -2163,20 +2163,22 @@
 
        pmap_check_pv(pmap, ptp, pp, va, true);
 
-       mutex_spin_enter(&pp->pp_lock);
-       pp->pp_attrs |= oattrs;
        if (pve == NULL) {
+               mutex_spin_enter(&pp->pp_lock);
                KASSERT(pp->pp_pte.pte_ptp == ptp);
                KASSERT(pp->pp_pte.pte_va == va);
+               pp->pp_attrs |= oattrs;
                pp->pp_pte.pte_ptp = NULL;
                pp->pp_pte.pte_va = 0;
                mutex_spin_exit(&pp->pp_lock);
        } else {
+               mutex_spin_enter(&pp->pp_lock);
                KASSERT(pp->pp_pte.pte_ptp != ptp ||
                    pp->pp_pte.pte_va != va);
                KASSERT(pve->pve_pte.pte_ptp == ptp);
                KASSERT(pve->pve_pte.pte_va == va);
                KASSERT(pve->pve_pp == pp);
+               pp->pp_attrs |= oattrs;
                LIST_REMOVE(pve, pve_list);
                mutex_spin_exit(&pp->pp_lock);
 
@@ -2347,7 +2349,7 @@
                if (pt->pg[i] == NULL) {
                        pmap_unget_ptp(pmap, pt);
                        return ENOMEM;
-               } else {
+               } else if (pt->alloced[i]) {
                        pt->pg[i]->uanon = (struct vm_anon *)(vaddr_t)~0L;
                        rb_tree_init(&VM_PAGE_TO_PP(pt->pg[i])->pp_rb,
                            &pmap_rbtree_ops);
@@ -3427,10 +3429,8 @@
        pd_entry_t pde;
        pd_entry_t * const *pdes;
        struct pmap *pmap2;
-       struct cpu_info *ci;
        paddr_t pa;
-       lwp_t *l;
-       bool hard, rv;
+       bool rv;
        int lvl;
 
        if (__predict_false(pmap->pm_extract != NULL)) {
@@ -3448,29 +3448,11 @@
 
        rv = false;
        pa = 0;
-       l = curlwp;
-
-       ci = l->l_cpu;
-       if (pmap == pmap_kernel() ||
-           __predict_true(!ci->ci_want_pmapload && ci->ci_pmap == pmap)) {
-               /*
-                * no need to lock, because it's pmap_kernel() or our
-                * own pmap and is active.  if a user pmap, the caller
-                * will hold the vm_map write/read locked and so prevent
-                * entries from disappearing while we are here.  ptps
-                * can disappear via pmap_remove() and pmap_protect(),
-                * but they are called with the vm_map write locked.
-                */
-               hard = false;
-               ptes = PTE_BASE;
-               pdes = normal_pdes;
-               kpreempt_disable();
-       } else {
-               /* we lose, do it the hard way. */
-               hard = true;
+
+       if (pmap != pmap_kernel()) {
                mutex_enter(&pmap->pm_lock);
-               pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);
-       }
+       }
+       pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);
        if (pmap_pdes_valid(va, pdes, &pde, &lvl)) {
                if (lvl == 2) {
                        pa = (pde & PTE_LGFRAME) | (va & (NBPD_L2 - 1));
@@ -3484,15 +3466,14 @@
                        }
                }
        }
-       if (__predict_false(hard)) {
-               pmap_unmap_ptes(pmap, pmap2);
+       pmap_unmap_ptes(pmap, pmap2);
+       if (pmap != pmap_kernel()) {
                mutex_exit(&pmap->pm_lock);
-       } else {
-               kpreempt_enable();
        }
        if (pap != NULL) {
                *pap = pa;
        }
+
        return rv;
 }
 



Home | Main Index | Thread Index | Old Index