diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 47a3441cf4c4..d29dd5fef8d2 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -22,7 +22,11 @@ #define FOR_ALL_ZONES(xx) DMA_ZONE(xx) DMA32_ZONE(xx) xx##_NORMAL, HIGHMEM_ZONE(xx) xx##_MOVABLE -enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, +enum vm_event_item { PGPGIN, PGPGOUT, +#ifdef CONFIG_VM_EVENT_COUNT_CLEAN_PAGE_RECLAIM + PGPGOUTCLEAN, +#endif + PSWPIN, PSWPOUT, FOR_ALL_ZONES(PGALLOC), FOR_ALL_ZONES(ALLOCSTALL), FOR_ALL_ZONES(PGSCAN_SKIP), diff --git a/init/Kconfig b/init/Kconfig index ec2127b69683..665453aa3866 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1779,6 +1779,18 @@ config VM_EVENT_COUNTERS on EXPERT systems. /proc/vmstat will only show page counts if VM event counters are disabled. +config VM_EVENT_COUNT_CLEAN_PAGE_RECLAIM + bool "Track the number of clean pages reclaimed from the page cache" + depends on VM_EVENT_COUNTERS + help + VM event counters currently maintain a count of the pages that + get dropped from the page cache as a part of memory reclaim. + However, this count only tracks the number of dirty pages that + get dropped, and does not account for the clean pages that get + dropped as well. Enable this to also account for the clean pages + that get dropped as part of memory reclaim to get a more holistic + view of what is happening during memory reclaim. + config SLUB_DEBUG default y bool "Enable SLUB debugging support" if EXPERT diff --git a/mm/filemap.c b/mm/filemap.c index 85b7d087eb45..a23131606774 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -153,6 +153,17 @@ static void page_cache_delete(struct address_space *mapping, mapping->nrpages -= nr; } +#ifdef CONFIG_VM_EVENT_COUNT_CLEAN_PAGE_RECLAIM +static void count_vm_event_clean_page_put(void) +{ + count_vm_event(PGPGOUTCLEAN); +} +#else +static void count_vm_event_clean_page_put(void) +{ +} +#endif + static void unaccount_page_cache_page(struct address_space *mapping, struct page *page) { @@ -163,10 +174,12 @@ static void unaccount_page_cache_page(struct address_space *mapping, * invalidate any existing cleancache entries. We can't leave * stale data around in the cleancache once our page is gone */ - if (PageUptodate(page) && PageMappedToDisk(page)) + if (PageUptodate(page) && PageMappedToDisk(page)) { + count_vm_event_clean_page_put(); cleancache_put_page(page); - else + } else { cleancache_invalidate_page(mapping, page); + } VM_BUG_ON_PAGE(PageTail(page), page); VM_BUG_ON_PAGE(page_mapped(page), page); diff --git a/mm/vmstat.c b/mm/vmstat.c index 9c1e5fa99032..e61dd4ee58c5 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1176,6 +1176,9 @@ const char * const vmstat_text[] = { /* enum vm_event_item counters */ "pgpgin", "pgpgout", +#ifdef CONFIG_VM_EVENT_COUNT_CLEAN_PAGE_RECLAIM + "pgpgoutclean", +#endif "pswpin", "pswpout",