Skip site navigation (1)Skip section navigation (2)
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>

next in thread | previous in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.33.0107151509060.569-100000>