Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/alpha/alpha Fix some major locking protocol issues ...



details:   https://anonhg.NetBSD.org/src/rev/aa020291f9ea
branches:  trunk
changeset: 473218:aa020291f9ea
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue May 25 20:32:29 1999 +0000

description:
Fix some major locking protocol issues related to pmap_kremove() having
to deal with PG_PVLIST mappings; it no longer has to.  Add some DIAGNOSTIC
checks for inconsistent use of pmap_enter/pmap_kremove.

diffstat:

 sys/arch/alpha/alpha/pmap.c |  98 ++++++++++++++++++++++++++++++--------------
 1 files changed, 67 insertions(+), 31 deletions(-)

diffs (170 lines):

diff -r 6270b4bdc5d6 -r aa020291f9ea sys/arch/alpha/alpha/pmap.c
--- a/sys/arch/alpha/alpha/pmap.c       Tue May 25 20:30:08 1999 +0000
+++ b/sys/arch/alpha/alpha/pmap.c       Tue May 25 20:32:29 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.100 1999/05/24 20:11:58 thorpej Exp $ */
+/* $NetBSD: pmap.c,v 1.101 1999/05/25 20:32:29 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -155,7 +155,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.100 1999/05/24 20:11:58 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.101 1999/05/25 20:32:29 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -481,10 +481,6 @@
 boolean_t pmap_remove_mapping __P((pmap_t, vaddr_t, pt_entry_t *,
            boolean_t, long, struct pv_entry **));
 void   pmap_changebit __P((paddr_t, pt_entry_t, pt_entry_t, long));
-#ifndef PMAP_NEW
-/* It's an interface function if PMAP_NEW. */
-void   pmap_kremove __P((vaddr_t, vsize_t));
-#endif
 
 /*
  * PT page management functions.
@@ -1276,11 +1272,42 @@
                return;
 
        /*
-        * If this is the kernel pmap, use a faster routine that
-        * can make some assumptions.
+        * If this is the kernel pmap, we can use a faster method
+        * for accessing the PTEs (since the PT pages are always
+        * resident).
+        *
+        * Note that this routine should NEVER be called from an
+        * interrupt context; pmap_kremove() is used for that.
         */
        if (pmap == pmap_kernel()) {
-               pmap_kremove(sva, eva - sva);
+               PMAP_MAP_TO_HEAD_LOCK();
+               PMAP_LOCK(pmap, ps);
+
+               while (sva < eva) {
+                       l3pte = PMAP_KERNEL_PTE(sva);
+                       if (pmap_pte_v(l3pte)) {
+#ifdef DIAGNOSTIC
+                               if (PAGE_IS_MANAGED(pmap_pte_pa(l3pte)) &&
+                                   pmap_pte_pv(l3pte) == 0)
+                                       panic("pmap_remove: managed page "
+                                           "without PG_PVLIST for 0x%lx",
+                                           sva);
+#endif
+                               needisync |= pmap_remove_mapping(pmap, sva,
+                                   l3pte, TRUE, cpu_id, NULL);
+                       }
+                       sva += PAGE_SIZE;
+               }
+
+               PMAP_UNLOCK(pmap, ps);
+               PMAP_MAP_TO_HEAD_UNLOCK();
+
+               if (needisync) {
+                       alpha_pal_imb();
+#if defined(MULTIPROCESSOR) && 0
+                       alpha_broadcast_ipi(ALPHA_IPI_IMB);
+#endif
+               }
                return;
        }
 
@@ -1880,9 +1907,9 @@
         * Invalidate the TLB entry for this VA and any appropriate
         * caches.
         */
-       PMAP_INVALIDATE_TLB(pmap_kernel(), va, TRUE, TRUE, cpu_id);
+       PMAP_INVALIDATE_TLB(pmap, va, TRUE, TRUE, cpu_id);
 #if defined(MULTIPROCESSOR) && 0
-       pmap_tlb_shootdown(pmap_kernel(), va, PG_ASM);
+       pmap_tlb_shootdown(pmap, va, PG_ASM);
 #endif
        if (needisync) {
                alpha_pal_imb();
@@ -1920,15 +1947,12 @@
                    VM_PAGE_TO_PHYS(pgs[i]),
                    VM_PROT_READ|VM_PROT_WRITE);
 }
-#endif /* PMAP_NEW */
 
 /*
  * pmap_kremove:               [ INTERFACE ]
  *
  *     Remove a mapping entered with pmap_kenter_pa() or pmap_kenter_pgs()
  *     starting at va, for size bytes (assumed to be page rounded).
- *
- *     NOTE: THIS IS AN INTERNAL FUNCTION IF NOT PMAP_NEW.
  */
 void
 pmap_kremove(va, size)
@@ -1939,7 +1963,7 @@
        boolean_t needisync = FALSE;
        long cpu_id = alpha_pal_whami();
        pmap_t pmap = pmap_kernel();
-       int s;
+       int ps;
 
 #ifdef DEBUG
        if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
@@ -1952,29 +1976,41 @@
                panic("pmap_kremove: user address");
 #endif
 
-       /*
-        * XXX WE MUST FIND AND FIX WHY WE ARE CALLED TO REMOVE MAPPINGS
-        * XXX WITH PG_PVENT SET!
-        */
-
-       s = splimp();
-       PMAP_MAP_TO_HEAD_LOCK();
-       simple_lock(&pmap->pm_slock);
+       PMAP_LOCK(pmap, ps);
 
        for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) {
                pte = PMAP_KERNEL_PTE(va);
-               if (pmap_pte_v(pte))
-                       needisync |= pmap_remove_mapping(pmap, va, pte,
-                           TRUE, cpu_id, NULL);
+               if (pmap_pte_v(pte)) {
+#ifdef DIAGNOSTIC
+                       if (pmap_pte_pv(pte))
+                               panic("pmap_kremove: PG_PVLIST mapping for "
+                                   "0x%lx", va);
+#endif
+                       if (pmap_pte_exec(pte))
+                               needisync = TRUE;
+
+                       /* Zap the mapping. */
+                       *pte = PG_NV;
+                       PMAP_INVALIDATE_TLB(pmap, va, TRUE, TRUE, cpu_id);
+#if defined(MULTIPROCESSOR) && 0
+                       pmap_tlb_shootdown(pmap, va, PG_ASM);
+#endif
+                       /* Update stats. */
+                       pmap->pm_stats.resident_count--;
+                       pmap->pm_stats.wired_count--;
+               }
        }
 
-       if (needisync)
+       PMAP_UNLOCK(pmap, ps);
+
+       if (needisync) {
                alpha_pal_imb();
-
-       simple_unlock(&pmap->pm_slock);
-       PMAP_MAP_TO_HEAD_UNLOCK();
-       splx(s);
+#if defined(MULTIPROCESSOR) && 0
+               alpha_broadcast_ipi(ALPHA_IPI_IMB);
+#endif
+       }
 }
+#endif /* PMAP_NEW */
 
 /*
  * pmap_change_wiring:         [ INTERFACE ]



Home | Main Index | Thread Index | Old Index