Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Jun 2001 20:35:20 +0100 (BST)
From:      Doug Rabson <dfr@nlsystems.com>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        <alpha@FreeBSD.ORG>
Subject:   Re: pmap_emulate_reference()
Message-ID:  <Pine.BSF.4.33.0106282033460.1173-100000@herring.nlsystems.com>
In-Reply-To: <XFMail.010627211630.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 27 Jun 2001, John Baldwin wrote:

>
> On 27-Jun-01 Doug Rabson wrote:
> > On Thu, 28 Jun 2001, Doug Rabson wrote:
> >
> >> Based on a conversation at lunch today, I decided to try rewriting
> >> pmap_emulate_reference() to avoid the need for the vm lock. Basically, I
> >> just use a couple of extra bits in the pte to store the changed/referenced
> >> state and defer the hard work to pmap_ts_referenced() etc.
> >>
> >> I haven't (obviously) tested this since I'm at Usenix but I think the
> >> principle is sound.
> >>
> >
> > This version is a bit simpler...
>
> It also means that pmap_emulate_reference() won't need the vm lock anymore,
> which is a big win here.

Ok, this version actually compiles. I'm not planning to test it until I
get home though.

Index: mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/mp_machdep.c,v
retrieving revision 1.21
diff -u -r1.21 mp_machdep.c
--- mp_machdep.c	2001/06/13 20:40:24	1.21
+++ mp_machdep.c	2001/06/28 19:18:09
@@ -363,13 +363,14 @@
 		}
 		all_cpus |= 1 << i;
 		mp_ncpus++;
+		break;
 	}
 	PCPU_SET(other_cpus, all_cpus & ~(1 << boot_cpu_id));

 	for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
 		if (i == boot_cpu_id)
 			continue;
-		if (all_cpus & 1 << i)
+		if (all_cpus & 1 << i)
 			smp_start_secondary(i);
 	}
 }
Index: pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v
retrieving revision 1.59
diff -u -r1.59 pmap.c
--- pmap.c	2001/06/25 23:52:25	1.59
+++ pmap.c	2001/06/28 19:32:43
@@ -2745,16 +2745,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 +2782,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 +2809,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);
+		}
 	}
 }

@@ -2829,7 +2871,6 @@
 {
 	pt_entry_t faultoff, *pte;
 	vm_offset_t pa;
-	vm_page_t m;
 	int user_addr;

 	/*
@@ -2883,33 +2924,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)
-		vm_page_flag_set(m, PG_REFERENCED);
-
 	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);
 }

 /*
Index: trap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/trap.c,v
retrieving revision 1.65
diff -u -r1.65 trap.c
--- trap.c	2001/06/25 23:52:25	1.65
+++ trap.c	2001/06/28 19:26:47
@@ -484,18 +484,10 @@
 		case ALPHA_MMCSR_FOR:
 		case ALPHA_MMCSR_FOE:
 		case ALPHA_MMCSR_FOW:
-		{
-			int hadvmlock;
-
-			hadvmlock = mtx_owned(&vm_mtx);
-			if (hadvmlock == 0)
-				mtx_lock(&vm_mtx);
 			pmap_emulate_reference(p, a0, user,
 			    a1 == ALPHA_MMCSR_FOW);
-			if (hadvmlock == 0)
-				mtx_unlock(&vm_mtx);
 			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.0106282033460.1173-100000>