kernel - Do not call pmap_enter() in vm_fault_page*()
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 16 Nov 2011 17:12:58 +0000 (09:12 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 16 Nov 2011 17:33:31 +0000 (09:33 -0800)
commit385c96e4b70a5753a404c12377398d39a3a1bf84
tree763f8f192d17cae58c86c069c61920866628700a
parentd64d3805b8fed58f561caac73c40fa8f8be03d1b
kernel - Do not call pmap_enter() in vm_fault_page*()

* Do not call pmap_enter() from vm_fault_page*().  This function can be
  called from foreign pmap contexts and thus the current cpu's bit may
  not be set in the target pmap cpumask.  Any pmap_enter() operation will
  thus not properly synchronize with other users of the pmap (particularly
  other foreign users).

* In addition, for callers of the umtx*() function calling pmap_enter()
  is inefficient as the correct page might already be faulted in.  Now
  because we are no longer updating the page in the pmap an older page
  may still exist in the pmap (mapped read-only as it was originally COW).

  This page may no longer be correct because the umtx*() functions
  modify the contend of the page returned by vm_fault_page() without
  necessarily mapping it.  So to keep the user visibility into the memory
  correct we unmap the old page when vm_fault_page() has to do a COW.

  This is slightly more burdensome for fork() but far less burdomsome
  for the umtx system calls and also allows procfs_memrw to work properly.

* procfs uses vm_fault_page*() to access command line arguments for
  any process and umtx*() uses it to access the memory page the umtx
  is operating in.  Relative to procfs the user process pmap is foreign
  (i.e. the current cpu's bit is not set in its pm_active) and cannot
  be properly updated via a vm_fault_page*() from procfs anyway, so the
  above new behavior for vm_fault_page*() is even more correct for
  procfs use cases.
sys/vm/vm_fault.c