Skip to content

Commit 170b04b

Browse files
JoonsooKimtorvalds
authored andcommitted
mm/workingset: prepare the workingset detection infrastructure for anon LRU
To prepare the workingset detection for anon LRU, this patch splits workingset event counters for refault, activate and restore into anon and file variants, as well as the refaults counter in struct lruvec. Signed-off-by: Joonsoo Kim <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Acked-by: Johannes Weiner <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Minchan Kim <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent b518154 commit 170b04b

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

include/linux/mmzone.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,15 @@ enum node_stat_item {
173173
NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
174174
NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
175175
WORKINGSET_NODES,
176-
WORKINGSET_REFAULT,
177-
WORKINGSET_ACTIVATE,
178-
WORKINGSET_RESTORE,
176+
WORKINGSET_REFAULT_BASE,
177+
WORKINGSET_REFAULT_ANON = WORKINGSET_REFAULT_BASE,
178+
WORKINGSET_REFAULT_FILE,
179+
WORKINGSET_ACTIVATE_BASE,
180+
WORKINGSET_ACTIVATE_ANON = WORKINGSET_ACTIVATE_BASE,
181+
WORKINGSET_ACTIVATE_FILE,
182+
WORKINGSET_RESTORE_BASE,
183+
WORKINGSET_RESTORE_ANON = WORKINGSET_RESTORE_BASE,
184+
WORKINGSET_RESTORE_FILE,
179185
WORKINGSET_NODERECLAIM,
180186
NR_ANON_MAPPED, /* Mapped anonymous pages */
181187
NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
@@ -277,8 +283,8 @@ struct lruvec {
277283
unsigned long file_cost;
278284
/* Non-resident age, driven by LRU movement */
279285
atomic_long_t nonresident_age;
280-
/* Refaults at the time of last reclaim cycle */
281-
unsigned long refaults;
286+
/* Refaults at the time of last reclaim cycle, anon=0, file=1 */
287+
unsigned long refaults[2];
282288
/* Various lruvec state flags (enum lruvec_flags) */
283289
unsigned long flags;
284290
#ifdef CONFIG_MEMCG

mm/memcontrol.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,12 +1530,18 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
15301530
seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGMAJFAULT),
15311531
memcg_events(memcg, PGMAJFAULT));
15321532

1533-
seq_buf_printf(&s, "workingset_refault %lu\n",
1534-
memcg_page_state(memcg, WORKINGSET_REFAULT));
1535-
seq_buf_printf(&s, "workingset_activate %lu\n",
1536-
memcg_page_state(memcg, WORKINGSET_ACTIVATE));
1533+
seq_buf_printf(&s, "workingset_refault_anon %lu\n",
1534+
memcg_page_state(memcg, WORKINGSET_REFAULT_ANON));
1535+
seq_buf_printf(&s, "workingset_refault_file %lu\n",
1536+
memcg_page_state(memcg, WORKINGSET_REFAULT_FILE));
1537+
seq_buf_printf(&s, "workingset_activate_anon %lu\n",
1538+
memcg_page_state(memcg, WORKINGSET_ACTIVATE_ANON));
1539+
seq_buf_printf(&s, "workingset_activate_file %lu\n",
1540+
memcg_page_state(memcg, WORKINGSET_ACTIVATE_FILE));
15371541
seq_buf_printf(&s, "workingset_restore %lu\n",
1538-
memcg_page_state(memcg, WORKINGSET_RESTORE));
1542+
memcg_page_state(memcg, WORKINGSET_RESTORE_ANON));
1543+
seq_buf_printf(&s, "workingset_restore %lu\n",
1544+
memcg_page_state(memcg, WORKINGSET_RESTORE_FILE));
15391545
seq_buf_printf(&s, "workingset_nodereclaim %lu\n",
15401546
memcg_page_state(memcg, WORKINGSET_NODERECLAIM));
15411547

