Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Work around the problem that causes kern/12554. Ba...
details: https://anonhg.NetBSD.org/src/rev/2f07c82ad6c7
branches: trunk
changeset: 509056:2f07c82ad6c7
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Apr 25 16:18:24 2001 +0000
description:
Work around the problem that causes kern/12554. Basically,
there are some pathological cases that cause pmap_page_protect()
to be called on a wired page to revoke all mappings. We
need to skip mappings that are actually wired to prevent Bad
things from happening later.
THIS IS JUST A WORK-AROUND. We need to prevent the pathological
behavior from happening in UVM to begin with. But it's unclear
what the right solution is there, right now.
diffstat:
sys/arch/i386/i386/pmap.c | 24 ++++++++++++++++++++----
sys/arch/pc532/pc532/pmap.c | 23 +++++++++++++++++++----
sys/arch/sh3/sh3/pmap.c | 23 +++++++++++++++++++----
3 files changed, 58 insertions(+), 12 deletions(-)
diffs (178 lines):
diff -r 0e294b35678c -r 2f07c82ad6c7 sys/arch/i386/i386/pmap.c
--- a/sys/arch/i386/i386/pmap.c Wed Apr 25 14:59:44 2001 +0000
+++ b/sys/arch/i386/i386/pmap.c Wed Apr 25 16:18:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.121 2001/04/24 04:30:58 thorpej Exp $ */
+/* $NetBSD: pmap.c,v 1.122 2001/04/25 16:18:24 thorpej Exp $ */
/*
*
@@ -2297,7 +2297,7 @@
{
int bank, off;
struct pv_head *pvh;
- struct pv_entry *pve;
+ struct pv_entry *pve, *npve, **prevptr, *killlist = NULL;
pt_entry_t *ptes, opte;
#if defined(I386_CPU)
boolean_t needs_update = FALSE;
@@ -2321,7 +2321,9 @@
/* XXX: needed if we hold head->map lock? */
simple_lock(&pvh->pvh_lock);
- for (pve = pvh->pvh_list ; pve != NULL ; pve = pve->pv_next) {
+ for (prevptr = &pvh->pvh_list, pve = pvh->pvh_list;
+ pve != NULL; pve = npve) {
+ npve = pve->pv_next;
ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */
#ifdef DIAGNOSTIC
@@ -2343,6 +2345,17 @@
#endif
opte = ptes[i386_btop(pve->pv_va)];
+#if 1 /* XXX Work-around for kern/12554. */
+ if (opte & PG_W) {
+#ifdef DEBUG
+ printf("pmap_page_remove: wired mapping for "
+ "0x%lx (wire count %d) not removed\n",
+ VM_PAGE_TO_PHYS(pg), pg->wire_count);
+#endif
+ prevptr = &pve->pv_next;
+ continue;
+ }
+#endif /* kern/12554 */
ptes[i386_btop(pve->pv_va)] = 0; /* zap! */
if (opte & PG_W)
@@ -2382,8 +2395,11 @@
}
}
pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
+ *prevptr = npve; /* remove it */
+ pve->pv_next = killlist; /* mark it for death */
+ killlist = pve;
}
- pmap_free_pvs(NULL, pvh->pvh_list);
+ pmap_free_pvs(NULL, killlist);
pvh->pvh_list = NULL;
simple_unlock(&pvh->pvh_lock);
PMAP_HEAD_TO_MAP_UNLOCK();
diff -r 0e294b35678c -r 2f07c82ad6c7 sys/arch/pc532/pc532/pmap.c
--- a/sys/arch/pc532/pc532/pmap.c Wed Apr 25 14:59:44 2001 +0000
+++ b/sys/arch/pc532/pc532/pmap.c Wed Apr 25 16:18:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.58 2001/04/24 04:31:06 thorpej Exp $ */
+/* $NetBSD: pmap.c,v 1.59 2001/04/25 16:18:25 thorpej Exp $ */
/*
*
@@ -2081,7 +2081,7 @@
{
int bank, off;
struct pv_head *pvh;
- struct pv_entry *pve;
+ struct pv_entry *pve, *npve, **prevptr, *killlist = NULL;
pt_entry_t *ptes, opte;
/* XXX: vm_page should either contain pv_head or have a pointer to it */
@@ -2102,7 +2102,8 @@
/* XXX: needed if we hold head->map lock? */
simple_lock(&pvh->pvh_lock);
- for (pve = pvh->pvh_list ; pve != NULL ; pve = pve->pv_next) {
+ for (prevptr = &pvh->pvh_list, pve = pvh->pvh_list;
+ pve != NULL; pve = npve) {
ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */
#ifdef DIAGNOSTIC
@@ -2124,6 +2125,17 @@
#endif
opte = ptes[ns532_btop(pve->pv_va)];
+#if 1 /* XXX Work-around for kern/12554. */
+ if (opte & PG_W) {
+#ifdef DEBUG
+ printf("pmap_page_remove: wired mapping for "
+ "0x%lx (wire count %d) not removed\n",
+ VM_PAGE_TO_PHYS(pg), pg->wire_count);
+#endif
+ prevptr = &pve->pv_next;
+ continue;
+ }
+#endif /* kern/12554 */
ptes[ns532_btop(pve->pv_va)] = 0; /* zap! */
if (opte & PG_W)
@@ -2155,8 +2167,11 @@
}
}
pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
+ *prevptr = npve; /* remove it */
+ pve->pv_next = killlist; /* mark it for death */
+ killlist = pve;
}
- pmap_free_pvs(NULL, pvh->pvh_list);
+ pmap_free_pvs(NULL, killlist);
pvh->pvh_list = NULL;
simple_unlock(&pvh->pvh_lock);
PMAP_HEAD_TO_MAP_UNLOCK();
diff -r 0e294b35678c -r 2f07c82ad6c7 sys/arch/sh3/sh3/pmap.c
--- a/sys/arch/sh3/sh3/pmap.c Wed Apr 25 14:59:44 2001 +0000
+++ b/sys/arch/sh3/sh3/pmap.c Wed Apr 25 16:18:24 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.18 2001/04/24 04:31:09 thorpej Exp $ */
+/* $NetBSD: pmap.c,v 1.19 2001/04/25 16:18:26 thorpej Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -2210,7 +2210,7 @@
{
int bank, off;
struct pv_head *pvh;
- struct pv_entry *pve;
+ struct pv_entry *pve, *npve, **prevptr, *killlist = NULL;
pt_entry_t *ptes, opte;
/* XXX: vm_page should either contain pv_head or have a pointer to it */
@@ -2231,7 +2231,8 @@
/* XXX: needed if we hold head->map lock? */
simple_lock(&pvh->pvh_lock);
- for (pve = pvh->pvh_list ; pve != NULL ; pve = pve->pv_next) {
+ for (prevptr = &pvh->pvh_list, pve = pvh->pvh_list;
+ pve != NULL; pve = npve) {
ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */
#ifdef DIAGNOSTIC
@@ -2250,6 +2251,17 @@
#endif
opte = ptes[sh3_btop(pve->pv_va)];
+#if 1 /* XXX Work-around for kern/12554. */
+ if (opte & PG_W) {
+#ifdef DEBUG
+ printf("pmap_page_remove: wired mapping for "
+ "0x%lx (wire count %d) not removed\n",
+ VM_PAGE_TO_PHYS(pg), pg->wire_count);
+#endif
+ prevptr = &pve->pv_next;
+ continue;
+ }
+#endif /* kern/12554 */
ptes[sh3_btop(pve->pv_va)] = 0; /* zap! */
if (opte & PG_W)
@@ -2281,8 +2293,11 @@
}
}
pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
+ *prevptr = npve; /* remove it */
+ pve->pv_next = killlist; /* mark it for death */
+ killlist = pve;
}
- pmap_free_pvs(NULL, pvh->pvh_list);
+ pmap_free_pvs(NULL, killlist);
pvh->pvh_list = NULL;
simple_unlock(&pvh->pvh_lock);
PMAP_HEAD_TO_MAP_UNLOCK();
Home |
Main Index |
Thread Index |
Old Index