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/03d61136ecd9
branches: trunk
changeset: 970326:03d61136ecd9
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 3055abc1d177 -r 03d61136ecd9 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