diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-12 18:53:15 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-12 18:53:15 +0000 |
commit | 0457cc79700207d192ee19c175a32761448c207d (patch) | |
tree | 5729dc487223229185658e9d835bd467aacf08dc /sys/arch/sparc64 | |
parent | 31932de7e60a24a438c0ca37a513bdbac0ef0612 (diff) |
Add a pm_statistics struct to all pmap, and keep track of resident
pages. Use this to provide a real pmap_resident_count() function.
ok kettenis@
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r-- | sys/arch/sparc64/include/pmap.h | 5 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/ipifuncs.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/pmap.c | 56 |
3 files changed, 17 insertions, 48 deletions
diff --git a/sys/arch/sparc64/include/pmap.h b/sys/arch/sparc64/include/pmap.h index 6d90051bdb5..31f48571b9a 100644 --- a/sys/arch/sparc64/include/pmap.h +++ b/sys/arch/sparc64/include/pmap.h @@ -122,6 +122,8 @@ struct pmap { paddr_t pm_physaddr; /* physical address of pm_segs */ int64_t *pm_segs; struct simplelock pm_lock; + + struct pmap_statistics pm_stats; }; /* @@ -157,9 +159,8 @@ typedef struct pmap *pmap_t; extern struct pmap kernel_pmap_; #define pmap_kernel() (&kernel_pmap_) -int pmap_count_res(pmap_t pmap); /* int pmap_change_wiring(pmap_t pm, vaddr_t va, boolean_t wired); */ -#define pmap_resident_count(pm) pmap_count_res((pm)) +#define pmap_resident_count(pm) ((pm)->pm_stats.resident_count) #define pmap_phys_address(x) (x) #define pmap_update(pm) /* nothing (yet) */ diff --git a/sys/arch/sparc64/sparc64/ipifuncs.c b/sys/arch/sparc64/sparc64/ipifuncs.c index 4903c71065c..d3ccc9acf19 100644 --- a/sys/arch/sparc64/sparc64/ipifuncs.c +++ b/sys/arch/sparc64/sparc64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.12 2008/11/22 18:12:32 art Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.13 2009/02/12 18:53:14 miod Exp $ */ /* $NetBSD: ipifuncs.c,v 1.8 2006/10/07 18:11:36 rjs Exp $ */ /*- @@ -31,6 +31,8 @@ #include <sys/systm.h> #include <sys/proc.h> +#include <uvm/uvm_extern.h> + #include <machine/cpu.h> #include <machine/ctlreg.h> #include <machine/hypervisor.h> diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c index 4412a94ddf9..a7648ced6ee 100644 --- a/sys/arch/sparc64/sparc64/pmap.c +++ b/sys/arch/sparc64/sparc64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.67 2008/07/27 20:33:23 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.68 2009/02/12 18:53:14 miod Exp $ */ /* $NetBSD: pmap.c,v 1.107 2001/08/31 16:47:41 eeh Exp $ */ #undef NO_VCACHE /* Don't forget the locked TLB in dostart */ /* @@ -474,6 +474,7 @@ pmap_enter_kpage(vaddr_t va, int64_t data) prom_printf("pmap_enter_kpage: out of pages\n"); panic("pmap_enter_kpage"); } + pmap_kernel()->pm_stats.resident_count++; BDPRINTF(PDB_BOOT1, ("pseg_set: pm=%p va=%p data=%lx newp %lx\r\n", @@ -1986,6 +1987,8 @@ pmap_kenter_pa(va, pa, prot) if (pseg_set(pmap_kernel(), va, tte.data, 0) != 0) panic("pmap_kenter_pa: no pseg"); + pmap_kernel()->pm_stats.resident_count++; + splx(s); /* this is correct */ dcache_flush_page(pa); @@ -2043,6 +2046,7 @@ pmap_kremove(va, size) remove_stats.removes ++; #endif + pmap_kernel()->pm_stats.resident_count--; tsb_invalidate(pm->pm_ctx, va); #ifdef DEBUG remove_stats.tflushes ++; @@ -2176,6 +2180,7 @@ pmap_enter(pm, va, pa, prot, flags) if (pv) pmap_enter_pv(pm, va, pa); + pm->pm_stats.resident_count++; simple_unlock(&pm->pm_lock); splx(s); if (pm->pm_ctx || pm == pmap_kernel()) { @@ -2232,7 +2237,7 @@ pmap_remove(pm, va, endva) panic("pmap_remove: va=%08x in locked TLB", (u_int)va); #endif /* We don't really need to do this if the valid bit is not set... */ - if ((data = pseg_get(pm, va))) { + if ((data = pseg_get(pm, va)) && (data & TLB_V) != 0) { paddr_t entry; pv_entry_t pv; @@ -2251,10 +2256,11 @@ pmap_remove(pm, va, endva) Debugger(); /* panic? */ } + pm->pm_stats.resident_count--; #ifdef DEBUG if (pmapdebug & PDB_REMOVE) printf(" clearing seg %x pte %x\n", (int)va_to_seg(va), (int)va_to_pte(va)); - remove_stats.removes ++; + remove_stats.removes++; #endif if (!pm->pm_ctx && pm != pmap_kernel()) continue; @@ -3124,6 +3130,7 @@ pmap_page_protect(pg, prot) (npv->pv_va & PV_VAMASK)); tlb_flush_pte(npv->pv_va&PV_VAMASK, npv->pv_pmap->pm_ctx); } + npv->pv_pmap->pm_stats.resident_count--; simple_unlock(&npv->pv_pmap->pm_lock); /* free the pv */ @@ -3162,6 +3169,7 @@ pmap_page_protect(pg, prot) tlb_flush_pte(pv->pv_va & PV_VAMASK, pv->pv_pmap->pm_ctx); } + pv->pv_pmap->pm_stats.resident_count--; simple_unlock(&pv->pv_pmap->pm_lock); npv = pv->pv_next; /* dump the first pv */ @@ -3184,48 +3192,6 @@ pmap_page_protect(pg, prot) } /* - * count pages in pmap -- this can be slow. - */ -int -pmap_count_res(pm) - pmap_t pm; -{ - int i, j, k, n, s; - paddr_t *pdir, *ptbl; - /* Almost the same as pmap_collect() */ - - /* - * XXX On the SPARC Enterprise T5120, counting the number of - * pages in the kernel pmap is ridiculously slow. Since ps(1) - * doesn't use the information for P_SYSTEM processes, we may - * as well skip the counting and return zero immediately. - */ - if (pm == pmap_kernel()) - return 0; - - /* Don't want one of these pages reused while we're reading it. */ - s = splvm(); - simple_lock(&pm->pm_lock); - n = 0; - for (i=0; i<STSZ; i++) { - if((pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED))) { - for (k=0; k<PDSZ; k++) { - if ((ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED))) { - for (j=0; j<PTSZ; j++) { - int64_t data = (int64_t)ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED); - if (data&TLB_V) - n++; - } - } - } - } - } - simple_unlock(&pm->pm_lock); - splx(s); - return n; -} - -/* * Allocate a context. If necessary, steal one from someone else. * Changes hardware context number and loads segment map. * |