From owner-svn-src-all@FreeBSD.ORG Thu Dec 9 20:16:01 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F2D111065672; Thu, 9 Dec 2010 20:16:00 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E1EA18FC0A; Thu, 9 Dec 2010 20:16:00 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oB9KG0VO049568; Thu, 9 Dec 2010 20:16:00 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oB9KG05P049565; Thu, 9 Dec 2010 20:16:00 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201012092016.oB9KG05P049565@svn.freebsd.org> From: Alan Cox Date: Thu, 9 Dec 2010 20:16:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216333 - head/sys/i386/i386 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Dec 2010 20:16:01 -0000 Author: alc Date: Thu Dec 9 20:16:00 2010 New Revision: 216333 URL: http://svn.freebsd.org/changeset/base/216333 Log: When r207410 eliminated the acquisition and release of the page queues lock from pmap_extract_and_hold(), it didn't take into account that pmap_pte_quick() sometimes requires the page queues lock to be held. This change reimplements pmap_extract_and_hold() such that it no longer uses pmap_pte_quick(), and thus never requires the page queues lock. For consistency, adopt the same idiom as used by the new implementation of pmap_extract_and_hold() in pmap_extract() and pmap_mincore(). It also happens to make these functions shorter. Fix a style error in pmap_pte(). Reviewed by: kib@ Modified: head/sys/i386/i386/pmap.c Modified: head/sys/i386/i386/pmap.c ============================================================================== --- head/sys/i386/i386/pmap.c Thu Dec 9 20:05:29 2010 (r216332) +++ head/sys/i386/i386/pmap.c Thu Dec 9 20:16:00 2010 (r216333) @@ -1213,7 +1213,7 @@ pmap_pte(pmap_t pmap, vm_offset_t va) } return (PADDR2 + (i386_btop(va) & (NPTEPG - 1))); } - return (0); + return (NULL); } /* @@ -1291,21 +1291,19 @@ pmap_pte_quick(pmap_t pmap, vm_offset_t vm_paddr_t pmap_extract(pmap_t pmap, vm_offset_t va) { + pt_entry_t pte, *ptep; vm_paddr_t rtval; - pt_entry_t *pte; - pd_entry_t pde; rtval = 0; PMAP_LOCK(pmap); - pde = pmap->pm_pdir[va >> PDRSHIFT]; - if (pde != 0) { - if ((pde & PG_PS) != 0) - rtval = (pde & PG_PS_FRAME) | (va & PDRMASK); - else { - pte = pmap_pte(pmap, va); - rtval = (*pte & PG_FRAME) | (va & PAGE_MASK); - pmap_pte_release(pte); - } + ptep = pmap_pte(pmap, va); + pte = (ptep != NULL) ? *ptep : 0; + pmap_pte_release(ptep); + if ((pte & PG_V) != 0) { + if ((pte & PG_PS) != 0) + rtval = (pte & PG_PS_FRAME) | (va & PDRMASK); + else + rtval = (pte & PG_FRAME) | (va & PAGE_MASK); } PMAP_UNLOCK(pmap); return (rtval); @@ -1321,40 +1319,30 @@ pmap_extract(pmap_t pmap, vm_offset_t va vm_page_t pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) { - pd_entry_t pde; - pt_entry_t pte; + pt_entry_t pte, *ptep; + vm_paddr_t locked_pa, pa; vm_page_t m; - vm_paddr_t pa; - pa = 0; + locked_pa = 0; m = NULL; PMAP_LOCK(pmap); retry: - pde = *pmap_pde(pmap, va); - if (pde != 0) { - if (pde & PG_PS) { - if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) { - if (vm_page_pa_tryrelock(pmap, (pde & PG_PS_FRAME) | - (va & PDRMASK), &pa)) - goto retry; - m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) | - (va & PDRMASK)); - vm_page_hold(m); - } - } else { - sched_pin(); - pte = *pmap_pte_quick(pmap, va); - if (pte != 0 && - ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) { - if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME, &pa)) - goto retry; - m = PHYS_TO_VM_PAGE(pte & PG_FRAME); - vm_page_hold(m); - } - sched_unpin(); - } + ptep = pmap_pte(pmap, va); + pte = (ptep != NULL) ? *ptep : 0; + pmap_pte_release(ptep); + if ((pte & PG_V) != 0 && + ((pte & PG_RW) != 0 || (prot & VM_PROT_WRITE) == 0)) { + if ((pte & PG_PS) != 0) { + /* Compute the physical address of the 4KB page. */ + pa = (pte & PG_PS_FRAME) | (va & PG_FRAME & PDRMASK); + } else + pa = pte & PG_FRAME; + if (vm_page_pa_tryrelock(pmap, pa, &locked_pa)) + goto retry; + m = PHYS_TO_VM_PAGE(pa); + vm_page_hold(m); + PA_UNLOCK(locked_pa); } - PA_UNLOCK_COND(pa); PMAP_UNLOCK(pmap); return (m); } @@ -4991,39 +4979,30 @@ pmap_change_attr(vm_offset_t va, vm_size int pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa) { - pd_entry_t *pdep; pt_entry_t *ptep, pte; vm_paddr_t pa; int val; PMAP_LOCK(pmap); retry: - pdep = pmap_pde(pmap, addr); - if (*pdep != 0) { - if (*pdep & PG_PS) { - pte = *pdep; + ptep = pmap_pte(pmap, addr); + pte = (ptep != NULL) ? *ptep : 0; + pmap_pte_release(ptep); + if ((pte & PG_V) != 0) { + val = MINCORE_INCORE; + if ((pte & PG_PS) != 0) { + val |= MINCORE_SUPER; /* Compute the physical address of the 4KB page. */ - pa = ((*pdep & PG_PS_FRAME) | (addr & PDRMASK)) & - PG_FRAME; - val = MINCORE_SUPER; - } else { - ptep = pmap_pte(pmap, addr); - pte = *ptep; - pmap_pte_release(ptep); + pa = (pte & PG_PS_FRAME) | (addr & PG_FRAME & PDRMASK); + } else pa = pte & PG_FRAME; - val = 0; - } - } else { - pte = 0; - pa = 0; - val = 0; - } - if ((pte & PG_V) != 0) { - val |= MINCORE_INCORE; if ((pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; if ((pte & PG_A) != 0) val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER; + } else { + val = 0; + pa = 0; } if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) != (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) &&