Skip to content

Commit f82a7a8

Browse files
yosrym93akpm00
authored andcommitted
memcg: calculate root usage from global state
Currently, we approximate the root usage by adding the memcg stats for anon, file, and conditionally swap (for memsw). To read the memcg stats we need to invoke an rstat flush. rstat flushes can be expensive, they scale with the number of cpus and cgroups on the system. mem_cgroup_usage() is called by memcg_events()->mem_cgroup_threshold() with irqs disabled, so such an expensive operation with irqs disabled can cause problems. Instead, approximate the root usage from global state. This is not 100% accurate, but the root usage has always been ill-defined anyway. Link: https://lkml.kernel.org/r/20230421174020.2994750-4-yosryahmed@google.com Signed-off-by: Yosry Ahmed <yosryahmed@google.com> Reviewed-by: Michal Koutný <mkoutny@suse.com> Acked-by: Shakeel Butt <shakeelb@google.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@kernel.dk> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Muchun Song <songmuchun@bytedance.com> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 190409c commit f82a7a8

File tree

1 file changed

+5
-19
lines changed

1 file changed

+5
-19
lines changed

mm/memcontrol.c

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3710,27 +3710,13 @@ static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
37103710

37113711
if (mem_cgroup_is_root(memcg)) {
37123712
/*
3713-
* We can reach here from irq context through:
3714-
* uncharge_batch()
3715-
* |--memcg_check_events()
3716-
* |--mem_cgroup_threshold()
3717-
* |--__mem_cgroup_threshold()
3718-
* |--mem_cgroup_usage
3719-
*
3720-
* rstat flushing is an expensive operation that should not be
3721-
* done from irq context; use stale stats in this case.
3722-
* Arguably, usage threshold events are not reliable on the root
3723-
* memcg anyway since its usage is ill-defined.
3724-
*
3725-
* Additionally, other call paths through memcg_check_events()
3726-
* disable irqs, so make sure we are flushing stats atomically.
3713+
* Approximate root's usage from global state. This isn't
3714+
* perfect, but the root usage was always an approximation.
37273715
*/
3728-
if (in_task())
3729-
mem_cgroup_flush_stats_atomic();
3730-
val = memcg_page_state(memcg, NR_FILE_PAGES) +
3731-
memcg_page_state(memcg, NR_ANON_MAPPED);
3716+
val = global_node_page_state(NR_FILE_PAGES) +
3717+
global_node_page_state(NR_ANON_MAPPED);
37323718
if (swap)
3733-
val += memcg_page_state(memcg, MEMCG_SWAP);
3719+
val += total_swap_pages - get_nr_swap_pages();
37343720
} else {
37353721
if (!swap)
37363722
val = page_counter_read(&memcg->memory);

0 commit comments

Comments
 (0)