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