memcg: add flush tracepoint

This tracepoint gives visibility on how often the flushing of memcg stats
occurs and contains info on whether it was forced, skipped, and the value
of stats updated.  It can help with understanding how readers are affected
by having to perform the flush, and the effectiveness of the flush by
inspecting the number of stats updated.  Paired with the recently added
tracepoints for tracing rstat updates, it can also help show correlation
where stats exceed thresholds frequently.

Link: https://lkml.kernel.org/r/20241029021106.25587-3-inwardvessel@gmail.com
Signed-off-by: JP Kobryn <inwardvessel@gmail.com>
Reviewed-by: Yosry Ahmed <yosryahmed@google.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
JP Kobryn 2024-10-28 19:11:06 -07:00 committed by Andrew Morton
parent e1479b880c
commit f914ac96ee
2 changed files with 31 additions and 1 deletions

View File

@ -74,6 +74,31 @@ DEFINE_EVENT(memcg_rstat_events, count_memcg_events,
TP_ARGS(memcg, item, val)
);
TRACE_EVENT(memcg_flush_stats,
TP_PROTO(struct mem_cgroup *memcg, s64 stats_updates,
bool force, bool needs_flush),
TP_ARGS(memcg, stats_updates, force, needs_flush),
TP_STRUCT__entry(
__field(u64, id)
__field(s64, stats_updates)
__field(bool, force)
__field(bool, needs_flush)
),
TP_fast_assign(
__entry->id = cgroup_id(memcg->css.cgroup);
__entry->stats_updates = stats_updates;
__entry->force = force;
__entry->needs_flush = needs_flush;
),
TP_printk("memcg_id=%llu stats_updates=%lld force=%d needs_flush=%d",
__entry->id, __entry->stats_updates,
__entry->force, __entry->needs_flush)
);
#endif /* _TRACE_MEMCG_H */

View File

@ -597,7 +597,12 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val)
static void __mem_cgroup_flush_stats(struct mem_cgroup *memcg, bool force)
{
if (!force && !memcg_vmstats_needs_flush(memcg->vmstats))
bool needs_flush = memcg_vmstats_needs_flush(memcg->vmstats);
trace_memcg_flush_stats(memcg, atomic64_read(&memcg->vmstats->stats_updates),
force, needs_flush);
if (!force && !needs_flush)
return;
if (mem_cgroup_is_root(memcg))