In case the source cache of the current vm_cache_ref was in the process of
being merged in vm_cache_remove_consumer(), fault_find_page() tried again with the current vm_cache_ref, but didn't realize it might have had inserted a busy page in this cache already. This fixes a deadlock, as this page would never get unbusy again. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20470 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3215,8 +3215,7 @@ fault_find_page(vm_translation_map *map, vm_cache_ref *topCacheRef,
|
|||||||
vm_page_set_state(page, PAGE_STATE_BUSY);
|
vm_page_set_state(page, PAGE_STATE_BUSY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (page == NULL || page == &dummyPage)
|
||||||
if (page == NULL)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// page must be busy
|
// page must be busy
|
||||||
@@ -3226,14 +3225,14 @@ fault_find_page(vm_translation_map *map, vm_cache_ref *topCacheRef,
|
|||||||
mutex_lock(&cacheRef->lock);
|
mutex_lock(&cacheRef->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page != NULL)
|
if (page != NULL && page != &dummyPage)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// The current cache does not contain the page we're looking for
|
// The current cache does not contain the page we're looking for
|
||||||
|
|
||||||
// If we're at the top most cache, insert the dummy page here to keep other threads
|
// If we're at the top most cache, insert the dummy page here to keep other threads
|
||||||
// from faulting on the same address and chasing us up the cache chain
|
// from faulting on the same address and chasing us up the cache chain
|
||||||
if (cacheRef == topCacheRef)
|
if (cacheRef == topCacheRef && dummyPage.state != PAGE_STATE_BUSY)
|
||||||
fault_insert_dummy_page(cacheRef, dummyPage, cacheOffset);
|
fault_insert_dummy_page(cacheRef, dummyPage, cacheOffset);
|
||||||
|
|
||||||
// see if the vm_store has it
|
// see if the vm_store has it
|
||||||
|
|||||||
Reference in New Issue
Block a user