* Added kernel tracing for insertion and removal of cache pages (tracing

level 2).
* merge_cache_with_only_consumer() marked the source cache unbusy when
  it was done, which caused a race condition with the page fault code.
  I accidentally introduced this problem in r25716. Fixes #2326.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26068 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-06-21 21:08:07 +00:00
parent efec339946
commit 0b4dac74e0
+64 -1
View File
@@ -259,8 +259,63 @@ class RemoveArea : public VMCacheTraceEntry {
} // namespace VMCacheTracing
# define T(x) new(std::nothrow) VMCacheTracing::x;
# if VM_CACHE_TRACING >= 2
namespace VMCacheTracing {
class InsertPage : public VMCacheTraceEntry {
public:
InsertPage(vm_cache* cache, vm_page* page, off_t offset)
:
VMCacheTraceEntry(cache),
fPage(page),
fOffset(offset)
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("vm cache insert page: cache: %p, page: %p, offset: %lld",
fCache, fPage, fOffset);
}
private:
vm_page* fPage;
off_t fOffset;
};
class RemovePage : public VMCacheTraceEntry {
public:
RemovePage(vm_cache* cache, vm_page* page)
:
VMCacheTraceEntry(cache),
fPage(page)
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("vm cache remove page: cache: %p, page: %p", fCache,
fPage);
}
private:
vm_page* fPage;
};
} // namespace VMCacheTracing
# define T2(x) new(std::nothrow) VMCacheTracing::x;
# else
# define T2(x) ;
# endif
#else
# define T(x) ;
# define T2(x) ;
#endif
@@ -510,7 +565,11 @@ if (cache->ref_count < 2)
panic("cacheRef %p ref count too low!\n", cache);
vm_cache_release_ref(cache);
cache->busy = false;
// Unpublishing the condition variable will wake up all threads waiting for
// the cache. It will still remain marked busy, though. In fact "busy" is
// a misnomer, since it actually means "to be deleted". Any thread we woke
// up will not touch the cache anymore, but release its reference and retry
// the hierarchy (cf. fault_find_page()).
busyCondition.Unpublish();
mutex_unlock(&consumer->lock);
@@ -699,6 +758,8 @@ vm_cache_insert_page(vm_cache* cache, vm_page* page, off_t offset)
page, cache, page->cache);
}
T2(InsertPage(cache, page, offset));
page->cache_offset = (uint32)(offset >> PAGE_SHIFT);
if (cache->page_list != NULL)
@@ -746,6 +807,8 @@ vm_cache_remove_page(vm_cache* cache, vm_page* page)
cache, page->cache);
}
T2(RemovePage(cache, page));
cpu_status state = disable_interrupts();
acquire_spinlock(&sPageCacheTableLock);