NetBSD-Bugs archive

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

Re: port-i386/37193 (x86 pmap concurrency strategy could use improvement)



The following reply was made to PR port-i386/37193; it has been noted by GNATS.

From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: port-i386-maintainer%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost,
        gnats-admin%NetBSD.org@localhost, ad%NetBSD.org@localhost, 
port-xen%NetBSD.org@localhost
Subject: Re: port-i386/37193 (x86 pmap concurrency strategy could use 
improvement)
Date: Fri, 11 Jan 2008 23:13:19 +0100

 --k1lZvvs/B4yU6o8G
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 On Thu, Jan 10, 2008 at 08:01:52PM +0900, YAMAMOTO Takashi wrote:
 > > Synopsis: x86 pmap concurrency strategy could use improvement
 > > 
 > > Responsible-Changed-From-To: port-i386-maintainer->yamt
 > > Responsible-Changed-By: yamt%netbsd.org@localhost
 > > Responsible-Changed-When: Wed, 09 Jan 2008 11:45:50 +0000
 > > Responsible-Changed-Why:
 > > i'll take a look.
 > 
 > here's a patch.  can anyone test it on xen+amd64?
 
 You can't map the ptp read/write on Xen. But with this issue fixed,
 it works fine. I used the attached patch on HEAD after the bouyer-xeni386
 merge.
 
 -- 
 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
      NetBSD: 26 ans d'experience feront toujours la difference
 --
 
 --k1lZvvs/B4yU6o8G
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename=diff
 
 Index: amd64/include/pmap.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/amd64/include/pmap.h,v
 retrieving revision 1.18
 diff -u -r1.18 pmap.h
 --- amd64/include/pmap.h       3 Jan 2008 19:30:10 -0000       1.18
 +++ amd64/include/pmap.h       11 Jan 2008 22:06:44 -0000
 @@ -257,6 +257,7 @@
  #define pmap_pa2pte(a)                        (a)
  #define pmap_pte2pa(a)                        ((a) & PG_FRAME)
  #define pmap_pte_set(p, n)            do { *(p) = (n); } while (0)
 +#define pmap_pte_cas(p, o, n)         atomic_cas_64((p), (o), (n))
  #define pmap_pte_testset(p, n)                \
      atomic_swap_ulong((volatile unsigned long *)p, n)
  #define pmap_pte_setbits(p, b)                \
 @@ -285,6 +286,20 @@
  }
  
  static __inline pt_entry_t
 +pmap_pte_cas(pt_entry_t *ptep, pt_entry_t o, pt_entry_t n)
 +{
 +      int s = splvm();
 +      pt_entry_t opte = *ptep;
 +
 +      if (opte == o) {
 +              xpq_queue_pte_update((pt_entry_t *)xpmap_ptetomach(ptep), n);
 +              xpq_flush_queue();
 +      }
 +      splx(s);
 +      return opte;
 +}
 +
 +static __inline pt_entry_t
  pmap_pte_testset(volatile pt_entry_t *pte, pt_entry_t npte)
  {
        int s = splvm();
 Index: i386/include/pmap.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/i386/include/pmap.h,v
 retrieving revision 1.98
 diff -u -r1.98 pmap.h
 --- i386/include/pmap.h        11 Jan 2008 20:00:15 -0000      1.98
 +++ i386/include/pmap.h        11 Jan 2008 22:07:02 -0000
 @@ -277,6 +277,7 @@
  #define pmap_pa2pte(a)                        (a)
  #define pmap_pte2pa(a)                        ((a) & PG_FRAME)
  #define pmap_pte_set(p, n)            do { *(p) = (n); } while (0)
 +#define pmap_pte_cas(p, o, n)         atomic_cas_32((p), (o), (n))
  #define pmap_pte_testset(p, n)                \
      atomic_swap_ulong((volatile unsigned long *)p, n)
  #define pmap_pte_setbits(p, b)                \
 @@ -305,6 +306,20 @@
  }
  
  static __inline pt_entry_t
 +pmap_pte_cas(pt_entry_t *ptep, pt_entry_t o, pt_entry_t n)
 +{
 +      int s = splvm();
 +      pt_entry_t opte = *ptep;
 +
 +      if (opte == o) {
 +              xpq_queue_pte_update((pt_entry_t *)xpmap_ptetomach(ptep), n);
 +              xpq_flush_queue();
 +      }
 +      splx(s);
 +      return opte;
 +}
 +
 +static __inline pt_entry_t
  pmap_pte_testset(volatile pt_entry_t *pte, pt_entry_t npte)
  {
        int s = splvm();
 Index: x86/x86/pmap.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/x86/x86/pmap.c,v
 retrieving revision 1.24
 diff -u -r1.24 pmap.c
 --- x86/x86/pmap.c     11 Jan 2008 20:00:17 -0000      1.24
 +++ x86/x86/pmap.c     11 Jan 2008 22:07:35 -0000
 @@ -346,7 +346,6 @@
  pd_entry_t *alternate_pdes[] = APDES_INITIALIZER;
  
  static kmutex_t pmaps_lock;
 -static krwlock_t pmap_main_lock;
  
  static vaddr_t pmap_maxkvaddr;
  
 @@ -557,6 +556,32 @@
   * p m a p   h e l p e r   f u n c t i o n s
   */
  
 +static inline void
 +pmap_stats_update(struct pmap *pmap, int resid_diff, int wired_diff)
 +{
 +
 +      if (pmap == pmap_kernel()) {
 +              atomic_add_long(&pmap->pm_stats.resident_count, resid_diff);
 +              atomic_add_long(&pmap->pm_stats.wired_count, wired_diff);
 +      } else {
 +              KASSERT(mutex_owned(&pmap->pm_lock));
 +              pmap->pm_stats.resident_count += resid_diff;
 +              pmap->pm_stats.wired_count += wired_diff;
 +      }
 +}
 +
 +static inline void
 +pmap_stats_update_bypte(struct pmap *pmap, pt_entry_t npte, pt_entry_t opte)
 +{
 +      int resid_diff = ((npte & PG_V) ? 1 : 0) - ((opte & PG_V) ? 1 : 0);
 +      int wired_diff = ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
 +
 +      KASSERT((npte & (PG_V | PG_W)) != PG_W);
 +      KASSERT((opte & (PG_V | PG_W)) != PG_W);
 +
 +      pmap_stats_update(pmap, resid_diff, wired_diff);
 +}
 +
  /*
   * pmap_is_curpmap: is this pmap the one currently loaded [in %cr3]?
   *            of course the kernel is always loaded
 @@ -1299,7 +1324,6 @@
         *      again is never taken from interrupt context.
         */
  
 -      rw_init(&pmap_main_lock);
        mutex_init(&pmaps_lock, MUTEX_DEFAULT, IPL_NONE);
        LIST_INIT(&pmaps);
        pmap_cpu_init_early(curcpu());
 @@ -1505,6 +1529,8 @@
              vaddr_t va,
              struct vm_page *ptp)      /* PTP in pmap that maps this VA */
  {
 +
 +      KASSERT(mutex_owned(&pvh->pvh_lock));
        pve->pv_pmap = pmap;
        pve->pv_va = va;
        pve->pv_ptp = ptp;                      /* NULL for kernel pmap */
 @@ -1526,6 +1552,7 @@
  {
        struct pv_entry tmp, *pve;
  
 +      KASSERT(mutex_owned(&pvh->pvh_lock));
        tmp.pv_pmap = pmap;
        tmp.pv_va = va;
        pve = SPLAY_FIND(pvtree, &pvh->pvh_root, &tmp);
 @@ -1569,7 +1596,7 @@
        lidx = level - 1;
  
        obj = &pmap->pm_obj[lidx];
 -      pmap->pm_stats.resident_count--;
 +      pmap_stats_update(pmap, -1, 0);
        if (lidx != 0)
                mutex_enter(&obj->vmobjlock);
        if (pmap->pm_ptphint[lidx] == ptp)
 @@ -1699,7 +1726,7 @@
                }
  #endif /* XEN && __x86_64__ */
                pmap_pte_flush();
 -              pmap->pm_stats.resident_count++;
 +              pmap_stats_update(pmap, 1, 0);
                /*
                 * If we're not in the top level, increase the
                 * wire count of the parent page.
 @@ -2502,6 +2529,7 @@
   
        pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);
        if (!pmap_pdes_valid(va, pdes, &pde)) {
 +              pmap_unmap_ptes(pmap, pmap2);
                return false;
        }
   
 @@ -2650,6 +2678,57 @@
  #endif
  }
  
 +static pt_entry_t *
 +pmap_map_ptp(struct vm_page *ptp)
 +{
 +      pt_entry_t *ptppte;
 +      void *ptpva;
 +      int id;
 +
 +      id = cpu_number();
 +      ptppte = PTESLEW(ptp_pte, id);
 +      ptpva = VASLEW(ptpp, id);
 +      pmap_pte_set(ptppte, pmap_pa2pte(VM_PAGE_TO_PHYS(ptp)) |
 +#ifdef XEN
 +          PG_V | PG_M | PG_U | PG_k);
 +#else
 +          PG_V | PG_RW | PG_M | PG_U | PG_k);
 +#endif
 +      pmap_pte_flush();
 +      pmap_update_pg((vaddr_t)ptpva);
 +
 +      return (pt_entry_t *)ptpva;
 +}
 +
 +static void
 +pmap_unmap_ptp(void)
 +{
 +#if defined(DIAGNOSTIC) || defined(XEN)
 +      pt_entry_t *pte;
 +
 +      pte = PTESLEW(ptp_pte, cpu_number());
 +      pmap_pte_set(pte, 0);
 +      pmap_pte_flush();
 +#endif
 +}
 +
 +static pt_entry_t *
 +pmap_map_pte(struct vm_page *ptp, vaddr_t va)
 +{
 +
 +      if (ptp == NULL) {
 +              return kvtopte(va);
 +      }
 +      return pmap_map_ptp(ptp) + pl1_pi(va);
 +}
 +
 +static void
 +pmap_unmap_pte(void)
 +{
 +
 +      pmap_unmap_ptp();
 +}
 +
  /*
   * p m a p   r e m o v e   f u n c t i o n s
   *
 @@ -2701,9 +2780,7 @@
                pmap_exec_account(pmap, startva, opte, 0);
                KASSERT(pmap_valid_entry(opte));
  
 -              if (opte & PG_W)
 -                      pmap->pm_stats.wired_count--;
 -              pmap->pm_stats.resident_count--;
 +              pmap_stats_update_bypte(pmap, 0, opte);
                xpte |= opte;
  
                if (ptp) {
 @@ -2784,9 +2861,7 @@
        pmap_exec_account(pmap, va, opte, 0);
        KASSERT(pmap_valid_entry(opte));
  
 -      if (opte & PG_W)
 -              pmap->pm_stats.wired_count--;
 -      pmap->pm_stats.resident_count--;
 +      pmap_stats_update_bypte(pmap, 0, opte);
  
        if (opte & PG_U)
                pmap_tlb_shootdown(pmap, va, 0, opte);
 @@ -2864,12 +2939,6 @@
        struct vm_page *ptp, *empty_ptps = NULL;
        struct pmap *pmap2;
  
 -      /*
 -       * we lock in the pmap => pv_head direction
 -       */
 -
 -      rw_enter(&pmap_main_lock, RW_READER);
 -
        pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);      /* locks pmap */
  
        /*
 @@ -2971,7 +3040,6 @@
        }
        pmap_tlb_shootwait();
        pmap_unmap_ptes(pmap, pmap2);           /* unlock pmap */
 -      rw_exit(&pmap_main_lock);
  
        /* Now we can free unused PVs and ptps */
        if (pv_tofree)
 @@ -2993,15 +3061,10 @@
  pmap_page_remove(struct vm_page *pg)
  {
        struct pv_head *pvh;
 -      struct pv_entry *pve, *npve, *killlist = NULL;
 -      pt_entry_t *ptes, opte;
 -      pd_entry_t **pdes;
 -#ifdef DIAGNOSTIC
 -      pd_entry_t pde;
 -#endif
 +      struct pv_entry *pve, *killlist = NULL;
        struct vm_page *empty_ptps = NULL;
        struct vm_page *ptp;
 -      struct pmap *pmap2;
 +      pt_entry_t expect;
  
  #ifdef DIAGNOSTIC
        int bank, off;
 @@ -3016,37 +3079,26 @@
                return;
        }
  
 -      /* set pv_head => pmap locking */
 -      rw_enter(&pmap_main_lock, RW_WRITER);
 -
 -      for (pve = SPLAY_MIN(pvtree, &pvh->pvh_root); pve != NULL; pve = npve) {
 -              npve = SPLAY_NEXT(pvtree, &pvh->pvh_root, pve);
 -
 -              /* locks pmap */
 -              pmap_map_ptes(pve->pv_pmap, &pmap2, &ptes, &pdes);
 -
 -#ifdef DIAGNOSTIC
 -              if (pve->pv_ptp && pmap_pdes_valid(pve->pv_va, pdes, &pde) &&
 -                 pmap_pte2pa(pde) != VM_PAGE_TO_PHYS(pve->pv_ptp)) {
 -                      printf("pmap_page_remove: pg=%p: va=%lx, pv_ptp=%p\n",
 -                             pg, pve->pv_va, pve->pv_ptp);
 -                      printf("pmap_page_remove: PTP's phys addr: "
 -                             "actual=%lx, recorded=%lx\n",
 -                             (unsigned long)pmap_pte2pa(pde),
 -                             (unsigned long)VM_PAGE_TO_PHYS(pve->pv_ptp));
 -                      panic("pmap_page_remove: mapped managed page has "
 -                            "invalid pv_ptp field");
 -              }
 -#endif
 +      expect = pmap_pa2pte(VM_PAGE_TO_PHYS(pg)) | PG_V;
 +retry:
 +      mutex_spin_enter(&pvh->pvh_lock);
 +      while ((pve = SPLAY_MIN(pvtree, &pvh->pvh_root)) != NULL) {
 +              struct pmap *pmap = pve->pv_pmap;
 +              pt_entry_t *ptep;
 +              pt_entry_t opte;
  
                /* atomically save the old PTE and zap! it */
 -              opte = pmap_pte_testset(&ptes[pl1_i(pve->pv_va)], 0);
 -              KASSERT(pmap_valid_entry(opte));
 -              KDASSERT(pmap_pte2pa(opte) == VM_PAGE_TO_PHYS(pg));
 -
 -              if (opte & PG_W)
 -                      pve->pv_pmap->pm_stats.wired_count--;
 -              pve->pv_pmap->pm_stats.resident_count--;
 +              ptep = pmap_map_pte(pve->pv_ptp, pve->pv_va);
 +              do {
 +                      opte = *ptep;
 +                      if ((opte & (PG_FRAME | PG_V)) != expect) {
 +                              pmap_unmap_pte();
 +                              mutex_spin_exit(&pvh->pvh_lock);
 +                              x86_pause();
 +                              goto retry;
 +                      }
 +              } while (pmap_pte_cas(ptep, opte, 0) != opte);
 +              pmap_unmap_pte();
  
                /* Shootdown only if referenced */
                if (opte & PG_U)
 @@ -3055,21 +3107,37 @@
                /* sync R/M bits */
                pg->mdpage.mp_attrs |= (opte & (PG_U|PG_M));
  
 +              if (pve->pv_ptp) {
 +                      pmap_reference(pmap);
 +              }
 +              SPLAY_REMOVE(pvtree, &pvh->pvh_root, pve); /* remove it */
 +              mutex_spin_exit(&pvh->pvh_lock);
 +
                /* update the PTP reference count.  free if last reference. */
                if (pve->pv_ptp) {
 +                      struct pmap *pmap2;
 +                      pt_entry_t *ptes;
 +                      pd_entry_t **pdes;
 +
 +                      KASSERT(pmap != pmap_kernel());
 +                      pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);
 +                      pmap_stats_update_bypte(pmap, 0, opte);
                        pve->pv_ptp->wire_count--;
                        if (pve->pv_ptp->wire_count <= 1) {
                                pmap_free_ptp(pve->pv_pmap, pve->pv_ptp,
                                    pve->pv_va, ptes, pdes, &empty_ptps);
                        }
 +                      pmap_unmap_ptes(pmap, pmap2);
 +                      pmap_destroy(pmap);
 +              } else {
 +                      pmap_stats_update_bypte(pmap, 0, opte);
                }
 -              
 -              pmap_unmap_ptes(pve->pv_pmap, pmap2);   /* unlocks pmap */
 -              SPLAY_REMOVE(pvtree, &pvh->pvh_root, pve); /* remove it */
 +
                SPLAY_RIGHT(pve, pv_node) = killlist;   /* mark it for death */
                killlist = pve;
 +              mutex_spin_enter(&pvh->pvh_lock);
        }
 -      rw_exit(&pmap_main_lock);
 +      mutex_spin_exit(&pvh->pvh_lock);
  
        crit_enter();
        pmap_tlb_shootwait();
 @@ -3103,8 +3171,8 @@
        int *myattrs;
        struct pv_head *pvh;
        struct pv_entry *pve;
 -      struct pmap *pmap2;
        pt_entry_t pte;
 +      pt_entry_t expect;
  
  #if DIAGNOSTIC
        int bank, off;
 @@ -3131,26 +3199,28 @@
        }
  
        /* nope, gonna have to do it the hard way */
 -      rw_enter(&pmap_main_lock, RW_WRITER);
  
 +      expect = pmap_pa2pte(VM_PAGE_TO_PHYS(pg)) | PG_V;
 +      mutex_spin_enter(&pvh->pvh_lock);
        for (pve = SPLAY_MIN(pvtree, &pvh->pvh_root);
             pve != NULL && (*myattrs & testbits) == 0;
             pve = SPLAY_NEXT(pvtree, &pvh->pvh_root, pve)) {
 -              pt_entry_t *ptes;
 -              pd_entry_t **pdes;
 +              pt_entry_t *ptep;
  
 -              pmap_map_ptes(pve->pv_pmap, &pmap2, &ptes, &pdes);
 -              pte = ptes[pl1_i(pve->pv_va)];
 -              pmap_unmap_ptes(pve->pv_pmap, pmap2);
 -              *myattrs |= pte;
 +              ptep = pmap_map_pte(pve->pv_ptp, pve->pv_va);
 +              pte = *ptep;
 +              pmap_unmap_pte();
 +              if ((pte & (PG_FRAME | PG_V)) == expect) {
 +                      *myattrs |= pte;
 +              }
        }
 +      mutex_spin_exit(&pvh->pvh_lock);
  
        /*
         * note that we will exit the for loop with a non-null pve if
         * we have found the bits we are testing for.
         */
  
 -      rw_exit(&pmap_main_lock);
        return((*myattrs & testbits) != 0);
  }
  
 @@ -3168,10 +3238,8 @@
        uint32_t result;
        struct pv_head *pvh;
        struct pv_entry *pve;
 -      pt_entry_t *ptes, opte;
        int *myattrs;
 -      struct pmap *pmap2;
 -
 +      pt_entry_t expect;
  #ifdef DIAGNOSTIC
        int bank, off;
  
 @@ -3180,33 +3248,26 @@
                panic("pmap_change_attrs: unmanaged page?");
  #endif
        mdpg = &pg->mdpage;
 -
 -      rw_enter(&pmap_main_lock, RW_WRITER);
        pvh = &mdpg->mp_pvhead;
 -
        myattrs = &mdpg->mp_attrs;
 +      expect = pmap_pa2pte(VM_PAGE_TO_PHYS(pg)) | PG_V;
 +
 +      mutex_spin_enter(&pvh->pvh_lock);
        result = *myattrs & clearbits;
        *myattrs &= ~clearbits;
 -
        SPLAY_FOREACH(pve, pvtree, &pvh->pvh_root) {
                pt_entry_t *ptep;
 -              pd_entry_t **pdes;
 +              pt_entry_t opte;
  
 -              /* locks pmap */
 -              pmap_map_ptes(pve->pv_pmap, &pmap2, &ptes, &pdes);
 -#ifdef DIAGNOSTIC
 -              if (!pmap_pdes_valid(pve->pv_va, pdes, NULL))
 -                      panic("pmap_change_attrs: mapping without PTP "
 -                            "detected");
 -#endif
 -              ptep = &ptes[pl1_i(pve->pv_va)];
 +              ptep = pmap_map_pte(pve->pv_ptp, pve->pv_va);
 +retry:
                opte = *ptep;
 -              KASSERT(pmap_valid_entry(opte));
 -              KDASSERT(pmap_pte2pa(opte) == VM_PAGE_TO_PHYS(pg));
 +              if ((opte & (PG_FRAME | PG_V)) != expect) {
 +                      goto no_tlb_shootdown;
 +              }
                if (opte & clearbits) {
                        /* We need to do something */
                        if (clearbits == PG_RW) {
 -                              result |= PG_RW;
  
                                /*
                                 * On write protect we might not need to flush 
 @@ -3214,8 +3275,12 @@
                                 */
  
                                /* First zap the RW bit! */
 -                              pmap_pte_clearbits(ptep, PG_RW); 
 -                              opte = *ptep;
 +                              if (pmap_pte_cas(ptep, opte, opte & ~PG_RW)
 +                                  != opte) {
 +                                      goto retry;
 +                              }
 +                              opte &= ~PG_RW;
 +                              result |= PG_RW;
  
                                /*
                                 * Then test if it is not cached as RW the TLB
 @@ -3230,7 +3295,10 @@
                         */
  
                        /* zap! */
 -                      opte = pmap_pte_testset(ptep, (opte & ~(PG_U | PG_M)));
 +                      if (pmap_pte_cas(ptep, opte, opte & ~(PG_U | PG_M))
 +                          != opte) {
 +                              goto retry;
 +                      }
  
                        result |= (opte & clearbits);
                        *myattrs |= (opte & ~(clearbits));
 @@ -3238,10 +3306,9 @@
                        pmap_tlb_shootdown(pve->pv_pmap, pve->pv_va, 0, opte);
                }
  no_tlb_shootdown:
 -              pmap_unmap_ptes(pve->pv_pmap, pmap2);   /* unlocks pmap */
 +              pmap_unmap_pte();
        }
 -
 -      rw_exit(&pmap_main_lock);
 +      mutex_spin_exit(&pvh->pvh_lock);
  
        crit_enter();
        pmap_tlb_shootwait();
 @@ -3366,14 +3433,18 @@
        pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);      /* locks pmap */
  
        if (pmap_pdes_valid(va, pdes, NULL)) {
 +              pt_entry_t *ptep = &ptes[pl1_i(va)];
 +              pt_entry_t opte = *ptep;
  
  #ifdef DIAGNOSTIC
 -              if (!pmap_valid_entry(ptes[pl1_i(va)]))
 +              if (!pmap_valid_entry(opte))
                        panic("pmap_unwire: invalid (unmapped) va 0x%lx", va);
  #endif
 -              if ((ptes[pl1_i(va)] & PG_W) != 0) {
 -                      pmap_pte_clearbits(&ptes[pl1_i(va)], PG_W);
 -                      pmap->pm_stats.wired_count--;
 +              if ((opte & PG_W) != 0) {
 +                      pt_entry_t npte = opte & ~PG_W;
 +
 +                      opte = pmap_pte_testset(ptep, npte);
 +                      pmap_stats_update_bypte(pmap, npte, opte);
                }
  #ifdef DIAGNOSTIC
                else {
 @@ -3488,9 +3559,6 @@
        /* get a pve. */
        freepve = pool_cache_get(&pmap_pv_cache, PR_NOWAIT);
  
 -      /* get lock */
 -      rw_enter(&pmap_main_lock, RW_READER);
 -
        pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);      /* locks pmap */
        if (pmap == pmap_kernel()) {
                ptp = NULL;
 @@ -3540,8 +3608,7 @@
                 * change since we are replacing/changing a valid mapping.
                 * wired count might change...
                 */
 -              pmap->pm_stats.wired_count +=
 -                  ((npte & PG_W) ? 1 : 0 - (opte & PG_W) ? 1 : 0);
 +              pmap_stats_update_bypte(pmap, npte, opte);
  
                /*
                 * if this is on the PVLIST, sync R/M bit
 @@ -3608,8 +3675,7 @@
                 * change since we are replacing/changing a valid mapping.
                 * wired count might change...
                 */
 -              pmap->pm_stats.wired_count +=
 -                  ((npte & PG_W) ? 1 : 0 - (opte & PG_W) ? 1 : 0);
 +              pmap_stats_update_bypte(pmap, npte, opte);
  
                if (opte & PG_PVLIST) {
                        pg = PHYS_TO_VM_PAGE(pmap_pte2pa(opte));
 @@ -3633,9 +3699,8 @@
                                    (pt_entry_t *)vtomach((vaddr_t)ptep),
                                    npte, domid);
                                if (error) {
 -                                      pmap->pm_stats.wired_count -=
 -                                          ((npte & PG_W) ? 1 : 0 -
 -                                          (opte & PG_W) ? 1 : 0);
 +                                      pmap_stats_update_bypte(pmap, opte,
 +                                          npte);
                                        splx(s);
                                        mutex_spin_exit(&old_pvh->pvh_lock);
                                        goto out;
 @@ -3659,9 +3724,7 @@
                        goto shootdown_test;
                }
        } else {        /* opte not valid */
 -              pmap->pm_stats.resident_count++;
 -              if (wired) 
 -                      pmap->pm_stats.wired_count++;
 +              pmap_stats_update(pmap, 1, (wired) ? 1 : 0);
                if (ptp)
                        ptp->wire_count++;
        }
 @@ -3676,13 +3739,11 @@
                splx(s);
                if (error) {
                        if (pmap_valid_entry(opte)) {
 -                              pmap->pm_stats.wired_count -=
 -                                  ((npte & PG_W) ? 1 : 0 -
 -                                  (opte & PG_W) ? 1 : 0);
 +                              pmap_stats_update(pmap, 0,
 +                                  -((npte & PG_W) ? 1 : 0 -
 +                                  (opte & PG_W) ? 1 : 0));
                        } else {        /* opte not valid */
 -                              pmap->pm_stats.resident_count--;
 -                              if (wired) 
 -                                      pmap->pm_stats.wired_count--;
 +                              pmap_stats_update(pmap, -1, wired ? -1 : 0);
                                if (ptp)
                                        ptp->wire_count--;
                        }
 @@ -3710,7 +3771,6 @@
  
  out:
        pmap_unmap_ptes(pmap, pmap2);
 -      rw_exit(&pmap_main_lock);
  
        if (freepve != NULL) {
                /* put back the pv, we don't need it. */
 @@ -3777,7 +3837,7 @@
                ptp->wire_count = 1;
                *paddrp = VM_PAGE_TO_PHYS(ptp);
        }
 -      kpm->pm_stats.resident_count++;
 +      pmap_stats_update(kpm, 1, 0);
        return true;
  }
  
 @@ -3958,7 +4018,6 @@
         * we lock in the pmap => pv_head direction
         */
  
 -      rw_enter(&pmap_main_lock, RW_READER);
        pmap_map_ptes(pmap, &pmap2, &ptes, &pdes);      /* locks pmap */
  
        /*
 @@ -3986,7 +4045,6 @@
                }
        }
        pmap_unmap_ptes(pmap, pmap2);
 -      rw_exit(&pmap_main_lock);
  }
  #endif
  
 
 --k1lZvvs/B4yU6o8G--
 



Home | Main Index | Thread Index | Old Index