Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc/sparc * Allow pv_link4_4c() to fail with ENOM...



details:   https://anonhg.NetBSD.org/src/rev/7834e29f1b8b
branches:  trunk
changeset: 565341:7834e29f1b8b
user:      pk <pk%NetBSD.org@localhost>
date:      Sun Apr 04 18:34:35 2004 +0000

description:
* Allow pv_link4_4c() to fail with ENOMEM on pool allocation failures
  (catching up with pv_link4m()).
* Fix return code checking for pv_link4m() calls.
* Add low water setting to pv pool.

diffstat:

 sys/arch/sparc/sparc/pmap.c |  157 +++++++++++++++++++++++++++----------------
 1 files changed, 98 insertions(+), 59 deletions(-)

diffs (truncated from 314 to 300 lines):

diff -r 88bb6c986e49 -r 7834e29f1b8b sys/arch/sparc/sparc/pmap.c
--- a/sys/arch/sparc/sparc/pmap.c       Sun Apr 04 18:24:22 2004 +0000
+++ b/sys/arch/sparc/sparc/pmap.c       Sun Apr 04 18:34:35 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.277 2004/04/03 23:11:14 pk Exp $ */
+/*     $NetBSD: pmap.c,v 1.278 2004/04/04 18:34:35 pk Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.277 2004/04/03 23:11:14 pk Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.278 2004/04/04 18:34:35 pk Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -556,7 +556,7 @@
                                  int, struct vm_page *, int);
 /*static*/ void pv_changepte4_4c(struct vm_page *, int, int);
 /*static*/ int  pv_syncflags4_4c(struct vm_page *);
-/*static*/ int  pv_link4_4c(struct vm_page *, struct pmap *, vaddr_t, int);
+/*static*/ int  pv_link4_4c(struct vm_page *, struct pmap *, vaddr_t, u_int *);
 /*static*/ void pv_unlink4_4c(struct vm_page *, struct pmap *, vaddr_t);
 #endif
 
@@ -2578,8 +2578,12 @@
        } else {
                struct pvlist *prev;
 
+               pmap_stats.ps_unlink_pvsearch++;
                for (prev = pv0;; prev = npv, npv = npv->pv_next) {
-                       pmap_stats.ps_unlink_pvsearch++;
+                       if (npv == NULL) {
+                               panic("pv_unlink: pm %p is missing on pg %p",
+                                       pm, pg);
+                       }
                        if (npv->pv_pmap == pm && npv->pv_va == va)
                                break;
                }
@@ -2606,17 +2610,16 @@
  * be cached.
  */
 /*static*/ int
-pv_link4_4c(pg, pm, va, nc)
+pv_link4_4c(pg, pm, va, pteprotop)
        struct vm_page *pg;
        struct pmap *pm;
        vaddr_t va;
-       int nc;
-{
-       struct pvlist *pv0, *npv;
-       int ret;
+       unsigned int *pteprotop;
+{
+       struct pvlist *pv0, *pv, *npv;
+       int nc = (*pteprotop & PG_NC) != 0 ? PV_NC : 0;
 
        pv0 = VM_MDPAGE_PVHEAD(pg);
-       ret = nc ? PG_NC : 0;
 
        if (pv0->pv_pmap == NULL) {
                /* no pvlist entries yet */
@@ -2624,55 +2627,66 @@
                pv0->pv_next = NULL;
                pv0->pv_pmap = pm;
                pv0->pv_va = va;
-               pv0->pv_flags |= nc ? PV_NC : 0;
-               return (ret);
-       }
+               pv0->pv_flags |= nc;
+               return (0);
+       }
+
+       /*
+        * Allocate the new PV entry now, and, if that fails, bail out 
+        * before changing the cacheable state of the existing mappings.
+        */
+       npv = pool_get(&pv_pool, PR_NOWAIT);
+       if (npv == NULL)
+               return (ENOMEM);
+
+       pmap_stats.ps_enter_secondpv++;
+
        /*
         * Before entering the new mapping, see if
         * it will cause old mappings to become aliased
         * and thus need to be `discached'.
         */
-       pmap_stats.ps_enter_secondpv++;
        if (pv0->pv_flags & PV_ANC) {
                /* already uncached, just stay that way */
-               ret = PG_NC;
-       } else {
-               for (npv = pv0; npv != NULL; npv = npv->pv_next) {
-                       if (npv->pv_flags & PV_NC) {
-                               ret = PG_NC;
-#ifdef DEBUG
-                               /* Check currently illegal condition */
-                               if (nc == 0)
-                                       printf("pv_link: proc %s, va=0x%lx: "
-                               "unexpected uncached mapping at 0x%lx\n",
-                                           curproc ? curproc->p_comm : "--",
-                                           va, npv->pv_va);
-#endif
-                       }
-                       if (BADALIAS(va, npv->pv_va)) {
+               *pteprotop |= PG_NC;
+               goto link_npv;
+       }
+
+       for (pv = pv0; pv != NULL; pv = pv->pv_next) {
+               if ((pv->pv_flags & PV_NC) != 0) {
+                       *pteprotop |= PG_NC;
 #ifdef DEBUG
-                               if (pmapdebug & PDB_CACHESTUFF)
-                                       printf(
-                       "pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pv %p\n",
-                                       curproc ? curproc->p_comm : "--",
-                                       va, npv->pv_va, pg);
-#endif
-                               /* Mark list head `uncached due to aliases' */
-                               pv0->pv_flags |= PV_ANC;
-                               pv_changepte4_4c(pg, ret = PG_NC, 0);
-                               break;
-                       }
+                       /* Check currently illegal condition */
+                       if (nc == 0)
+                               printf("pv_link: proc %s, va=0x%lx: "
+                               "unexpected uncached mapping at 0x%lx\n",
+                                   curproc ? curproc->p_comm : "--",
+                                   va, pv->pv_va);
+#endif
                }
-       }
-       npv = pool_get(&pv_pool, PR_NOWAIT);
-       if (npv == NULL)
-               panic("pv_link: pv_pool exhausted");
+               if (BADALIAS(va, pv->pv_va)) {
+#ifdef DEBUG
+                       if (pmapdebug & PDB_CACHESTUFF)
+                               printf(
+                       "pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pg %p\n",
+                               curproc ? curproc->p_comm : "--",
+                               va, pv->pv_va, pg);
+#endif
+                       /* Mark list head `uncached due to aliases' */
+                       pv0->pv_flags |= PV_ANC;
+                       pv_changepte4_4c(pg, PG_NC, 0);
+                       *pteprotop |= PG_NC;
+                       break;
+               }
+       }
+
+link_npv:
        npv->pv_next = pv0->pv_next;
        npv->pv_pmap = pm;
        npv->pv_va = va;
-       npv->pv_flags = nc ? PV_NC : 0;
+       npv->pv_flags = nc;
        pv0->pv_next = npv;
-       return (ret);
+       return (0);
 }
 
 #endif /* SUN4 || SUN4C */
@@ -2867,13 +2881,13 @@
        } else {
                struct pvlist *prev;
 
+               pmap_stats.ps_unlink_pvsearch++;
                for (prev = pv0;; prev = npv, npv = npv->pv_next) {
                        if (npv == NULL) {
-                               panic("pm %p is missing ", pm);
-                               printf("pm %p is missing ", pm);
+                               panic("pv_unlink: pm %p is missing on pg %p",
+                                       pm, pg);
                                goto out;
                        }
-                       pmap_stats.ps_unlink_pvsearch++;
                        if (npv->pv_pmap == pm && npv->pv_va == va)
                                break;
                }
@@ -2935,8 +2949,6 @@
                goto out;
        }
 
