follow up nodereclaim for 32b fix
Subsystems (4)
Michal Hocko
reviewercover follow up nodereclaim for 32b fix
Hi,
this is a follow up fix on top of [1]. I wasn't able to trigger bad things happening without the patch but the fix should be quite obvious and should make sense in general. I am sending this as an RFC, though, because g_u_p is better to not touch without strong reasons because it is just too easy to screw up.
The second patch is just a cleanup on top.
[1] http://lkml.kernel.org/r/[email protected]
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerRFC PATCH 1/2 mm, vmscan: consider eligible zones in get_scan_count
From: Michal Hocko <[email protected]>
get_scan_count considers the whole node LRU size when
- doing SCAN_FILE due to many page cache inactive pages
- calculating the number of pages to scan
in both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
A large highmem zone can easily distort SCAN_FILE heuristic because there might be only few file pages from the eligible zones on the node lru and we would still enforce file lru scanning which can lead to trashing while we could still scan anonymous pages.
The later use of lruvec_lru_size can be problematic as well. Especially when there are not many pages from the eligible zones. We would have to skip over many pages to find anything to reclaim but shrink_node_memcg would only reduce the remaining number to scan by SWAP_CLUSTER_MAX at maximum. Therefore we can end up going over a large LRU many times without actually having chance to reclaim much if anything at all. The closer we are out of memory on lowmem zone the worse the problem will be.
Changes since v1
- s@lruvec_lru_size_zone_idx@lruvec_lru_size_eligibe_zones@
--- mm/vmscan.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
mm/vmscan.c +28 -2
@@ -253,6 +253,32 @@ unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru, }/* +* Return the number of pages on the given lru which are eligible for the +* given zone_idx +*/ +static unsigned long lruvec_lru_size_eligibe_zones (struct lruvec *lruvec, +enum lru_list lru,int zone_idx) +{ +struct pglist_data *pgdat =lruvec_pgdat (lruvec); +unsigned long lru_size; +int zid; + + lru_size =lruvec_lru_size (lruvec, lru); +for (zid = zone_idx +1 ; zid <MAX_NR_ZONES ; zid++) { +struct zone *zone = &pgdat->node_zones[zid]; +unsigned long size; + +if (!managed_zone (zone)) +continue ; + + size =lruvec_zone_lru_size (lruvec, lru, zid); + lru_size -=min (size, lru_size); + } + +return lru_size; +} + +/* * Add a shrinker callback to be called from the vm. */ int register_shrinker (struct shrinker *shrinker)
@@ -2213,7 +2239,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,* system is under heavy pressure. */ if (!inactive_list_is_low (lruvec, true, sc, false) && -lruvec_lru_size (lruvec,LRU_INACTIVE_FILE ) >> sc->priority) { +lruvec_lru_size_eligibe_zones (lruvec,LRU_INACTIVE_FILE , sc->reclaim_idx) >> sc->priority) { scan_balance =SCAN_FILE ; goto out; }
@@ -2280,7 +2306,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,unsigned long size;unsigned long scan; - size =lruvec_lru_size (lruvec, lru); + size =lruvec_lru_size_eligibe_zones (lruvec, lru, sc->reclaim_idx); scan = size >> sc->priority;if (!scan && pass && force_scan)
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
Quoted 24 lines · Michal Hocko
From: Michal Hocko <[email protected]>
get_scan_countconsiders the whole node LRU size when
- doingSCAN_FILEdue to many page cache inactive pages
- calculating the number of pages to scanin both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
A large highmem zone can easily distort
SCAN_FILEheuristic because there might be only few file pages from the eligible zones on the node lru and we would still enforce file lru scanning which can lead to trashing while we could still scan anonymous pages.The later use of
lruvec_lru_sizecan be problematic as well. Especially when there are not many pages from the eligible zones. We would have to skip over many pages to find anything to reclaim butshrink_node_memcgwould only reduce the remaining number to scan bySWAP_CLUSTER_MAXat maximum. Therefore we can end up going over a large LRU many times without actually having chance to reclaim much if anything at all. The closer we are out of memory on lowmem zone the worse the problem will be.
Quoted 6 lines
Changes since v1
- s@lruvec_lru_size_zone_idx@lruvec_lru_size_eligibe_zones@Acked-by Minchan Kim <[email protected]>Signed-off-by Michal Hocko <[email protected]>---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerRe: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
In reply to Michal HockoOn Tue 10-01-17 13:55:51, Michal Hocko wrote:
[...]
mm/vmscan.c static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, · line 2312
Quoted 9 lines
mm/vmscan.c +1
-1@@ -2280,7 +2306,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,unsigned long size;unsigned long scan; - size =lruvec_lru_size (lruvec, lru); + size =lruvec_lru_size_eligibe_zones (lruvec, lru, sc->reclaim_idx); scan = size >> sc->priority;if (!scan && pass && force_scan)
I have just come across inactive_reclaimable_pages and it seems it is unnecessary after this, right Minchan?
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
Quoted 6 lines · Michal Hocko
On Tue 10-01-17 13:55:51, Michal Hocko wrote:
[...]Quoted 4 lines
mm/vmscan.c +0
-0@@ -2280,7 +2306,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,unsigned long size;unsigned long scan;
Quoted 8 lines
mm/vmscan.c static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, · line 2312
Quoted 5 lines
mm/vmscan.c +1
-1- size =lruvec_lru_size (lruvec, lru); + size =lruvec_lru_size_eligibe_zones (lruvec, lru, sc->reclaim_idx); scan = size >> sc->priority;if (!scan && pass && force_scan)I have just come across
inactive_reclaimable_pagesand it seems it is unnecessary after this, right Minchan?
Good catch.
At that time, I also wanted to change get_scan_count to fix the problem but be lack of report and other guys didn't want it. :-(
I'm happy to see it now.
Thanks.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerRe: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
In reply to Michal HockoQuoted 8 lines · Michal Hocko
From: Michal Hocko <[email protected]>
get_scan_countconsiders the whole node LRU size when
- doingSCAN_FILEdue to many page cache inactive pages
- calculating the number of pages to scanin both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
The amount of retrofitting zones back into reclaim is disappointing :/
Quoted 14 lines
/*
+ * Return the number of pages on the given lru which are eligible for the
+ * givenzone_idx
+ */mm/vmscan.c +10
-0+static unsigned long lruvec_lru_size_eligibe_zones (struct lruvec *lruvec, +enum lru_list lru,int zone_idx) +{ +struct pglist_data *pgdat =lruvec_pgdat (lruvec); +unsigned long lru_size; +int zid; + + lru_size =lruvec_lru_size (lruvec, lru); +for (zid = zone_idx +1 ; zid <MAX_NR_ZONES ; zid++) { +struct zone *zone = &pgdat->node_zones[zid];
mm/vmscan.c unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru, · line 278
Quoted 10 lines
mm/vmscan.c +10
-0+unsigned long size; + +if (!managed_zone (zone)) +continue ; + + size =lruvec_zone_lru_size (lruvec, lru, zid); + lru_size -=min (size, lru_size); + } + +return lru_size;
The only other use of lruvec_lru_size() is also in get_scan_count(), where it decays the LRU pressure balancing ratios. That caller wants to operate on the entire lruvec.
Can you instead add the filtering logic to lruvec_lru_size() directly, and pass MAX_NR_ZONES when operating on the entire lruvec? That would make the code quite a bit clearer than having 3 different lruvec size querying functions.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerRe: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
Quoted 11 lines · Johannes Weiner
Quoted 8 lines · Michal Hocko
From: Michal Hocko <[email protected]>
get_scan_countconsiders the whole node LRU size when
- doingSCAN_FILEdue to many page cache inactive pages
- calculating the number of pages to scanin both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
The amount of retrofitting zones back into reclaim is disappointing :/
Agreed
Quoted 29 lines
Quoted 14 lines
/*
+ * Return the number of pages on the given lru which are eligible for the
+ * givenzone_idx
+ */mm/vmscan.c +10
-0+static unsigned long lruvec_lru_size_eligibe_zones (struct lruvec *lruvec, +enum lru_list lru,int zone_idx) +{ +struct pglist_data *pgdat =lruvec_pgdat (lruvec); +unsigned long lru_size; +int zid; + + lru_size =lruvec_lru_size (lruvec, lru); +for (zid = zone_idx +1 ; zid <MAX_NR_ZONES ; zid++) { +struct zone *zone = &pgdat->node_zones[zid];mm/vmscan.c unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru, · line 278
Quoted 10 lines
mm/vmscan.c +10
-0+unsigned long size; + +if (!managed_zone (zone)) +continue ; + + size =lruvec_zone_lru_size (lruvec, lru, zid); + lru_size -=min (size, lru_size); + } + +return lru_size;The only other use of
lruvec_lru_size()is also inget_scan_count(), where it decays the LRU pressure balancing ratios. That caller wants to operate on the entire lruvec.
Quoted 4 lines
Can you instead add the filtering logic to
lruvec_lru_size()directly, and passMAX_NR_ZONESwhen operating on the entire lruvec? That would make the code quite a bit clearer than having 3 different lruvec size querying functions.
OK, fair point. What about this?
---
Johannes Weiner
maintainerRe: [RFC PATCH 1/2] mm, vmscan: consider eligible zones in get_scan_count
Quoted 33 lines · Michal Hocko
From
39824aac7504b38f943a80b7d98ec4e87a5607a7Mon Sep 17 00:00:00 2001
From: Michal Hocko <[email protected]>
Date: Tue, 27 Dec 2016 16:28:44 +0100
Subject: [PATCH] mm, vmscan: consider eligible zones inget_scan_count
get_scan_countconsiders the whole node LRU size when
- doingSCAN_FILEdue to many page cache inactive pages
- calculating the number of pages to scanin both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
A large highmem zone can easily distort
SCAN_FILEheuristic because there might be only few file pages from the eligible zones on the node lru and we would still enforce file lru scanning which can lead to trashing while we could still scan anonymous pages.The later use of
lruvec_lru_sizecan be problematic as well. Especially when there are not many pages from the eligible zones. We would have to skip over many pages to find anything to reclaim butshrink_node_memcgwould only reduce the remaining number to scan bySWAP_CLUSTER_MAXat maximum. Therefore we can end up going over a large LRU many times without actually having chance to reclaim much if anything at all. The closer we are out of memory on lowmem zone the worse the problem will be.Fix this by making
lruvec_lru_sizezone aware.zone_idxwill tell the the maximum eligible zone.Changes since v2
- move the zone filtering logic tolruvec_lru_sizeso that we do not have too many lruvec_lru_size* functions - Johannes
Quoted 5 lines
Changes since v1
- s@lruvec_lru_size_zone_idx@lruvec_lru_size_eligibe_zones@Acked-by Minchan Kim <[email protected]>Signed-off-by Michal Hocko <[email protected]>
Thanks, that looks better IMO. Two tiny things:
Quoted 34 lines
(quoted diff) +17
-6@@ -234,22 +234,44 @@ bool pgdat_reclaimable(struct pglist_data *pgdat) pgdat_reclaimable_pages(pgdat) * 6; } -unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru) +static unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, + enum lru_list lru, int zone_idx) { if (!mem_cgroup_disabled()) - return mem_cgroup_get_lru_size(lruvec, lru); + return mem_cgroup_get_zone_lru_size(lruvec, lru, zone_idx); - return node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru); + return zone_page_state(&lruvec_pgdat(lruvec)->node_zones[zone_idx], + NR_ZONE_LRU_BASE + lru); } -unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru, - int zone_idx) +/** lruvec_lru_size - Returns the number of pages on the given LRU list. + * @lruvec: lru vector + * @lru: lru to use + * @zone_idx: zones to consider (use MAX_NR_ZONES for the whole LRU list) + */ +unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx) { + unsigned long lru_size; + int zid; + if (!mem_cgroup_disabled()) - return mem_cgroup_get_zone_lru_size(lruvec, lru, zone_idx); + lru_size = mem_cgroup_get_lru_size(lruvec, lru); + else + lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
Review bool pgdat_reclaimable(struct pglist_data *pgdat) · line 270
Quoted 10 lines
(quoted diff) +10
-0+ + for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) { + struct zone *zone = &lruvec_pgdat(lruvec)->node_zones[zid]; + unsigned long size; + + if (!managed_zone(zone)) + continue; + + size = lruvec_zone_lru_size(lruvec, lru, zid); + lru_size -= min(size, lru_size);
Fold lruvec_zone_lru_size() in here? Its body goes well with how we get lru_size at the start of the function, no need to maintain that abstraction.
Review static bool inactive_list_is_low(struct lruvec *lruvec, bool file, · line 2093
Quoted 11 lines
(quoted diff) +2
-2@@ -2064,8 +2086,8 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, if (!file && !total_swap_pages) return false; - total_inactive = inactive = lruvec_lru_size(lruvec, file * LRU_FILE); - total_active = active = lruvec_lru_size(lruvec, file * LRU_FILE + LRU_ACTIVE); + total_inactive = inactive = lruvec_lru_size(lruvec, file * LRU_FILE, MAX_NR_ZONES); + total_active = active = lruvec_lru_size(lruvec, file * LRU_FILE + LRU_ACTIVE, MAX_NR_ZONES); /* * For zone-constrained allocations, it is necessary to check if
It might be a better patch order to do the refactoring of the zone filtering from inactive_list_is_low() to lruvec_lru_size() in 1/2, without change of behavior; then update the other callers in 2/2.
Hm?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerPATCH 1/3 mm, vmscan: cleanup lru size claculations
From: Michal Hocko <[email protected]>
lruvec_lru_size returns the full size of the LRU list while we sometimes need a value reduced only to eligible zones (e.g. for lowmem requests). inactive_list_is_low is one such user. Later patches will add more of them. Add a new parameter to lruvec_lru_size and allow it filter out zones which are not eligible for the given context.
--- include/linux/mmzone.h | 2 +- mm/vmscan.c | 88 ++++++++++++++++++++++++-------------------------- mm/workingset.c | 2 +- 3 files changed, 45 insertions(+), 47 deletions(-)
include/linux/mmzone.h +1 -1
@@ -780,7 +780,7 @@ static inline struct pglist_data *lruvec_pgdat(struct lruvec *lruvec)#endif } -extern unsigned long lruvec_lru_size (struct lruvec *lruvec,enum lru_list lru); +extern unsigned long lruvec_lru_size (struct lruvec *lruvec,enum lru_list lru,int zone_idx);#ifdef CONFIG_HAVE_MEMORY_PRESENT void memory_present (int nid,unsigned long start,unsigned long end);
mm/vmscan.c +43 -45
137 lines not on this page · raw message
mm/workingset.c +1 -1
@@ -267,7 +267,7 @@ bool workingset_refault(void *shadow) } lruvec =mem_cgroup_lruvec (pgdat, memcg); refault =atomic_long_read (&lruvec->inactive_age); - active_file =lruvec_lru_size (lruvec,LRU_ACTIVE_FILE ); + active_file =lruvec_lru_size (lruvec,LRU_ACTIVE_FILE ,MAX_NR_ZONES );rcu_read_unlock ();/*
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerPATCH 2/3 mm, vmscan: consider eligible zones in get_scan_count
From: Michal Hocko <[email protected]>
get_scan_count considers the whole node LRU size when
- doing SCAN_FILE due to many page cache inactive pages
- calculating the number of pages to scan
in both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
A large highmem zone can easily distort SCAN_FILE heuristic because there might be only few file pages from the eligible zones on the node lru and we would still enforce file lru scanning which can lead to trashing while we could still scan anonymous pages.
The later use of lruvec_lru_size can be problematic as well. Especially when there are not many pages from the eligible zones. We would have to skip over many pages to find anything to reclaim but shrink_node_memcg would only reduce the remaining number to scan by SWAP_CLUSTER_MAX at maximum. Therefore we can end up going over a large LRU many times without actually having chance to reclaim much if anything at all. The closer we are out of memory on lowmem zone the worse the problem will be.
Fix this by filtering out all the ineligible zones when calculating the lru size for both paths and consider only sc->reclaim_idx zones.
--- mm/vmscan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/vmscan.c +2 -2
@@ -2234,7 +2234,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,* system is under heavy pressure. */ if (!inactive_list_is_low (lruvec, true, sc, false) && -lruvec_lru_size (lruvec,LRU_INACTIVE_FILE ,MAX_NR_ZONES ) >> sc->priority) { +lruvec_lru_size (lruvec,LRU_INACTIVE_FILE , sc->reclaim_idx) >> sc->priority) { scan_balance =SCAN_FILE ; goto out; }
@@ -2301,7 +2301,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,unsigned long size;unsigned long scan; - size =lruvec_lru_size (lruvec, lru,MAX_NR_ZONES ); + size =lruvec_lru_size (lruvec, lru, sc->reclaim_idx); scan = size >> sc->priority;if (!scan && pass && force_scan)
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] mm, vmscan: consider eligible zones in get_scan_count
Quoted 24 lines · Michal Hocko
From: Michal Hocko <[email protected]>
get_scan_countconsiders the whole node LRU size when
- doingSCAN_FILEdue to many page cache inactive pages
- calculating the number of pages to scanin both cases this might lead to unexpected behavior especially on 32b systems where we can expect lowmem memory pressure very often.
A large highmem zone can easily distort
SCAN_FILEheuristic because there might be only few file pages from the eligible zones on the node lru and we would still enforce file lru scanning which can lead to trashing while we could still scan anonymous pages.The later use of
lruvec_lru_sizecan be problematic as well. Especially when there are not many pages from the eligible zones. We would have to skip over many pages to find anything to reclaim butshrink_node_memcgwould only reduce the remaining number to scan bySWAP_CLUSTER_MAXat maximum. Therefore we can end up going over a large LRU many times without actually having chance to reclaim much if anything at all. The closer we are out of memory on lowmem zone the worse the problem will be.
Quoted 6 lines
Fix this by filtering out all the ineligible zones when calculating the lru size for both paths and consider only
sc->reclaim_idxzones.Acked-by Minchan Kim <[email protected]>Signed-off-by Michal Hocko <[email protected]>---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerPATCH 3/3 Reverted "mm: bail out in shrink_inactive_list()"
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
This reverts 91dcade47a3d0e7c31464ef05f56c08e92a0e9c2. inactive_reclaimable_pages shouldn't be needed anymore since that get_scan_count is aware of the eligble zones ("mm, vmscan: consider eligible zones in get_scan_count").
--- mm/vmscan.c | 27 --------------------------- 1 file changed, 27 deletions(-)
mm/vmscan.c +0 -27
@@ -1700,30 +1700,6 @@ static int current_may_throttle(void)bdi_write_congested (current->backing_dev_info); } -static bool inactive_reclaimable_pages (struct lruvec *lruvec, -struct scan_control *sc,enum lru_list lru) -{ -int zid; -struct zone *zone; -int file =is_file_lru (lru); -struct pglist_data *pgdat =lruvec_pgdat (lruvec); - -if (!global_reclaim (sc)) -return true; - -for (zid = sc->reclaim_idx; zid >=0 ; zid--) { - zone = &pgdat->node_zones[zid]; -if (!managed_zone (zone)) -continue ; - -if (zone_page_state_snapshot (zone,NR_ZONE_LRU_BASE + -LRU_FILE * file) >=SWAP_CLUSTER_MAX ) -return true; - } - -return false; -} -/* * shrink_inactive_list() is a helper for shrink_node(). It returns the number * of reclaimed pages
@@ -1742,9 +1718,6 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,struct pglist_data *pgdat =lruvec_pgdat (lruvec);struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat; -if (!inactive_reclaimable_pages (lruvec, sc, lru)) -return 0 ; -while (unlikely (too_many_isolated (pgdat, file, sc))) {congestion_wait (BLK_RW_ASYNC ,HZ /10 );
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] Reverted "mm: bail out in shrink_inactive_list()"
Quoted 8 lines · Michal Hocko
From: Michal Hocko <[email protected]>
This reverts
91dcade47a3d0e7c31464ef05f56c08e92a0e9c2.inactive_reclaimable_pagesshouldn't be needed anymore since thatget_scan_countis aware of the eligble zones ("mm, vmscan: consider eligible zones inget_scan_count").
Looks radical ;)
Quoted 2 lines
Signed-off-by Michal Hocko <[email protected]>---
Quoted 49 lines
mm/vmscan.c | 27 --------------------------- 1 file changed, 27 deletions(-)mm/vmscan.c +0
-28@@ -1700,30 +1700,6 @@ static int current_may_throttle(void)bdi_write_congested (current->backing_dev_info); } -static bool inactive_reclaimable_pages (struct lruvec *lruvec, -struct scan_control *sc,enum lru_list lru) -{ -int zid; -struct zone *zone; -int file =is_file_lru (lru); -struct pglist_data *pgdat =lruvec_pgdat (lruvec); - -if (!global_reclaim (sc)) -return true; - -for (zid = sc->reclaim_idx; zid >=0 ; zid--) { - zone = &pgdat->node_zones[zid]; -if (!managed_zone (zone)) -continue ; - -if (zone_page_state_snapshot (zone,NR_ZONE_LRU_BASE + -LRU_FILE * file) >=SWAP_CLUSTER_MAX ) -return true; - } - -return false; -} -/* * shrink_inactive_list() is a helper for shrink_node(). It returns the number * of reclaimed pages @@ -1742,9 +1718,6 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,struct pglist_data *pgdat =lruvec_pgdat (lruvec);struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat; -if (!inactive_reclaimable_pages (lruvec, sc, lru)) -return 0 ; -while (unlikely (too_many_isolated (pgdat, file, sc))) {congestion_wait (BLK_RW_ASYNC ,HZ /10 ); --
Quoted 1 line
2.11.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] Reverted "mm: bail out in shrink_inactive_list()"
In reply to Michal HockoQuoted 8 lines · Michal Hocko
From: Michal Hocko <[email protected]>
This reverts
91dcade47a3d0e7c31464ef05f56c08e92a0e9c2.inactive_reclaimable_pagesshouldn't be needed anymore since thatget_scan_countis aware of the eligble zones ("mm, vmscan: consider eligible zones inget_scan_count").Signed-off-by Michal Hocko <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] mm, vmscan: cleanup lru size claculations
In reply to Michal HockoQuoted 9 lines · Michal Hocko
From: Michal Hocko <[email protected]>
lruvec_lru_sizereturns the full size of the LRU list while we sometimes need a value reduced only to eligible zones (e.g. for lowmem requests).inactive_list_is_lowis one such user. Later patches will add more of them. Add a new parameter tolruvec_lru_sizeand allow it filter out zones which are not eligible for the given context.
Quoted 3 lines
Acked-by Johannes Weiner <[email protected]>Signed-off-by Michal Hocko <[email protected]>---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] mm, vmscan: cleanup lru size claculations
In reply to Michal HockoQuoted 34 lines · Michal Hocko
From: Michal Hocko <[email protected]>
lruvec_lru_sizereturns the full size of the LRU list while we sometimes need a value reduced only to eligible zones (e.g. for lowmem requests).inactive_list_is_lowis one such user. Later patches will add more of them. Add a new parameter tolruvec_lru_sizeand allow it filter out zones which are not eligible for the given context.Acked-by Johannes Weiner <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- include/linux/mmzone.h | 2 +- mm/vmscan.c | 88 ++++++++++++++++++++++++-------------------------- mm/workingset.c | 2 +- 3 files changed, 45 insertions(+), 47 deletions(-)include/linux/mmzone.h +1
-1@@ -780,7 +780,7 @@ static inline struct pglist_data *lruvec_pgdat(struct lruvec *lruvec)#endif } -extern unsigned long lruvec_lru_size (struct lruvec *lruvec,enum lru_list lru); +extern unsigned long lruvec_lru_size (struct lruvec *lruvec,enum lru_list lru,int zone_idx);#ifdef CONFIG_HAVE_MEMORY_PRESENT void memory_present (int nid,unsigned long start,unsigned long end);mm/vmscan.c +0
-0
mm/vmscan.c bool pgdat_reclaimable(struct pglist_data *pgdat) · line 237
Quoted 5 lines
mm/vmscan.c +1
-1@@ -234,22 +234,38 @@ bool pgdat_reclaimable(struct pglist_data *pgdat)pgdat_reclaimable_pages (pgdat) *6 ; } -unsigned long lruvec_lru_size (struct lruvec *lruvec,enum lru_list lru) +/** lruvec_lru_size - Returns the number of pages on the given LRU list.
minor:
/*
* lruvec_lru_size
I don't have any preferance but just found.
Otherwise,
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
reviewerRFC PATCH 2/2 mm, vmscan: cleanup inactive_list_is_low
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
inactive_list_is_low is duplicating logic implemented by lruvec_lru_size_eligibe_zones. Let's use the dedicated function to get the number of eligible pages on the lru list and ask use lruvec_lru_size to get the total LRU lize only when the tracing is really requested. We are still iterating over all LRUs two times in that case but a) inactive_list_is_low is not a hot path and b) this can be addressed at the tracing layer and only evaluate arguments only when the tracing is enabled in future if that ever matters.
--- mm/vmscan.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-)
mm/vmscan.c +10 -28
@@ -2054,11 +2054,10 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, struct scan_control *sc, bool trace) {unsigned long inactive_ratio; -unsigned long total_inactive, inactive; -unsigned long total_active, active; +unsigned long inactive, active; +enum lru_list inactive_lru = file *LRU_FILE ; +enum lru_list active_lru = file *LRU_FILE +LRU_ACTIVE ;unsigned long gb; -struct pglist_data *pgdat =lruvec_pgdat (lruvec); -int zid;/* * If we don't have swap space, anonymous page deactivation
@@ -2067,27 +2066,8 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,if (!file && !total_swap_pages)return false; - total_inactive = inactive =lruvec_lru_size (lruvec, file *LRU_FILE ); - total_active = active =lruvec_lru_size (lruvec, file *LRU_FILE +LRU_ACTIVE ); - -/* -* For zone-constrained allocations, it is necessary to check if -* deactivations are required for lowmem to be reclaimed. This -* calculates the inactive/active pages available in eligible zones. -*/ -for (zid = sc->reclaim_idx +1 ; zid <MAX_NR_ZONES ; zid++) { -struct zone *zone = &pgdat->node_zones[zid]; -unsigned long inactive_zone, active_zone; - -if (!managed_zone (zone)) -continue ; - - inactive_zone =lruvec_zone_lru_size (lruvec, file *LRU_FILE , zid); - active_zone =lruvec_zone_lru_size (lruvec, (file *LRU_FILE ) +LRU_ACTIVE , zid); - - inactive -=min (inactive, inactive_zone); - active -=min (active, active_zone); - } + inactive =lruvec_lru_size_eligibe_zones (lruvec, inactive_lru, sc->reclaim_idx); + active =lruvec_lru_size_eligibe_zones (lruvec, active_lru, sc->reclaim_idx); gb = (inactive + active) >> (30 -PAGE_SHIFT );if (gb)
@@ -2096,10 +2076,12 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, inactive_ratio =1 ;if (trace) -trace_mm_vmscan_inactive_list_is_low (pgdat->node_id, +trace_mm_vmscan_inactive_list_is_low (lruvec_pgdat (lruvec)->node_id, sc->reclaim_idx, - total_inactive, inactive, - total_active, active, inactive_ratio, file); +lruvec_lru_size (lruvec, inactive_lru), inactive, +lruvec_lru_size (lruvec, active_lru), active, + inactive_ratio, file); +return inactive * inactive_ratio < active; }
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [RFC PATCH 2/2] mm, vmscan: cleanup inactive_list_is_low
Hi Michal,
Quoted 10 lines · Michal Hocko
From: Michal Hocko <[email protected]>
inactive_list_is_lowis duplicating logic implemented bylruvec_lru_size_eligibe_zones. Let's use the dedicated function to get the number of eligible pages on the lru list and ask uselruvec_lru_sizeto get the total LRU lize only when the tracing is really requested. We are still iterating over all LRUs two times in that case but a)inactive_list_is_lowis not a hot path and b) this can be addressed at the tracing layer and only evaluate arguments only when the tracing is enabled in future if that ever matters.
Make sense so I was about to add my acked-by but surprised when I found "bool trace variable" and lruvec_lru_size in the trace so I ask some questions to the "+ mm-vmscan-add-mm_vmscan_inactive_list_is_low-tracepoint" thread.
Except that part, looks good to me.
Quoted 79 lines
Signed-off-by Michal Hocko <[email protected]>--- mm/vmscan.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-)mm/vmscan.c +10
-28@@ -2054,11 +2054,10 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, struct scan_control *sc, bool trace) {unsigned long inactive_ratio; -unsigned long total_inactive, inactive; -unsigned long total_active, active; +unsigned long inactive, active; +enum lru_list inactive_lru = file *LRU_FILE ; +enum lru_list active_lru = file *LRU_FILE +LRU_ACTIVE ;unsigned long gb; -struct pglist_data *pgdat =lruvec_pgdat (lruvec); -int zid;/* * If we don't have swap space, anonymous page deactivation @@ -2067,27 +2066,8 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,if (!file && !total_swap_pages)return false; - total_inactive = inactive =lruvec_lru_size (lruvec, file *LRU_FILE ); - total_active = active =lruvec_lru_size (lruvec, file *LRU_FILE +LRU_ACTIVE ); - -/* -* For zone-constrained allocations, it is necessary to check if -* deactivations are required for lowmem to be reclaimed. This -* calculates the inactive/active pages available in eligible zones. -*/ -for (zid = sc->reclaim_idx +1 ; zid <MAX_NR_ZONES ; zid++) { -struct zone *zone = &pgdat->node_zones[zid]; -unsigned long inactive_zone, active_zone; - -if (!managed_zone (zone)) -continue ; - - inactive_zone =lruvec_zone_lru_size (lruvec, file *LRU_FILE , zid); - active_zone =lruvec_zone_lru_size (lruvec, (file *LRU_FILE ) +LRU_ACTIVE , zid); - - inactive -=min (inactive, inactive_zone); - active -=min (active, active_zone); - } + inactive =lruvec_lru_size_eligibe_zones (lruvec, inactive_lru, sc->reclaim_idx); + active =lruvec_lru_size_eligibe_zones (lruvec, active_lru, sc->reclaim_idx); gb = (inactive + active) >> (30 -PAGE_SHIFT );if (gb)@@ -2096,10 +2076,12 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, inactive_ratio =1 ;if (trace) -trace_mm_vmscan_inactive_list_is_low (pgdat->node_id, +trace_mm_vmscan_inactive_list_is_low (lruvec_pgdat (lruvec)->node_id, sc->reclaim_idx, - total_inactive, inactive, - total_active, active, inactive_ratio, file); +lruvec_lru_size (lruvec, inactive_lru), inactive, +lruvec_lru_size (lruvec, active_lru), active, + inactive_ratio, file); +return inactive * inactive_ratio < active; }Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [RFC PATCH 2/2] mm, vmscan: cleanup inactive_list_is_low
In reply to Michal HockoQuoted 12 lines · Michal Hocko
From: Michal Hocko <[email protected]>
inactive_list_is_lowis duplicating logic implemented bylruvec_lru_size_eligibe_zones. Let's use the dedicated function to get the number of eligible pages on the lru list and ask uselruvec_lru_sizeto get the total LRU lize only when the tracing is really requested. We are still iterating over all LRUs two times in that case but a)inactive_list_is_lowis not a hot path and b) this can be addressed at the tracing layer and only evaluate arguments only when the tracing is enabled in future if that ever matters.
Quoted 2 lines
Signed-off-by Michal Hocko <[email protected]>---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [RFC PATCH 2/2] mm, vmscan: cleanup inactive_list_is_low
In reply to Michal HockoQuoted 10 lines · Michal Hocko
From: Michal Hocko <[email protected]>
inactive_list_is_lowis duplicating logic implemented bylruvec_lru_size_eligibe_zones. Let's use the dedicated function to get the number of eligible pages on the lru list and ask uselruvec_lru_sizeto get the total LRU lize only when the tracing is really requested. We are still iterating over all LRUs two times in that case but a)inactive_list_is_lowis not a hot path and b) this can be addressed at the tracing layer and only evaluate arguments only when the tracing is enabled in future if that ever matters.
lruvec_zone_lru_size() is no longer needed after this. Again, it would be better to consolidate everything into one lruvec_lru_size() that takes a reclaim index. Trivial to rebase on top of that, though, so:
Quoted 1 line
Signed-off-by Michal Hocko <[email protected]>
Thanks
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>