From d62afe7ab01c79574766f6abd08cee1d00819579 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 28 Apr 2010 22:06:40 +0000 Subject: [PATCH] VMUserAddressSpace::LookupArea(): Although only a read-lock is the precondition for calling the function it read/write accessed the fAreaHint attribute in a non-atomic manner. I.e. if executed concurrently by two threads of the same team one could return the wrong area. The most likely problem could be caused in vm_soft_fault(), leading to pages being added to the wrong caches. The bug itself is inherited from NewOS, but is triggered way more likely since the page daemon unmaps inactive pages (r35485). Probably fixes #5413. Might also fix the sporadically occurring crashes/asserts in the hoard allocator -- at least inactive pages being replaced by zeroed ones would be an excellent explanation. [Thanks to Matt for providing remote debug access to his machine.] git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36523 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/vm/VMUserAddressSpace.cpp | 8 +++++--- src/system/kernel/vm/VMUserAddressSpace.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index 94b266466f..038a45cbc6 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -95,8 +96,9 @@ VMArea* VMUserAddressSpace::LookupArea(addr_t address) const { // check the area hint first - if (fAreaHint != NULL && fAreaHint->ContainsAddress(address)) - return fAreaHint; + VMArea* areaHint = atomic_pointer_get(&fAreaHint); + if (areaHint != NULL && areaHint->ContainsAddress(address)) + return areaHint; for (VMUserAreaList::ConstIterator it = fAreas.GetIterator(); VMUserArea* area = it.Next();) { @@ -104,7 +106,7 @@ VMUserAddressSpace::LookupArea(addr_t address) const continue; if (area->ContainsAddress(address)) { - fAreaHint = area; + atomic_pointer_set(&fAreaHint, area); return area; } } diff --git a/src/system/kernel/vm/VMUserAddressSpace.h b/src/system/kernel/vm/VMUserAddressSpace.h index 052c399373..fc51459a14 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.h +++ b/src/system/kernel/vm/VMUserAddressSpace.h @@ -58,8 +58,8 @@ private: VMUserArea* area, uint32 allocationFlags); private: - VMUserAreaList fAreas; - mutable VMArea* fAreaHint; + VMUserAreaList fAreas; + mutable VMUserArea* fAreaHint; };