Skip to content

Commit f1e1a7b

Browse files
yuzhaogoogleakpm00
authored andcommitted
mm/vmscan.c: refactor shrink_node()
This patch refactors shrink_node() to improve readability for the upcoming changes to mm/vmscan.c. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Yu Zhao <[email protected]> Reviewed-by: Barry Song <[email protected]> Reviewed-by: Miaohe Lin <[email protected]> Acked-by: Brian Geffon <[email protected]> Acked-by: Jan Alexander Steffens (heftig) <[email protected]> Acked-by: Oleksandr Natalenko <[email protected]> Acked-by: Steven Barrett <[email protected]> Acked-by: Suleiman Souhlal <[email protected]> Tested-by: Daniel Byrne <[email protected]> Tested-by: Donald Carr <[email protected]> Tested-by: Holger Hoffstätte <[email protected]> Tested-by: Konstantin Kharlamov <[email protected]> Tested-by: Shuang Zhai <[email protected]> Tested-by: Sofia Trinh <[email protected]> Tested-by: Vaibhav Jain <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Hillf Danton <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Michael Larabel <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Qi Zheng <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent eed9a32 commit f1e1a7b

File tree

1 file changed

+104
-94
lines changed

1 file changed

+104
-94
lines changed

mm/vmscan.c

Lines changed: 104 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,109 @@ enum scan_balance {
27282728
SCAN_FILE,
27292729
};
27302730

