History

mm: balance LRU lists based on relative thrashing

Since the LRUs were split into anon and file lists, the VM has been balancing between page cache and anonymous pages based on per-list ratios of scanned vs. rotated pages. In most cases that tips page reclaim towards the list that is easier to reclaim and has the fewest actively used pages, but there are a few problems with it: 1. Refaults and LRU rotations are weighted the same way, even though one costs IO and the other costs a bit of CPU. 2. The less we scan an LRU list based on already observed rotations, the more we increase the sampling interval for new references, and rotations become even more likely on that list. This can enter a death spiral in which we stop looking at one list completely until the other one is all but annihilated by page reclaim. Since commit a528910e12ec ("mm: thrash detection-based file cache sizing") we have refault detection for the page cache. Along with swapin events, they are good indicators of when the file or anon list, respectively, is too small for its workingset and needs to grow. For example, if the page cache is thrashing, the cache pages need more time in memory, while there may be colder pages on the anonymous list. Likewise, if swapped pages are faulting back in, it indicates that we reclaim anonymous pages too aggressively and should back off. Replace LRU rotations with refaults and swapins as the basis for relative reclaim cost of the two LRUs. This will have the VM target list balances that incur the least amount of IO on aggregate.

Johannes Weiner committed 6 years ago

Commit 314b57f1 parent 264e90c5 files · +27 −35Browse files

Showing the changes to include/linux (1 of 5 files). Show all

Unified · Split

include/linux/swap.h+1−2
@@ -334,8 +334,7 @@ extern unsigned long nr_free_pagecache_pages(void); · 333 unmodified lines
334 334
335 335
336/* linux/mm/swap.c */336/* linux/mm/swap.c */
337extern void lru_note_cost(struct lruvec *lruvec, bool file,337extern void lru_note_cost(struct page *);
338 unsigned int nr_pages);
339extern void lru_cache_add(struct page *);338extern void lru_cache_add(struct page *);
340extern void lru_add_page_tail(struct page *page, struct page *page_tail,339extern void lru_add_page_tail(struct page *page, struct page *page_tail,
341 struct lruvec *lruvec, struct list_head *head);340 struct lruvec *lruvec, struct list_head *head);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t