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
This commit is contained in:
Ingo Weinhold 2010-04-28 22:06:40 +00:00
parent ca34b4221c
commit d62afe7ab0
2 changed files with 7 additions and 5 deletions

View File

@ -16,6 +16,7 @@
#include <heap.h>
#include <thread.h>
#include <util/atomic.h>
#include <vm/vm.h>
#include <vm/VMArea.h>
@ -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;
}
}

View File

@ -58,8 +58,8 @@ private:
VMUserArea* area, uint32 allocationFlags);
private:
VMUserAreaList fAreas;
mutable VMArea* fAreaHint;
VMUserAreaList fAreas;
mutable VMUserArea* fAreaHint;
};