From owner-freebsd-alpha Wed Jun 27 16:23:55 2001 Delivered-To: freebsd-alpha@freebsd.org Received: from anchor-post-33.mail.demon.net (anchor-post-33.mail.demon.net [194.217.242.91]) by hub.freebsd.org (Postfix) with ESMTP id A9A6837B405 for ; Wed, 27 Jun 2001 16:23:49 -0700 (PDT) (envelope-from dfr@nlsystems.com) Received: from [62.49.251.130] (helo=herring.nlsystems.com) by anchor-post-33.mail.demon.net with esmtp (Exim 2.12 #1) id 15FOfm-000IUY-0X for alpha@freebsd.org; Thu, 28 Jun 2001 00:24:38 +0100 Received: from herring (herring [10.0.0.2]) by herring.nlsystems.com (8.11.2/8.11.2) with ESMTP id f5RNMX797911 for ; Thu, 28 Jun 2001 00:22:33 +0100 (BST) (envelope-from dfr@nlsystems.com) Date: Thu, 28 Jun 2001 00:22:33 +0100 (BST) From: Doug Rabson To: Subject: Re: pmap_emulate_reference() In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-alpha@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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... Index: alpha/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v retrieving revision 1.58 diff -u -r1.58 pmap.c --- alpha/pmap.c 2001/05/21 16:09:29 1.58 +++ alpha/pmap.c 2001/06/28 00:18:13 @@ -2745,16 +2745,31 @@ int pmap_ts_referenced(vm_page_t m) { + pv_entry_t pv; + 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 +2781,24 @@ boolean_t pmap_is_modified(vm_page_t m) { + pv_entry_t pv; 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 +2807,23 @@ void pmap_clear_modify(vm_page_t m) { + pv_entry_t pv; + 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_FOR | PG_FOE | PG_FOW; + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + } } } @@ -2883,35 +2922,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_trylock(&vm_mtx)) { - vm_page_flag_set(m, PG_REFERENCED); - mtx_unlock(&vm_mtx); - } - 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); } /* -- 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