Fix the computation of used memory and add a TODO.
* The altered used pages calculation of hrev43168 wasn't correct, as the inactive page queue may (validly) contain mapped pages as well. Those would then get counted twice (as they are included in gMappedPagesCount already). Instead we calculate the used pages from the total page count, minus everything we account for otherwise. Doing it this way is possible without introducing any additional counters, as all the counts to subtract are already present (as opposed to some of the ones that would be needed for adding the counts up). Fixes #8109. * Added TODO regarding the problem of not locking any of the counters which runs the risk of them getting modified while we haven't yet read all of them.
This commit is contained in:
parent
3b1791fa15
commit
3733c51d38
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user