mm/vmscan.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,10 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
26832683
if (!sc->force_deactivate) {
26842684
unsigned long refaults;
26852685

2686-
if (inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
2686+
refaults = lruvec_page_state(target_lruvec,
2687+
WORKINGSET_ACTIVATE_ANON);
2688+
if (refaults != target_lruvec->refaults[0] ||
2689+
inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
26872690
sc->may_deactivate |= DEACTIVATE_ANON;
26882691
else
26892692
sc->may_deactivate &= ~DEACTIVATE_ANON;
@@ -2694,8 +2697,8 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
26942697
* rid of any stale active pages quickly.
26952698
*/
26962699
refaults = lruvec_page_state(target_lruvec,
2697-
WORKINGSET_ACTIVATE);
2698-
if (refaults != target_lruvec->refaults ||
2700+
WORKINGSET_ACTIVATE_FILE);
2701+
if (refaults != target_lruvec->refaults[1] ||
26992702
inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
27002703
sc->may_deactivate |= DEACTIVATE_FILE;
27012704
else
@@ -2972,8 +2975,10 @@ static void snapshot_refaults(struct mem_cgroup *target_memcg, pg_data_t *pgdat)
29722975
unsigned long refaults;
29732976

29742977
target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
2975-
refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE);
2976-
target_lruvec->refaults = refaults;
2978+
refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON);
2979+
target_lruvec->refaults[0] = refaults;
2980+
refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_FILE);
2981+
target_lruvec->refaults[1] = refaults;
29772982
}
29782983

29792984
/*

mm/vmstat.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,9 +1167,12 @@ const char * const vmstat_text[] = {
11671167
"nr_isolated_anon",
11681168
"nr_isolated_file",
11691169
"workingset_nodes",
1170-
"workingset_refault",
1171-
"workingset_activate",
1172-
"workingset_restore",
1170+
"workingset_refault_anon",
1171+
"workingset_refault_file",
1172+
"workingset_activate_anon",
1173+
"workingset_activate_file",
1174+
"workingset_restore_anon",
1175+
"workingset_restore_file",
11731176
"workingset_nodereclaim",
11741177
"nr_anon_pages",
11751178
"nr_mapped",

mm/workingset.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/memcontrol.h>
9+
#include <linux/mm_inline.h>
910
#include <linux/writeback.h>
1011
#include <linux/shmem_fs.h>
1112
#include <linux/pagemap.h>
@@ -280,6 +281,7 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
280281
*/
281282
void workingset_refault(struct page *page, void *shadow)
282283
{
284+
bool file = page_is_file_lru(page);
283285
struct mem_cgroup *eviction_memcg;
284286
struct lruvec *eviction_lruvec;
285287
unsigned long refault_distance;
@@ -346,7 +348,7 @@ void workingset_refault(struct page *page, void *shadow)
346348
memcg = page_memcg(page);
347349
lruvec = mem_cgroup_lruvec(memcg, pgdat);
348350

349-
inc_lruvec_state(lruvec, WORKINGSET_REFAULT);
351+
inc_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + file);
350352

351353
/*
352354
* Compare the distance to the existing workingset size. We
@@ -366,7 +368,7 @@ void workingset_refault(struct page *page, void *shadow)
366368

367369
SetPageActive(page);
368370
workingset_age_nonresident(lruvec, hpage_nr_pages(page));
369-
inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE);
371+
inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + file);
370372

371373
/* Page was active prior to eviction */
372374
if (workingset) {
@@ -375,7 +377,7 @@ void workingset_refault(struct page *page, void *shadow)
375377
spin_lock_irq(&page_pgdat(page)->lru_lock);
376378
lru_note_cost_page(page);
377379
spin_unlock_irq(&page_pgdat(page)->lru_lock);
378-
inc_lruvec_state(lruvec, WORKINGSET_RESTORE);
380+
inc_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + file);
379381
}
380382
out:
381383
rcu_read_unlock();

0 commit comments

Comments
 (0)