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:
parent
ca34b4221c
commit
d62afe7ab0
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <heap.h>
|
#include <heap.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
|
#include <util/atomic.h>
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/VMArea.h>
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
@ -95,8 +96,9 @@ VMArea*
|
|||||||
VMUserAddressSpace::LookupArea(addr_t address) const
|
VMUserAddressSpace::LookupArea(addr_t address) const
|
||||||
{
|
{
|
||||||
// check the area hint first
|
// check the area hint first
|
||||||
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
|
VMArea* areaHint = atomic_pointer_get(&fAreaHint);
|
||||||
return fAreaHint;
|
if (areaHint != NULL && areaHint->ContainsAddress(address))
|
||||||
|
return areaHint;
|
||||||
|
|
||||||
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
|
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
|
||||||
VMUserArea* area = it.Next();) {
|
VMUserArea* area = it.Next();) {
|
||||||
@ -104,7 +106,7 @@ VMUserAddressSpace::LookupArea(addr_t address) const
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (area->ContainsAddress(address)) {
|
if (area->ContainsAddress(address)) {
|
||||||
fAreaHint = area;
|
atomic_pointer_set(&fAreaHint, area);
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,8 @@ private:
|
|||||||
VMUserArea* area, uint32 allocationFlags);
|
VMUserArea* area, uint32 allocationFlags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMUserAreaList fAreas;
|
VMUserAreaList fAreas;
|
||||||
mutable VMArea* fAreaHint;
|
mutable VMUserArea* fAreaHint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user