diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index 56b94ec6b2..559aace6e1 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -4053,13 +4053,9 @@ vm_page_num_unused_pages(void) void vm_page_get_stats(system_info *info) { - // Get free pages count -- not really exact, since we don't know how many - // of the reserved pages have already been allocated, but good citizens - // unreserve chunk-wise as they are allocating the pages, if they have - // reserved a larger quantity. - int32 free = sUnreservedFreePages; - if (free < 0) - free = 0; + // TODO: there's no locking protecting any of the queues or counters here, + // so we run the risk of getting bogus values when evaluating them at + // throughout this function... // The pages used for the block cache buffers. Those should not be counted // as used but as cached pages. @@ -4067,11 +4063,25 @@ vm_page_get_stats(system_info *info) // can't really be freed in a low memory situation. page_num_t blockCachePages = block_cache_used_memory() / B_PAGE_SIZE; - info->max_pages = sNumPages - sNonExistingPages; - info->used_pages = gMappedPagesCount + sInactivePageQueue.Count() - - blockCachePages; - info->cached_pages = info->max_pages >= free + info->used_pages - ? info->max_pages - free - info->used_pages : 0; + // Non-temporary modified pages are special as they represent pages that + // can be written back, so they could be freed if necessary, for us + // basically making them into cached pages with a higher overhead. The + // modified queue count is therefore split into temporary and non-temporary + // counts that are then added to the corresponding number. + page_num_t modifiedNonTemporaryPages + = (sModifiedPageQueue.Count() - sModifiedTemporaryPages); + + info->max_pages = vm_page_num_pages(); + info->cached_pages = sCachedPageQueue.Count() + modifiedNonTemporaryPages + + blockCachePages; + + // max_pages is composed of: + // active + inactive + unused + wired + modified + cached + free + clear + // So taking out the cached (including modified non-temporary), free and + // clear ones leaves us with all used pages. + info->used_pages = info->max_pages - info->cached_pages + - sFreePageQueue.Count() - sClearPageQueue.Count(); + info->page_faults = vm_num_page_faults(); info->ignored_pages = sIgnoredPages;