From 88799a5d976b5c799c8484c8d72d7495e4690170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 30 Jun 2007 13:49:31 +0000 Subject: [PATCH] An almost complete overview over the VM locking/reference count methods and their inherent problems. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21528 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- docs/develop/kernel/VM_Locking | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs/develop/kernel/VM_Locking diff --git a/docs/develop/kernel/VM_Locking b/docs/develop/kernel/VM_Locking new file mode 100644 index 0000000000..db2db6073f --- /dev/null +++ b/docs/develop/kernel/VM_Locking @@ -0,0 +1,51 @@ +Locks/Reference Counting: + +vm_address_space: + sem R/W for area creation/deletion and any other address space changes + fields: areas, area_hint (is currently written in vm_area_lookup() without a write lock!), + state + ref_count: ensures validity of object beyond team lifetime, + retrieved via the global sAddressSpaceTable's pointer (which is guarded by + sAddressSpaceHashSem) + vm_address_space_walk_next() is unsafe! (and obsolete, only used by the former + page scanner) + Problems: resize_area() does not lock any address spaces yet, but needs to lock all clones + +vm_area: + ref_count: ensures validity + retrieved via the global sAreaHash's pointer (which is guarded by + sAreaHashLock) + vs. vm_area_lookup() which iterates over the address space's area list, not + the hash - therefore, it checks ref_count against NULL (ugly) + variable fields: + size, protection: essentially unguarded! (can be changed by resize_area() + and set_area_protection()) + mappings: guarded by the global sMappingLock (currently a spinlock) + address_space_next: vm_address_space::sem + hash_next: sAreaHashLock + cache_next|prev: cache_ref::lock + +vm_cache_ref: + ref_count: ensures validity + vm_cache_remove_consumer(): does scary things with the ref_count + fault_acquire_locked_source(): tries to get a ref through the vm_cache + cache, areas: guarded by lock + +vm_cache: + all fields: guarded by ref::lock + BUT: ref may change, therefore it's generally unsafe to go from cache to ref + without holding the ref's lock (which happens, by design, in vm_cache::source + and vm_cache::consumers)! + +vm_page: + hash_next: guarded by sPageCacheTableLock spinlock + queue_prev|next: guarded by sPageLock + cache_prev|next, cache, cache_offset: guarded by vm_cache_ref::lock + mappings: guarded by the global sMappingLock (currently a spinlock) + state: in vm_page only used with the sPageLock held, other uses have the + cache locked the page is in + wired_count, usage_count: not guarded? TBD + busy_reading, busy_writing: dummy pages only + +vm_translation_map: + TBD.