Date: Sun, 15 Jul 2001 15:10:17 +0100 (BST) From: Doug Rabson <dfr@nlsystems.com> To: Peter Wemm <peter@wemm.org> Cc: Matthew Jacob <mjacob@feral.com>, John Baldwin <jhb@FreeBSD.ORG>, <alpha@FreeBSD.ORG> Subject: Re: pmap_emulate_reference() Message-ID: <Pine.BSF.4.33.0107151509060.569-100000@salmon.nlsystems.com> In-Reply-To: <20010714085805.D440538CC@overcee.netplex.com.au>
index | next in thread | previous in thread | raw e-mail
On Sat, 14 Jul 2001, Peter Wemm wrote:
> Doug Rabson wrote:
> > On Thu, 28 Jun 2001, Matthew Jacob wrote:
> >
> > >
> > >
> > > Can somebody fix:
> > >
> > > + if (all_cpus & 1 << i)
> > >
> > >
> >
> > Oops. That shouldn't even be part of the patch. Ignore everything except
> > trap.c and pmap.c.
>
> The patch seems to work, but there are some stray loose ends still.. There
> are still references to PV_TABLE_REF and PV_TABLE_MOD where things are
> testing them but nothing ever sets them.
Good point. This version (which I'm just testing now) deals with that and
should even give more accurate reports from pmap_mincore().
Index: include/pmap.h
===================================================================
RCS file: /home/ncvs/src/sys/alpha/include/pmap.h,v
retrieving revision 1.11
diff -u -r1.11 pmap.h
--- include/pmap.h 2000/09/23 12:18:05 1.11
+++ include/pmap.h 2001/07/15 12:39:13
@@ -165,15 +165,11 @@
TAILQ_HEAD(,pv_entry) pv_list;
};
-#define PV_TABLE_MOD 0x01 /* modified */
-#define PV_TABLE_REF 0x02 /* referenced */
-
struct pmap {
pt_entry_t *pm_lev1; /* KVA of lev0map */
vm_object_t pm_pteobj; /* Container for pte's */
TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
int pm_count; /* reference count */
- int pm_flags; /* pmap flags */
u_int32_t pm_active; /* active cpus */
struct {
u_int32_t asn:8; /* address space number */
Index: alpha/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v
retrieving revision 1.60
diff -u -r1.60 pmap.c
--- alpha/pmap.c 2001/07/05 17:27:50 1.60
+++ alpha/pmap.c 2001/07/15 12:48:30
@@ -1189,7 +1189,6 @@
int i;
pmap->pm_lev1 = Lev1map;
- pmap->pm_flags = 0;
pmap->pm_count = 1;
pmap->pm_ptphint = NULL;
pmap->pm_active = 0;
@@ -1239,7 +1238,6 @@
pmap->pm_lev1[PTLEV1I] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(lev1pg))
| PG_V | PG_KRE | PG_KWE;
- pmap->pm_flags = 0;
pmap->pm_count = 1;
pmap->pm_ptphint = NULL;
pmap->pm_active = 0;
@@ -2107,16 +2105,10 @@
newpte = pmap_phys_to_pte(pa) | pte_prot(pmap, prot) | PG_V | managed;
if (managed) {
- vm_page_t om;
-
/*
* Set up referenced/modified emulation for the new mapping
*/
- om = PHYS_TO_VM_PAGE(pa);
- if ((om->md.pv_flags & PV_TABLE_REF) == 0)
- newpte |= PG_FOR | PG_FOW | PG_FOE;
- else if ((om->md.pv_flags & PV_TABLE_MOD) == 0)
- newpte |= PG_FOW;
+ newpte |= origpte & (PG_FOR | PG_FOW | PG_FOE);
}
if (wired)
@@ -2745,16 +2737,32 @@
int
pmap_ts_referenced(vm_page_t m)
{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+ int count;
+
if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return 0;
- if (m->md.pv_flags & PV_TABLE_REF) {
- pmap_changebit(m, PG_FOR|PG_FOE|PG_FOW, TRUE);
- m->md.pv_flags &= ~PV_TABLE_REF;
- return 1;
+ /*
+ * Loop over current mappings looking for any which have don't
+ * have PG_FOR set (i.e. ones where we have taken an emulate
+ * reference trap recently).
+ */
+ count = 0;
+ for (pv = TAILQ_FIRST(&m->md.pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+
+ if (!(*pte & PG_FOR)) {
+ count++;
+ *pte |= PG_FOR | PG_FOE;
+ pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ }
}
- return 0;
+ return count;
}
/*
@@ -2766,11 +2774,25 @@
boolean_t
pmap_is_modified(vm_page_t m)
{
+ pv_entry_t pv;
+ pt_entry_t *pte;
if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return FALSE;
- return (m->md.pv_flags & PV_TABLE_MOD) != 0;
+ /*
+ * A page is modified if any mapping has had its PG_FOW flag
+ * cleared.
+ */
+ for (pv = TAILQ_FIRST(&m->md.pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+ if (!(*pte & PG_FOW))
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -2779,12 +2801,24 @@
void
pmap_clear_modify(vm_page_t m)
{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+
if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return;
- if (m->md.pv_flags & PV_TABLE_MOD) {
- pmap_changebit(m, PG_FOW, TRUE);
- m->md.pv_flags &= ~PV_TABLE_MOD;
+ /*
+ * Loop over current mappings setting PG_FOW where needed.
+ */
+ for (pv = TAILQ_FIRST(&m->md.pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+
+ if (!(*pte & PG_FOW)) {
+ *pte |= PG_FOW;
+ pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ }
}
}
@@ -2809,12 +2843,24 @@
void
pmap_clear_reference(vm_page_t m)
{
+ pv_entry_t pv;
+ pt_entry_t *pte;
+
if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return;
- if (m->md.pv_flags & PV_TABLE_REF) {
- pmap_changebit(m, PG_FOR|PG_FOE|PG_FOW, TRUE);
- m->md.pv_flags &= ~PV_TABLE_REF;
+ /*
+ * Loop over current mappings setting PG_FOR and PG_FOE where needed.
+ */
+ for (pv = TAILQ_FIRST(&m->md.pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+
+ if (!(*pte & (PG_FOR | PG_FOE))) {
+ *pte |= (PG_FOR | PG_FOE);
+ pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
+ }
}
}
@@ -2829,7 +2875,6 @@
{
pt_entry_t faultoff, *pte;
vm_offset_t pa;
- vm_page_t m;
int user_addr;
/*
@@ -2883,36 +2928,14 @@
* (1) always mark page as used, and
* (2) if it was a write fault, mark page as modified.
*/
- m = PHYS_TO_VM_PAGE(pa);
- m->md.pv_flags |= PV_TABLE_REF;
- faultoff = PG_FOR | PG_FOE;
-
- if (user_addr) {
- mtx_lock(&Giant);
- vm_page_flag_set(m, PG_REFERENCED);
- mtx_unlock(&Giant);
- }
-
if (write) {
- m->md.pv_flags |= PV_TABLE_MOD;
- vm_page_dirty(m);
- faultoff |= PG_FOW;
- }
- pmap_changebit(m, faultoff, FALSE);
- if ((*pte & faultoff) != 0) {
-#if 1
- /*
- * XXX dfr - don't think its possible in our pmap
- */
- /*
- * This is apparently normal. Why? -- cgd
- * XXX because was being called on unmanaged pages?
- */
- panic("warning: pmap_changebit didn't.");
-#endif
- *pte &= ~faultoff;
- ALPHA_TBIS(v);
+ faultoff = PG_FOR | PG_FOE | PG_FOW;
+ } else {
+ faultoff = PG_FOR | PG_FOE;
}
+
+ *pte = (*pte & ~faultoff);
+ ALPHA_TBIS(v);
}
/*
@@ -2975,7 +2998,6 @@
pmap_t pmap;
vm_offset_t addr;
{
-
pt_entry_t *pte;
int val = 0;
@@ -2999,7 +3021,7 @@
/*
* Modified by us
*/
- if (m->md.pv_flags & PV_TABLE_MOD)
+ if ((*pte & PG_FOW) == 0)
val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
/*
* Modified by someone
@@ -3009,7 +3031,7 @@
/*
* Referenced by us
*/
- if (m->md.pv_flags & PV_TABLE_REF)
+ if ((*pte & (PG_FOR | PG_FOE)) == 0)
val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
/*
Index: alpha/trap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/trap.c,v
retrieving revision 1.71
diff -u -r1.71 trap.c
--- alpha/trap.c 2001/07/11 02:23:31 1.71
+++ alpha/trap.c 2001/07/15 11:57:12
@@ -434,11 +434,10 @@
case ALPHA_MMCSR_FOR:
case ALPHA_MMCSR_FOE:
case ALPHA_MMCSR_FOW:
- {
pmap_emulate_reference(p, a0, user,
a1 == ALPHA_MMCSR_FOW);
goto out;
- }
+
case ALPHA_MMCSR_INVALTRANS:
case ALPHA_MMCSR_ACCESS:
{
--
Doug Rabson Mail: dfr@nlsystems.com
Phone: +44 20 8348 6160
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.33.0107151509060.569-100000>
