[PATCH] mm, memcg: reduce memory_stat_show stack footprint

From: Michal Hocko
Date: Thu Dec 14 2017 - 04:12:22 EST


scripts/stackusage says that memory_stat_show consumes a lot of stack
space
./mm/memcontrol.c:5526 memory_stat_show 976 static

The size can be even larger depending on the configuration. Paul Menzel
has even got the following warning for his distribution config:
mm/memcontrol.c: In function âmemory_stat_showâ:
mm/memcontrol.c:5364:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=]

The stack usage should be safe because this function is called from
shallow context but let's make those two large arrays static and
synchronize callers by a mutex. This might slow heavy parallel memcg
stat readers. If this ever turns out to be a problem we can drop those
arrays altogether and print the current snapshots of those counters
(this would be more prone to get inconsistent results though).

Reported-by: Paul Menzel <pmenzel+linux-cgroups@xxxxxxxxxxxxx>
Signed-off-by: Michal Hocko <mhocko@xxxxxxxx>
---
mm/memcontrol.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 8fa91d24a70b..784a4bd5fdf0 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5526,8 +5526,9 @@ static int memory_events_show(struct seq_file *m, void *v)
static int memory_stat_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
- unsigned long stat[MEMCG_NR_STAT];
- unsigned long events[MEMCG_NR_EVENTS];
+ static unsigned long stat[MEMCG_NR_STAT];
+ static unsigned long events[MEMCG_NR_EVENTS];
+ static DEFINE_MUTEX(stat_lock);
int i;

/*
@@ -5540,7 +5541,7 @@ static int memory_stat_show(struct seq_file *m, void *v)
*
* Current memory state:
*/
-
+ mutex_lock(&stat_lock);
tree_stat(memcg, stat);
tree_events(memcg, events);

@@ -5601,6 +5602,7 @@ static int memory_stat_show(struct seq_file *m, void *v)
stat[WORKINGSET_ACTIVATE]);
seq_printf(m, "workingset_nodereclaim %lu\n",
stat[WORKINGSET_NODERECLAIM]);
+ mutex_unlock(&stat_lock);

return 0;
}
--
2.15.0

--
Michal Hocko
SUSE Labs