opnsense-src/sys/vm
Alan Cox b5e8f167b9 Consider a scenario in which one processor, call it Pt, is performing
vm_object_terminate() on a device-backed object at the same time that
another processor, call it Pa, is performing dev_pager_alloc() on the
same device.  The problem is that vm_pager_object_lookup() should not be
allowed to return a doomed object, i.e., an object with OBJ_DEAD set,
but it does.  In detail, the unfortunate sequence of events is: Pt in
vm_object_terminate() holds the doomed object's lock and sets OBJ_DEAD
on the object.  Pa in dev_pager_alloc() holds dev_pager_sx and calls
vm_pager_object_lookup(), which returns the doomed object.  Next, Pa
calls vm_object_reference(), which requires the doomed object's lock, so
Pa waits for Pt to release the doomed object's lock.  Pt proceeds to the
point in vm_object_terminate() where it releases the doomed object's
lock.  Pa is now able to complete vm_object_reference() because it can
now complete the acquisition of the doomed object's lock.  So, now the
doomed object has a reference count of one!  Pa releases dev_pager_sx
and returns the doomed object from dev_pager_alloc().  Pt now acquires
dev_pager_mtx, removes the doomed object from dev_pager_object_list,
releases dev_pager_mtx, and finally calls uma_zfree with the doomed
object.  However, the doomed object is still in use by Pa.

Repeating my key point, vm_pager_object_lookup() must not return a
doomed object.  Moreover, the test for the object's state, i.e.,
doomed or not, and the increment of the object's reference count
should be carried out atomically.

Reviewed by:	kib
Approved by:	re (kensmith)
MFC after:	3 weeks
2007-08-05 21:04:32 +00:00
..
default_pager.c /* -> /*- for license, minor formatting changes 2005-01-07 02:29:27 +00:00
device_pager.c Consider a scenario in which one processor, call it Pt, is performing 2007-08-05 21:04:32 +00:00
memguard.c Improve memguard a bit: 2005-12-30 11:45:07 +00:00
memguard.h Improve memguard a bit: 2005-12-30 11:45:07 +00:00
phys_pager.c Consider a scenario in which one processor, call it Pt, is performing 2007-08-05 21:04:32 +00:00
pmap.h Complete the transition from pmap_page_protect() to pmap_remove_write(). 2006-08-01 19:06:06 +00:00
redzone.c Add buffer corruption protection (RedZone) for kernel's malloc(9). 2006-01-31 11:09:21 +00:00
redzone.h Add buffer corruption protection (RedZone) for kernel's malloc(9). 2006-01-31 11:09:21 +00:00
swap_pager.c Consider a scenario in which one processor, call it Pt, is performing 2007-08-05 21:04:32 +00:00
swap_pager.h - Move 'struct swdevt' back into swap_pager.h and expose it to userland. 2007-02-07 17:43:11 +00:00
uma.h Add uma_set_align() interface, which will be called at most once during 2007-02-11 20:13:52 +00:00
uma_core.c Revert VMCNT_* operations introduction. 2007-05-31 22:52:15 +00:00
uma_dbg.c Improve canonicalization of copyrights. Order copyrights by order of 2005-07-16 09:51:52 +00:00
uma_dbg.h Improve canonicalization of copyrights. Order copyrights by order of 2005-07-16 09:51:52 +00:00
uma_int.h Update stale comment on protecting UMA per-CPU caches: we now use 2007-05-09 22:53:34 +00:00
vm.h Retire debug.mpsafevm. None of the architectures supported in CVS require 2006-07-21 23:22:49 +00:00
vm_contig.c Enable the new physical memory allocator. 2007-06-16 04:57:06 +00:00
vm_extern.h Close race between vmspace_exitfree() and exit1() and races between 2006-05-29 21:28:56 +00:00
vm_fault.c Two changes to vm_fault_additional_pages(): 2007-07-20 06:55:11 +00:00
vm_glue.c Commit 14/14 of sched_lock decomposition. 2007-06-05 00:00:57 +00:00
vm_init.c Add the vm.exec_map_entries tunable and read-only sysctl, which controls 2005-04-25 19:22:05 +00:00
vm_kern.c When KVA is exhausted, try the vm_lowmem event for the last time before 2007-04-05 20:52:51 +00:00
vm_kern.h The clean_map has been made local to vm_init.c long ago. 2006-11-20 16:23:34 +00:00
vm_map.c Revert VMCNT_* operations introduction. 2007-05-31 22:52:15 +00:00
vm_map.h Close race between vmspace_exitfree() and exit1() and races between 2006-05-29 21:28:56 +00:00
vm_meter.c Add a counter for the total number of pages cached and support for 2007-07-27 20:01:22 +00:00
vm_mmap.c Add freebsd6_ wrappers for mmap/lseek/pread/pwrite/truncate/ftruncate 2007-07-04 22:57:21 +00:00
vm_object.c Enable the new physical memory allocator. 2007-06-16 04:57:06 +00:00
vm_object.h Eliminate OBJ_WRITEABLE. It hasn't been used in a long time. 2006-07-21 06:40:29 +00:00
vm_page.c Add a counter for the total number of pages cached and support for 2007-07-27 20:01:22 +00:00
vm_page.h Update a comment describing the page queues. 2007-07-13 04:42:20 +00:00
vm_pageout.c In the previous revision, when I replaced the unconditional acquisition 2007-07-02 06:56:37 +00:00
vm_pageout.h /* -> /*- for license, minor formatting changes 2005-01-07 02:29:27 +00:00
vm_pageq.c Enable the new physical memory allocator. 2007-06-16 04:57:06 +00:00
vm_pager.c Consider a scenario in which one processor, call it Pt, is performing 2007-08-05 21:04:32 +00:00
vm_pager.h Update some comments to reflect the change from spl-based to lock-based 2005-05-18 22:08:52 +00:00
vm_param.h Correct two comments. 2007-04-19 04:52:47 +00:00
vm_phys.c Eliminate two unused functions: vm_phys_alloc_pages() and 2007-07-14 21:21:17 +00:00
vm_phys.h Eliminate two unused functions: vm_phys_alloc_pages() and 2007-07-14 21:21:17 +00:00
vm_unix.c /* -> /*- for license, minor formatting changes 2005-01-07 02:29:27 +00:00
vm_zeroidle.c Eliminate dead code, specifically, an unused sysctl: "vm.idlezero_maxrun". 2007-07-14 19:00:44 +00:00
vnode_pager.c When we do open, we should lock the vnode exclusively. This fixes few races: 2007-07-26 16:58:09 +00:00
vnode_pager.h Move the body of vop_stdcreatevobject() over to the vnode_pager under 2005-01-24 21:21:59 +00:00