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>