init_pte_prot() patch
Alan Cox
alc at imimic.com
Thu Jun 3 05:30:06 UTC 2010
I would appreciate it if someone would test the attached patch. (A
"buildworld" would probably suffice.) Essentially, it does two things:
1. The virtual memory system only cares about the contents of a page's
dirty field if that page is managed (i.e., it is pageable). And, in
fact, if you survey the calls to vm_page_dirty() in the MIPS or any
other pmap, they are generally conditioned on the mapping having been
for a managed page.
The MIPS pmap_enter() is an exception to this rule. It is
unconditionally calling vm_page_dirty() on any page mapped within the
kernel address space, managed or otherwise. In fact, it is highly
unusual for pmap_enter() to be calling vm_page_dirty() on the page being
mapped, regardless of whether it is managed. This call to
vm_page_dirty() shouldn't be needed if change #2 below is also made.
The attached patch eliminates the call.
2. Since the virtual memory system only cares about the contents of a
page's dirty field if that page is managed, then dirty bit emulation
need only be performed on managed pages. At present, init_pte_prot()
skips emulation if the address being mapped is in the kernel. However,
this is not really the right condition to test for. There do exist some
managed pages in the kernel address space, and it is also possible
through System V shared memory to have unmanaged pages in the user
address space. The attached patch bases the emulation decision on
whether the page is managed.
Thanks,
Alan
-------------- next part --------------
Index: mips/mips/pmap.c
===================================================================
--- mips/mips/pmap.c (revision 208667)
+++ mips/mips/pmap.c (working copy)
@@ -3067,26 +3067,20 @@ page_is_managed(vm_offset_t pa)
static int
init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot)
{
- int rw = 0;
+ int rw;
if (!(prot & VM_PROT_WRITE))
rw = PTE_ROPAGE;
- else {
- if (va >= VM_MIN_KERNEL_ADDRESS) {
- /*
- * Don't bother to trap on kernel writes, just
- * record page as dirty.
- */
+ else if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
+ if ((m->md.pv_flags & PV_TABLE_MOD) != 0)
rw = PTE_RWPAGE;
- vm_page_dirty(m);
- } else if ((m->md.pv_flags & PV_TABLE_MOD) ||
- m->dirty == VM_PAGE_BITS_ALL)
- rw = PTE_RWPAGE;
else
rw = PTE_CWPAGE;
vm_page_flag_set(m, PG_WRITEABLE);
- }
- return rw;
+ } else
+ /* Needn't emulate a modified bit for unmanaged pages. */
+ rw = PTE_RWPAGE;
+ return (rw);
}
/*
More information about the freebsd-mips
mailing list