Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/rmind-uvmplock]: src/sys/arch/x86/x86 - pmap_remove_ptes: simplify by re...
details: https://anonhg.NetBSD.org/src/rev/3278c1cd16aa
branches: rmind-uvmplock
changeset: 753073:3278c1cd16aa
user: rmind <rmind%NetBSD.org@localhost>
date: Tue Mar 08 20:07:30 2011 +0000
description:
- pmap_remove_ptes: simplify by removing the duplicate code and re-using
equivalent functionality in pmap_remove_pte().
- pmap_remove_pte: fix assert to allow page owner lock to be unacquired
if pmap is pmap_kernel(); relevant for UVM_KMF_PAGEABLE memory case.
diffstat:
sys/arch/x86/x86/pmap.c | 154 ++++++++++++++---------------------------------
1 files changed, 46 insertions(+), 108 deletions(-)
diffs (258 lines):
diff -r 56787923b566 -r 3278c1cd16aa sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c Tue Mar 08 16:30:38 2011 +0000
+++ b/sys/arch/x86/x86/pmap.c Tue Mar 08 20:07:30 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.105.2.10 2011/03/05 20:52:31 rmind Exp $ */
+/* $NetBSD: pmap.c,v 1.105.2.11 2011/03/08 20:07:30 rmind Exp $ */
/*-
* Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
@@ -171,7 +171,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.105.2.10 2011/03/05 20:52:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.105.2.11 2011/03/08 20:07:30 rmind Exp $");
#include "opt_user_ldt.h"
#include "opt_lockdebug.h"
@@ -3121,9 +3121,7 @@
pmap_remove_ptes(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva,
vaddr_t startva, vaddr_t endva, struct pv_entry **pv_tofree)
{
- struct pv_entry *pve;
- pt_entry_t *pte = (pt_entry_t *) ptpva;
- pt_entry_t opte;
+ pt_entry_t *pte = (pt_entry_t *)ptpva;
KASSERT(pmap == pmap_kernel() || mutex_owned(pmap->pm_lock));
KASSERT(kpreempt_disabled());
@@ -3136,74 +3134,16 @@
* and the wire_count is greater than 1 (because we use the wire_count
* to keep track of the number of real PTEs in the PTP).
*/
-
- for (/*null*/; startva < endva && (ptp == NULL || ptp->wire_count > 1)
- ; pte++, startva += PAGE_SIZE) {
- struct vm_page *pg;
- struct pmap_page *pp;
-
- if (!pmap_valid_entry(*pte))
- continue; /* VA not mapped */
-
- /* atomically save the old PTE and zap! it */
- opte = pmap_pte_testset(pte, 0);
- if (!pmap_valid_entry(opte)) {
- continue;
- }
-
- pmap_exec_account(pmap, startva, opte, 0);
- pmap_stats_update_bypte(pmap, 0, opte);
-
- if (ptp) {
- ptp->wire_count--; /* dropping a PTE */
- /* Make sure that the PDE is flushed */
- if (ptp->wire_count <= 1)
- opte |= PG_U;
- }
-
- if ((opte & PG_U) != 0) {
- pmap_tlb_shootdown(pmap, startva, opte,
- TLBSHOOT_REMOVE_PTES);
- }
-
- /*
- * if we are not on a pv_head list we are done.
- */
-
- if ((opte & PG_PVLIST) == 0) {
-#if defined(DIAGNOSTIC) && !defined(DOM0OPS)
- if (PHYS_TO_VM_PAGE(pmap_pte2pa(opte)) != NULL)
- panic("pmap_remove_ptes: managed page without "
- "PG_PVLIST for %#" PRIxVADDR, startva);
-#endif
- continue;
- }
-
- pg = PHYS_TO_VM_PAGE(pmap_pte2pa(opte));
-
- KASSERTMSG(pg != NULL, ("pmap_remove_ptes: unmanaged page "
- "marked PG_PVLIST, va = %#" PRIxVADDR ", pa = %#" PRIxPADDR,
- startva, (paddr_t)pmap_pte2pa(opte)));
-
- KASSERT(uvm_page_locked_p(pg));
-
- /* sync R/M bits */
- pp = VM_PAGE_TO_PP(pg);
- pp->pp_attrs |= opte;
- pve = pmap_remove_pv(pp, ptp, startva);
-
- if (pve != NULL) {
- pve->pve_next = *pv_tofree;
- *pv_tofree = pve;
- }
-
- /* end of "for" loop: time for next pte */
+ while (startva < endva && (ptp == NULL || ptp->wire_count > 1)) {
+ (void)pmap_remove_pte(pmap, ptp, pte, startva, pv_tofree);
+ startva += PAGE_SIZE;
+ pte++;
}
}
/*
- * pmap_remove_pte: remove a single PTE from a PTP
+ * pmap_remove_pte: remove a single PTE from a PTP.
*
* => caller must hold pmap's lock
* => PTP must be mapped into KVA
@@ -3211,23 +3151,24 @@
* => returns true if we removed a mapping
* => must be called with kernel preemption disabled
*/
-
static bool
pmap_remove_pte(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte,
vaddr_t va, struct pv_entry **pv_tofree)
{
- pt_entry_t opte;
struct pv_entry *pve;
struct vm_page *pg;
struct pmap_page *pp;
+ pt_entry_t opte;
KASSERT(pmap == pmap_kernel() || mutex_owned(pmap->pm_lock));
- KASSERT(pmap == pmap_kernel() || kpreempt_disabled());
-
- if (!pmap_valid_entry(*pte))
- return(false); /* VA not mapped */
-
- /* atomically save the old PTE and zap! it */
+ KASSERT(kpreempt_disabled());
+
+ if (!pmap_valid_entry(*pte)) {
+ /* VA not mapped. */
+ return false;
+ }
+
+ /* Atomically save the old PTE and zap it. */
opte = pmap_pte_testset(pte, 0);
if (!pmap_valid_entry(opte)) {
return false;
@@ -3237,10 +3178,13 @@
pmap_stats_update_bypte(pmap, 0, opte);
if (ptp) {
- ptp->wire_count--; /* dropping a PTE */
- /* Make sure that the PDE is flushed */
- if (ptp->wire_count <= 1)
+ /*
+ * Dropping a PTE. Make sure that the PDE is flushed.
+ */
+ ptp->wire_count--;
+ if (ptp->wire_count <= 1) {
opte |= PG_U;
+ }
}
if ((opte & PG_U) != 0) {
@@ -3248,16 +3192,15 @@
}
/*
- * if we are not on a pv_head list we are done.
+ * If we are not on a pv_head list - we are done.
*/
-
if ((opte & PG_PVLIST) == 0) {
#if defined(DIAGNOSTIC) && !defined(DOM0OPS)
if (PHYS_TO_VM_PAGE(pmap_pte2pa(opte)) != NULL)
panic("pmap_remove_pte: managed page without "
"PG_PVLIST for %#" PRIxVADDR, va);
#endif
- return(true);
+ return true;
}
pg = PHYS_TO_VM_PAGE(pmap_pte2pa(opte));
@@ -3266,9 +3209,9 @@
"PG_PVLIST, va = %#" PRIxVADDR ", pa = %#" PRIxPADDR,
va, (paddr_t)pmap_pte2pa(opte)));
- KASSERT(uvm_page_locked_p(pg));
-
- /* sync R/M bits */
+ KASSERT(pmap == pmap_kernel() || uvm_page_locked_p(pg));
+
+ /* Sync R/M bits. */
pp = VM_PAGE_TO_PP(pg);
pp->pp_attrs |= opte;
pve = pmap_remove_pv(pp, ptp, va);
@@ -3277,8 +3220,7 @@
pve->pve_next = *pv_tofree;
*pv_tofree = pve;
}
-
- return(true);
+ return true;
}
/*
@@ -3314,20 +3256,17 @@
/* PA of the PTP */
ptppa = pmap_pte2pa(pde);
- /* get PTP if non-kernel mapping */
- if (pmap == pmap_kernel()) {
- /* we never free kernel PTPs */
- ptp = NULL;
- } else {
+ /* Get PTP if non-kernel mapping. */
+ if (pmap != pmap_kernel()) {
ptp = pmap_find_ptp(pmap, va, ptppa, 1);
-#ifdef DIAGNOSTIC
- if (ptp == NULL)
- panic("pmap_remove: unmanaged "
- "PTP detected");
-#endif
+ KASSERTMSG(ptp != NULL,
+ ("pmap_remove: unmanaged PTP detected")
+ );
+ } else {
+ /* Never free kernel PTPs. */
+ ptp = NULL;
}
- /* do it! */
result = pmap_remove_pte(pmap, ptp,
&ptes[pl1_i(va)], va, &pv_tofree);
@@ -3379,18 +3318,17 @@
/* PA of the PTP */
ptppa = pmap_pte2pa(pde);
- /* get PTP if non-kernel mapping */
- if (pmap == pmap_kernel()) {
- /* we never free kernel PTPs */
- ptp = NULL;
- } else {
+ /* Get PTP if non-kernel mapping. */
+ if (pmap != pmap_kernel()) {
ptp = pmap_find_ptp(pmap, va, ptppa, 1);
-#ifdef DIAGNOSTIC
- if (ptp == NULL)
- panic("pmap_remove: unmanaged PTP "
- "detected");
-#endif
+ KASSERTMSG(ptp != NULL,
+ ("pmap_remove: unmanaged PTP detected")
+ );
+ } else {
+ /* Never free kernel PTPs. */
+ ptp = NULL;
}
+
pmap_remove_ptes(pmap, ptp, (vaddr_t)&ptes[pl1_i(va)], va,
blkendva, &pv_tofree);
Home |
Main Index |
Thread Index |
Old Index