diff --git a/build/config_headers/tracing_config.h b/build/config_headers/tracing_config.h index b6d2498db5..b8571d4aaa 100644 --- a/build/config_headers/tracing_config.h +++ b/build/config_headers/tracing_config.h @@ -34,6 +34,7 @@ #define RUNTIME_LOADER_TRACING 0 #define SCHEDULER_TRACING 0 #define SIGNAL_TRACING 0 +#define SWAP_TRACING 0 #define SYSCALL_TRACING 0 #define SYSCALL_TRACING_IGNORE_KTRACE_OUTPUT 1 #define TCP_TRACING 0 diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp index 0bbb59fb9c..59bb48c29f 100644 --- a/src/system/kernel/vm/VMAnonymousCache.cpp +++ b/src/system/kernel/vm/VMAnonymousCache.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -147,6 +148,78 @@ static mutex sAvailSwapSpaceLock; static object_cache *sSwapBlockCache; +#if SWAP_TRACING +namespace SwapTracing { + +class SwapTraceEntry : public AbstractTraceEntry { +public: + SwapTraceEntry(VMAnonymousCache* cache) + : + fCache(cache) + { + } + +protected: + VMAnonymousCache* fCache; +}; + + +class ReadPage : public SwapTraceEntry { +public: + ReadPage(VMAnonymousCache* cache, page_num_t pageIndex, + swap_addr_t swapSlotIndex) + : + SwapTraceEntry(cache), + fPageIndex(pageIndex), + fSwapSlotIndex(swapSlotIndex) + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("swap read: cache %p, page index: %lu <- swap slot: %lu", + fCache, fPageIndex, fSwapSlotIndex); + } + +private: + page_num_t fPageIndex; + swap_addr_t fSwapSlotIndex; +}; + + +class WritePage : public SwapTraceEntry { +public: + WritePage(VMAnonymousCache* cache, page_num_t pageIndex, + swap_addr_t swapSlotIndex) + : + SwapTraceEntry(cache), + fPageIndex(pageIndex), + fSwapSlotIndex(swapSlotIndex) + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("swap write: cache %p, page index: %lu -> swap slot: %lu", + fCache, fPageIndex, fSwapSlotIndex); + } + +private: + page_num_t fPageIndex; + swap_addr_t fSwapSlotIndex; +}; + +} // namespace SwapTracing + +# define T(x) new(std::nothrow) SwapTracing::x; +#else +# define T(x) ; +#endif + + + static int dump_swap_info(int argc, char** argv) { @@ -488,6 +561,9 @@ VMAnonymousCache::Read(off_t offset, const iovec *vecs, size_t count, break; } + T(ReadPage(this, pageIndex, startSlotIndex)); + // TODO: Assumes that only one page is read. + swap_file *swapFile = find_swap_file(startSlotIndex); off_t pos = (startSlotIndex - swapFile->first_slot) * B_PAGE_SIZE; @@ -534,6 +610,9 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count, if (slotIndex == SWAP_SLOT_NONE) panic("VMAnonymousCache::Write(): can't allocate swap space\n"); + T(WritePage(this, pageIndex, slotIndex)); + // TODO: Assumes that only one page is written. + swap_file *swapFile = find_swap_file(slotIndex); off_t pos = (slotIndex - swapFile->first_slot) * B_PAGE_SIZE; @@ -603,6 +682,8 @@ VMAnonymousCache::WriteAsync(off_t offset, const iovec* vecs, size_t count, callback->SetTo(pageIndex, slotIndex, newSlot); + T(WritePage(this, pageIndex, slotIndex)); + // write the page asynchrounously swap_file* swapFile = find_swap_file(slotIndex); off_t pos = (slotIndex - swapFile->first_slot) * B_PAGE_SIZE;