diff options
author | alc <alc@FreeBSD.org> | 2010-04-25 20:40:45 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2010-04-25 20:40:45 +0000 |
commit | 019a1d16bacaa7783b857c309ce61d655e899904 (patch) | |
tree | ec9ad7b26fa81cd6cf0b255dbb08eeabdf74fed4 | |
parent | 8156e27dd79d633bbb41f44cf030e93cdcd15889 (diff) | |
download | FreeBSD-src-019a1d16bacaa7783b857c309ce61d655e899904.zip FreeBSD-src-019a1d16bacaa7783b857c309ce61d655e899904.tar.gz |
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.
-rw-r--r-- | sys/amd64/amd64/pmap.c | 29 | ||||
-rw-r--r-- | sys/i386/i386/pmap.c | 28 |
2 files changed, 12 insertions, 45 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 9c7d8b0..6cd10b4 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -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; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 1ce6454..d8b9686 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -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; |