summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-02-12 18:53:15 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-02-12 18:53:15 +0000
commit0457cc79700207d192ee19c175a32761448c207d (patch)
tree5729dc487223229185658e9d835bd467aacf08dc /sys/arch/sparc64
parent31932de7e60a24a438c0ca37a513bdbac0ef0612 (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.h5
-rw-r--r--sys/arch/sparc64/sparc64/ipifuncs.c4
-rw-r--r--sys/arch/sparc64/sparc64/pmap.c56
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.
*