2731+
static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc)
2732+
{
2733+
unsigned long file;
2734+
struct lruvec *target_lruvec;
2735+
2736+
target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
2737+
2738+
/*
2739+
* Flush the memory cgroup stats, so that we read accurate per-memcg
2740+
* lruvec stats for heuristics.
2741+
*/
2742+
mem_cgroup_flush_stats();
2743+
2744+
/*
2745+
* Determine the scan balance between anon and file LRUs.
2746+
*/
2747+
spin_lock_irq(&target_lruvec->lru_lock);
2748+
sc->anon_cost = target_lruvec->anon_cost;
2749+
sc->file_cost = target_lruvec->file_cost;
2750+
spin_unlock_irq(&target_lruvec->lru_lock);
2751+
2752+
/*
2753+
* Target desirable inactive:active list ratios for the anon
2754+
* and file LRU lists.
2755+
*/
2756+
if (!sc->force_deactivate) {
2757+
unsigned long refaults;
2758+
2759+
/*
2760+
* When refaults are being observed, it means a new
2761+
* workingset is being established. Deactivate to get
2762+
* rid of any stale active pages quickly.
2763+
*/
2764+
refaults = lruvec_page_state(target_lruvec,
2765+
WORKINGSET_ACTIVATE_ANON);
2766+
if (refaults != target_lruvec->refaults[WORKINGSET_ANON] ||
2767+
inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
2768+
sc->may_deactivate |= DEACTIVATE_ANON;
2769+
else
2770+
sc->may_deactivate &= ~DEACTIVATE_ANON;
2771+
2772+
refaults = lruvec_page_state(target_lruvec,
2773+
WORKINGSET_ACTIVATE_FILE);
2774+
if (refaults != target_lruvec->refaults[WORKINGSET_FILE] ||
2775+
inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
2776+
sc->may_deactivate |= DEACTIVATE_FILE;
2777+
else
2778+
sc->may_deactivate &= ~DEACTIVATE_FILE;
2779+
} else
2780+
sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
2781+
2782+
/*
2783+
* If we have plenty of inactive file pages that aren't
2784+
* thrashing, try to reclaim those first before touching
2785+
* anonymous pages.
2786+
*/
2787+
file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
2788+
if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
2789+
sc->cache_trim_mode = 1;
2790+
else
2791+
sc->cache_trim_mode = 0;
2792+
2793+
/*
2794+
* Prevent the reclaimer from falling into the cache trap: as
2795+
* cache pages start out inactive, every cache fault will tip
2796+
* the scan balance towards the file LRU. And as the file LRU
2797+
* shrinks, so does the window for rotation from references.
2798+
* This means we have a runaway feedback loop where a tiny
2799+
* thrashing file LRU becomes infinitely more attractive than
2800+
* anon pages. Try to detect this based on file LRU size.
2801+
*/
2802+
if (!cgroup_reclaim(sc)) {
2803+
unsigned long total_high_wmark = 0;
2804+
unsigned long free, anon;
2805+
int z;
2806+
2807+
free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
2808+
file = node_page_state(pgdat, NR_ACTIVE_FILE) +
2809+
node_page_state(pgdat, NR_INACTIVE_FILE);
2810+
2811+
for (z = 0; z < MAX_NR_ZONES; z++) {
2812+
struct zone *zone = &pgdat->node_zones[z];
2813+
2814+
if (!managed_zone(zone))
2815+
continue;
2816+
2817+
total_high_wmark += high_wmark_pages(zone);
2818+
}
2819+
2820+
/*
2821+
* Consider anon: if that's low too, this isn't a
2822+
* runaway file reclaim problem, but rather just
2823+
* extreme pressure. Reclaim as per usual then.
2824+
*/
2825+
anon = node_page_state(pgdat, NR_INACTIVE_ANON);
2826+
2827+
sc->file_is_tiny =
2828+
file + free <= total_high_wmark &&
2829+
!(sc->may_deactivate & DEACTIVATE_ANON) &&
2830+
anon >> sc->priority;
2831+
}
2832+
}
2833+
27312834
/*
27322835
* Determine how aggressively the anon and file LRU lists should be
27332836
* scanned.
@@ -3197,109 +3300,16 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
31973300
unsigned long nr_reclaimed, nr_scanned;
31983301
struct lruvec *target_lruvec;
31993302
bool reclaimable = false;
3200-
unsigned long file;
32013303

32023304
target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
32033305

32043306
again:
3205-
/*
3206-
* Flush the memory cgroup stats, so that we read accurate per-memcg
3207-
* lruvec stats for heuristics.
3208-
*/
3209-
mem_cgroup_flush_stats();
3210-
32113307
memset(&sc->nr, 0, sizeof(sc->nr));
32123308

32133309
nr_reclaimed = sc->nr_reclaimed;
32143310
nr_scanned = sc->nr_scanned;
32153311

3216-
/*
3217-
* Determine the scan balance between anon and file LRUs.
3218-
*/
3219-
spin_lock_irq(&target_lruvec->lru_lock);
3220-
sc->anon_cost = target_lruvec->anon_cost;
3221-
sc->file_cost = target_lruvec->file_cost;
3222-
spin_unlock_irq(&target_lruvec->lru_lock);
3223-
3224-
/*
3225-
* Target desirable inactive:active list ratios for the anon
3226-
* and file LRU lists.
3227-
*/
3228-
if (!sc->force_deactivate) {
3229-
unsigned long refaults;
3230-
3231-
/*
3232-
* When refaults are being observed, it means a new
3233-
* workingset is being established. Deactivate to get
3234-
* rid of any stale active pages quickly.
3235-
*/
3236-
refaults = lruvec_page_state(target_lruvec,
3237-
WORKINGSET_ACTIVATE_ANON);
3238-
if (refaults != target_lruvec->refaults[WORKINGSET_ANON] ||
3239-
inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
3240-
sc->may_deactivate |= DEACTIVATE_ANON;
3241-
else
3242-
sc->may_deactivate &= ~DEACTIVATE_ANON;
3243-
3244-
refaults = lruvec_page_state(target_lruvec,
3245-
WORKINGSET_ACTIVATE_FILE);
3246-
if (refaults != target_lruvec->refaults[WORKINGSET_FILE] ||
3247-
inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
3248-
sc->may_deactivate |= DEACTIVATE_FILE;
3249-
else
3250-
sc->may_deactivate &= ~DEACTIVATE_FILE;
3251-
} else
3252-
sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
3253-
3254-
/*
3255-
* If we have plenty of inactive file pages that aren't
3256-
* thrashing, try to reclaim those first before touching
3257-
* anonymous pages.
3258-
*/
3259-
file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
3260-
if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
3261-
sc->cache_trim_mode = 1;
3262-
else
3263-
sc->cache_trim_mode = 0;
3264-
3265-
/*
3266-
* Prevent the reclaimer from falling into the cache trap: as
3267-
* cache pages start out inactive, every cache fault will tip
3268-
* the scan balance towards the file LRU. And as the file LRU
3269-
* shrinks, so does the window for rotation from references.
3270-
* This means we have a runaway feedback loop where a tiny
3271-
* thrashing file LRU becomes infinitely more attractive than
3272-
* anon pages. Try to detect this based on file LRU size.
3273-
*/
3274-
if (!cgroup_reclaim(sc)) {
3275-
unsigned long total_high_wmark = 0;
3276-
unsigned long free, anon;
3277-
int z;
3278-
3279-
free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
3280-
file = node_page_state(pgdat, NR_ACTIVE_FILE) +
3281-
node_page_state(pgdat, NR_INACTIVE_FILE);
3282-
3283-
for (z = 0; z < MAX_NR_ZONES; z++) {
3284-
struct zone *zone = &pgdat->node_zones[z];
3285-
if (!managed_zone(zone))
3286-
continue;
3287-
3288-
total_high_wmark += high_wmark_pages(zone);
3289-
}
3290-
3291-
/*
3292-
* Consider anon: if that's low too, this isn't a
3293-
* runaway file reclaim problem, but rather just
3294-
* extreme pressure. Reclaim as per usual then.
3295-
*/
3296-
anon = node_page_state(pgdat, NR_INACTIVE_ANON);
3297-
3298-
sc->file_is_tiny =
3299-
file + free <= total_high_wmark &&
3300-
!(sc->may_deactivate & DEACTIVATE_ANON) &&
3301-
anon >> sc->priority;
3302-
}
3312+
prepare_scan_count(pgdat, sc);
33033313

33043314
shrink_node_memcgs(pgdat, sc);
33053315

0 commit comments

Comments
 (0)