kernel/vm: Fix double-read-lock in user_set_memory_swappable.
lock_memory_etc also acquires the address space read lock. So, just perform that step first and separately from the loop. Discovered by the RW_LOCK_DEBUG assertions.
This commit is contained in:
@@ -6701,8 +6701,13 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable)
|
|||||||
|
|
||||||
const addr_t endAddress = address + size;
|
const addr_t endAddress = address + size;
|
||||||
|
|
||||||
|
status_t error = lock_memory_etc(B_CURRENT_TEAM,
|
||||||
|
(void*)address, endAddress - address, 0);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
AddressSpaceReadLocker addressSpaceLocker;
|
AddressSpaceReadLocker addressSpaceLocker;
|
||||||
status_t error = addressSpaceLocker.SetTo(team_get_current_team_id());
|
error = addressSpaceLocker.SetTo(team_get_current_team_id());
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
VMAddressSpace* addressSpace = addressSpaceLocker.AddressSpace();
|
VMAddressSpace* addressSpace = addressSpaceLocker.AddressSpace();
|
||||||
@@ -6721,12 +6726,6 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable)
|
|||||||
const addr_t areaEnd = std::min(endAddress, area->Base() + area->Size());
|
const addr_t areaEnd = std::min(endAddress, area->Base() + area->Size());
|
||||||
nextAddress = areaEnd;
|
nextAddress = areaEnd;
|
||||||
|
|
||||||
error = lock_memory_etc(addressSpace->ID(), (void*)areaStart, areaEnd - areaStart, 0);
|
|
||||||
if (error != B_OK) {
|
|
||||||
// We don't need to unset or reset things on failure.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
VMCacheChainLocker cacheChainLocker(vm_area_get_locked_cache(area));
|
VMCacheChainLocker cacheChainLocker(vm_area_get_locked_cache(area));
|
||||||
VMAnonymousCache* anonCache = NULL;
|
VMAnonymousCache* anonCache = NULL;
|
||||||
if (dynamic_cast<VMAnonymousNoSwapCache*>(area->cache) != NULL) {
|
if (dynamic_cast<VMAnonymousNoSwapCache*>(area->cache) != NULL) {
|
||||||
@@ -6740,12 +6739,15 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cacheChainLocker.Unlock();
|
cacheChainLocker.Unlock();
|
||||||
|
|
||||||
unlock_memory_etc(addressSpace->ID(), (void*)areaStart, areaEnd - areaStart, 0);
|
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addressSpaceLocker.Unlock();
|
||||||
|
|
||||||
|
unlock_memory_etc(B_CURRENT_TEAM,
|
||||||
|
(void*)address, endAddress - address, 0);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
#else
|
#else
|
||||||
// No swap support? Nothing to do.
|
// No swap support? Nothing to do.
|
||||||
|
|||||||
Reference in New Issue
Block a user