From owner-svn-src-head@FreeBSD.ORG Sun Apr 25 20:40:46 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 02DC8106564A; Sun, 25 Apr 2010 20:40:46 +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 E52668FC21; Sun, 25 Apr 2010 20:40:45 +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 o3PKej2j065067; Sun, 25 Apr 2010 20:40:45 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3PKejOe065064; Sun, 25 Apr 2010 20:40:45 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201004252040.o3PKejOe065064@svn.freebsd.org> From: Alan Cox Date: Sun, 25 Apr 2010 20:40:45 +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: r207205 - in head/sys: amd64/amd64 i386/i386 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Apr 2010 20:40:46 -0000 Author: alc Date: Sun Apr 25 20:40:45 2010 New Revision: 207205 URL: http://svn.freebsd.org/changeset/base/207205 Log: Clearing a page table entry's accessed bit (PG_A) and setting the page's PG_REFERENCED flag in pmap_protect() can't really be justified. In contrast to pmap_remove() or pmap_remove_all(), the mapping is not being destroyed, so the notion that the page was accessed is not lost. Moreover, clearing the page table entry's accessed bit and setting the page's PG_REFERENCED flag can throw off the page daemon's activity count calculation. Finally, in my tests, I found that 15% of the atomic memory operations being performed by pmap_protect() were only to clear PG_A, and not change protection. This could, by itself, be fixed, but I don't see the point given the above argument. Remove a comment from pmap_protect_pde() that is no longer meaningful after the above change. Modified: head/sys/amd64/amd64/pmap.c head/sys/i386/i386/pmap.c Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Sun Apr 25 20:01:13 2010 (r207204) +++ head/sys/amd64/amd64/pmap.c Sun Apr 25 20:40:45 2010 (r207205) @@ -2833,18 +2833,9 @@ retry: if (oldpde & PG_MANAGED) { eva = sva + NBPDR; for (va = sva, m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME); - va < eva; va += PAGE_SIZE, m++) { - /* - * In contrast to the analogous operation on a 4KB page - * mapping, the mapping's PG_A flag is not cleared and - * the page's PG_REFERENCED flag is not set. The - * reason is that pmap_demote_pde() expects that a 2MB - * page mapping with a stored page table page has PG_A - * set. - */ + va < eva; va += PAGE_SIZE, m++) if ((oldpde & (PG_M | PG_RW)) == (PG_M | PG_RW)) vm_page_dirty(m); - } } if ((prot & VM_PROT_WRITE) == 0) newpde &= ~(PG_RW | PG_M); @@ -2953,23 +2944,15 @@ retry: obits = pbits = *pte; if ((pbits & PG_V) == 0) continue; - if (pbits & PG_MANAGED) { - m = NULL; - if (pbits & PG_A) { + + if ((prot & VM_PROT_WRITE) == 0) { + if ((pbits & (PG_MANAGED | PG_M | PG_RW)) == + (PG_MANAGED | PG_M | PG_RW)) { m = PHYS_TO_VM_PAGE(pbits & PG_FRAME); - vm_page_flag_set(m, PG_REFERENCED); - pbits &= ~PG_A; - } - if ((pbits & (PG_M | PG_RW)) == (PG_M | PG_RW)) { - if (m == NULL) - m = PHYS_TO_VM_PAGE(pbits & - PG_FRAME); vm_page_dirty(m); } - } - - if ((prot & VM_PROT_WRITE) == 0) pbits &= ~(PG_RW | PG_M); + } if ((prot & VM_PROT_EXECUTE) == 0) pbits |= pg_nx; Modified: head/sys/i386/i386/pmap.c ============================================================================== --- head/sys/i386/i386/pmap.c Sun Apr 25 20:01:13 2010 (r207204) +++ head/sys/i386/i386/pmap.c Sun Apr 25 20:40:45 2010 (r207205) @@ -2955,18 +2955,9 @@ retry: if (oldpde & PG_MANAGED) { eva = sva + NBPDR; for (va = sva, m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME); - va < eva; va += PAGE_SIZE, m++) { - /* - * In contrast to the analogous operation on a 4KB page - * mapping, the mapping's PG_A flag is not cleared and - * the page's PG_REFERENCED flag is not set. The - * reason is that pmap_demote_pde() expects that a 2/4MB - * page mapping with a stored page table page has PG_A - * set. - */ + va < eva; va += PAGE_SIZE, m++) if ((oldpde & (PG_M | PG_RW)) == (PG_M | PG_RW)) vm_page_dirty(m); - } } if ((prot & VM_PROT_WRITE) == 0) newpde &= ~(PG_RW | PG_M); @@ -3074,22 +3065,15 @@ retry: obits = pbits = *pte; if ((pbits & PG_V) == 0) continue; - if (pbits & PG_MANAGED) { - m = NULL; - if (pbits & PG_A) { + + if ((prot & VM_PROT_WRITE) == 0) { + if ((pbits & (PG_MANAGED | PG_M | PG_RW)) == + (PG_MANAGED | PG_M | PG_RW)) { m = PHYS_TO_VM_PAGE(pbits & PG_FRAME); - vm_page_flag_set(m, PG_REFERENCED); - pbits &= ~PG_A; - } - if ((pbits & (PG_M | PG_RW)) == (PG_M | PG_RW)) { - if (m == NULL) - m = PHYS_TO_VM_PAGE(pbits & PG_FRAME); vm_page_dirty(m); } - } - - if ((prot & VM_PROT_WRITE) == 0) pbits &= ~(PG_RW | PG_M); + } #ifdef PAE if ((prot & VM_PROT_EXECUTE) == 0) pbits |= pg_nx;