-       pmap_stats.ps_enter_secondpv++;
-
        /*
         * Allocate the new PV entry now, and, if that fails, bail out 
         * before changing the cacheable state of the existing mappings.
@@ -2947,6 +2959,8 @@
                goto out;
        }
 
+       pmap_stats.ps_enter_secondpv++;
+
        /*
         * See if the new mapping will cause old mappings to
         * become aliased and thus need to be `discached'.
@@ -2995,7 +3009,7 @@
 
 out:
        simple_unlock(&pg->mdpage.pv_slock);
-       return (0);
+       return (error);
 }
 #endif
 
@@ -4371,6 +4385,11 @@
        }
 #endif /* SUN4M || SUN4D */
 
+       /* XXX - a peculiar place to do this, but we can't do it in pmap_init
+        * and here at least it's off the beaten code track.
+        */
+{static int x; if (x == 0) pool_setlowat(&pv_pool, 512), x = 1; }
+
        return (0);
 }
 
@@ -5698,6 +5717,7 @@
        int *ptep;
        struct regmap *rp;
        struct segmap *sp;
+       int error = 0;
 
        vr = VA_VREG(va);
        vs = VA_VSEG(va);
@@ -5738,6 +5758,9 @@
                                cache_flush_page(va, 0);
                        }
                }
+               *ptep = 0;
+               if (inmmu)
+                       setpte4(va, 0);
                if (pte & PG_WIRED)
                        sp->sg_nwired--;
                pm->pm_stats.resident_count--;
@@ -5759,8 +5782,13 @@
        /*
         * If the new mapping is for a managed PA, enter into pvlist.
         */
-       if (pg != NULL)
-               pteproto |= pv_link4_4c(pg, pm, va, pteproto & PG_NC);
+       if (pg != NULL && (error = pv_link4_4c(pg, pm, va, &pteproto)) != 0) {
+               if (--sp->sg_npte == 0)
+                       pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs);
+               if ((flags & PMAP_CANFAIL) != 0)
+                       goto out;
+               panic("pmap_enter: cannot allocate PV entry");
+       }
 
        /* Update S/W page table */
        *ptep = pteproto;
@@ -5781,8 +5809,9 @@
 
        /* Update H/W page table */
        setpte4(va, pteproto & ~PG_MBZ);
+out:
        splx(s);
-       return (0);
+       return (error);
 }
 
 /* enter new (or change existing) user mapping */
@@ -5928,6 +5957,9 @@
                        if (pte & PG_WIRED)
                                sp->sg_nwired--;
                        pm->pm_stats.resident_count--;
+                       ptep[VA_VPG(va)] = 0;
+                       if (sp->sg_pmeg != seginval)
+                               setpte4(va, 0);
                } else {
                        /* adding new entry */
                        sp->sg_npte++;
@@ -5940,8 +5972,15 @@
                }
        }
 
-       if (pg != NULL)
-               pteproto |= pv_link4_4c(pg, pm, va, pteproto & PG_NC);
+       if (pg != NULL && (error = pv_link4_4c(pg, pm, va, &pteproto)) != 0) {
+               if (--sp->sg_npte == 0)
+                       /* Sigh, undo pgt allocations */
+                       pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs);
+
+               if ((flags & PMAP_CANFAIL) != 0)
+                       goto out;
+               panic("pmap_enter: cannot allocate PV entry");
+       }
 
        /* Update S/W page table */
        ptep += VA_VPG(va);
@@ -6368,7 +6407,7 @@
        /*
         * If the new mapping is for a managed PA, enter into pvlist.
         */



Home | Main Index | Thread Index | Old Index