* [PATCH v2 1/3] mm/vmstat: expose min_slab_pages in /proc/zoneinfo
2019-05-27 11:52 [PATCH v2 0/3] mm: improvement in shrink slab Yafang Shao
@ 2019-05-27 11:52 ` Yafang Shao
2019-05-27 11:52 ` [PATCH v2 2/3] mm/vmscan: change return type of shrink_node() to void Yafang Shao
2019-05-27 11:52 ` [PATCH v2 3/3] mm/vmscan: shrink slab in node reclaim Yafang Shao
2 siblings, 0 replies; 4+ messages in thread
From: Yafang Shao @ 2019-05-27 11:52 UTC (permalink / raw)
To: mhocko, akpm; +Cc: linux-mm, shaoyafang, Yafang Shao
On one of our servers, we find the dentry is continuously growing
without shrinking. We're not sure whether that is because reclaimable
slab is still less than min_slab_pages.
So if we expose min_slab_pages, it would be easy to compare.
As we can set min_slab_ratio with sysctl, we should expose the effective
min_slab_pages to user as well.
That is same with min_unmapped_pages.
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
mm/vmstat.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/mm/vmstat.c b/mm/vmstat.c
index a7d4933..bb76cfe 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1549,7 +1549,15 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
NR_VM_NUMA_STAT_ITEMS],
node_page_state(pgdat, i));
}
+
+#ifdef CONFIG_NUMA
+ seq_printf(m, "\n %-12s %lu", "min_slab",
+ pgdat->min_slab_pages);
+ seq_printf(m, "\n %-12s %lu", "min_unmapped",
+ pgdat->min_unmapped_pages);
+#endif
}
+
seq_printf(m,
"\n pages free %lu"
"\n min %lu"
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/3] mm/vmscan: change return type of shrink_node() to void
2019-05-27 11:52 [PATCH v2 0/3] mm: improvement in shrink slab Yafang Shao
2019-05-27 11:52 ` [PATCH v2 1/3] mm/vmstat: expose min_slab_pages in /proc/zoneinfo Yafang Shao
@ 2019-05-27 11:52 ` Yafang Shao
2019-05-27 11:52 ` [PATCH v2 3/3] mm/vmscan: shrink slab in node reclaim Yafang Shao
2 siblings, 0 replies; 4+ messages in thread
From: Yafang Shao @ 2019-05-27 11:52 UTC (permalink / raw)
To: mhocko, akpm; +Cc: linux-mm, shaoyafang, Yafang Shao
As the return value of shrink_node() isn't used by any callsites,
we'd better change the return type of shrink_node() from static inline
to void.
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
mm/vmscan.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d9c3e87..e0c5669 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2657,7 +2657,7 @@ static bool pgdat_memcg_congested(pg_data_t *pgdat, struct mem_cgroup *memcg)
(memcg && memcg_congested(pgdat, memcg));
}
-static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
+static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
{
struct reclaim_state *reclaim_state = current->reclaim_state;
unsigned long nr_reclaimed, nr_scanned;
@@ -2827,8 +2827,6 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
*/
if (reclaimable)
pgdat->kswapd_failures = 0;
-
- return reclaimable;
}
/*
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 3/3] mm/vmscan: shrink slab in node reclaim
2019-05-27 11:52 [PATCH v2 0/3] mm: improvement in shrink slab Yafang Shao
2019-05-27 11:52 ` [PATCH v2 1/3] mm/vmstat: expose min_slab_pages in /proc/zoneinfo Yafang Shao
2019-05-27 11:52 ` [PATCH v2 2/3] mm/vmscan: change return type of shrink_node() to void Yafang Shao
@ 2019-05-27 11:52 ` Yafang Shao
2 siblings, 0 replies; 4+ messages in thread
From: Yafang Shao @ 2019-05-27 11:52 UTC (permalink / raw)
To: mhocko, akpm; +Cc: linux-mm, shaoyafang, Yafang Shao
In the node reclaim, may_shrinkslab is 0 by default,
hence shrink_slab will never be performed in it.
While shrik_slab should be performed if the relcaimable slab is over
min slab limit.
If reclaimable pagecache is less than min_unmapped_pages while
reclaimable slab is greater than min_slab_pages, we only shrink slab.
Otherwise the min_unmapped_pages will be useless under this condition.
reclaim_state.reclaimed_slab is to tell us how many pages are
reclaimed in shrink slab.
This issue is very easy to produce, first you continuously cat a random
non-exist file to produce more and more dentry, then you read big file
to produce page cache. And finally you will find that the denty will
never be shrunk.
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
mm/vmscan.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e0c5669..c624f59 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4157,6 +4157,8 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
p->reclaim_state = &reclaim_state;
if (node_pagecache_reclaimable(pgdat) > pgdat->min_unmapped_pages) {
+ sc.may_shrinkslab = (pgdat->min_slab_pages <
+ node_page_state(pgdat, NR_SLAB_RECLAIMABLE));
/*
* Free memory by calling shrink node with increasing
* priorities until we have enough memory freed.
@@ -4164,6 +4166,28 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
do {
shrink_node(pgdat, &sc);
} while (sc.nr_reclaimed < nr_pages && --sc.priority >= 0);
+ } else {
+ /*
+ * If the reclaimable pagecache is not greater than
+ * min_unmapped_pages, only reclaim the slab.
+ */
+ struct mem_cgroup *memcg;
+ struct mem_cgroup_reclaim_cookie reclaim = {
+ .pgdat = pgdat,
+ .priority = sc.priority,
+ };
+
+ do {
+ memcg = mem_cgroup_iter(NULL, NULL, &reclaim);
+ do {
+ shrink_slab(sc.gfp_mask, pgdat->node_id,
+ memcg, sc.priority);
+ } while ((memcg = mem_cgroup_iter(NULL, memcg,
+ &reclaim)));
+
+ sc.nr_reclaimed += reclaim_state.reclaimed_slab;
+ reclaim_state.reclaimed_slab = 0;
+ } while (sc.nr_reclaimed < nr_pages && --sc.priority >= 0);
}
p->reclaim_state = NULL;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread