Skip to content

Commit 3ac4638

Browse files
shakeelbakpm00
authored andcommitted
memcg: make memcg_rstat_updated nmi safe
Currently kernel maintains memory related stats updates per-cgroup to optimize stats flushing. The stats_updates is defined as atomic64_t which is not nmi-safe on some archs. Actually we don't really need 64bit atomic as the max value stats_updates can get should be less than nr_cpus * MEMCG_CHARGE_BATCH. A normal atomic_t should suffice. Also the function cgroup_rstat_updated() is still not nmi-safe but there is parallel effort to make it nmi-safe, so until then let's ignore it in the nmi context. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Shakeel Butt <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Muchun Song <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Sebastian Andrzej Siewior <[email protected]> Cc: Tejun Heo <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 15ca4fa commit 3ac4638

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

mm/memcontrol.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ struct memcg_vmstats {
531531
unsigned long events_pending[NR_MEMCG_EVENTS];
532532

533533
/* Stats updates since the last flush */
534-
atomic64_t stats_updates;
534+
atomic_t stats_updates;
535535
};
536536

537537
/*
@@ -557,7 +557,7 @@ static u64 flush_last_time;
557557

558558
static bool memcg_vmstats_needs_flush(struct memcg_vmstats *vmstats)
559559
{
560-
return atomic64_read(&vmstats->stats_updates) >
560+
return atomic_read(&vmstats->stats_updates) >
561561
MEMCG_CHARGE_BATCH * num_online_cpus();
562562
}
563563

@@ -571,7 +571,9 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val,
571571
if (!val)
572572
return;
573573

574-
cgroup_rstat_updated(memcg->css.cgroup, cpu);
574+
/* TODO: add to cgroup update tree once it is nmi-safe. */
575+
if (!in_nmi())
576+
cgroup_rstat_updated(memcg->css.cgroup, cpu);
575577
statc_pcpu = memcg->vmstats_percpu;
576578
for (; statc_pcpu; statc_pcpu = statc->parent_pcpu) {
577579
statc = this_cpu_ptr(statc_pcpu);
@@ -589,15 +591,15 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val,
589591
continue;
590592

591593
stats_updates = this_cpu_xchg(statc_pcpu->stats_updates, 0);
592-
atomic64_add(stats_updates, &statc->vmstats->stats_updates);
594+
atomic_add(stats_updates, &statc->vmstats->stats_updates);
593595
}
594596
}
595597

596598
static void __mem_cgroup_flush_stats(struct mem_cgroup *memcg, bool force)
597599
{
598600
bool needs_flush = memcg_vmstats_needs_flush(memcg->vmstats);
599601

600-
trace_memcg_flush_stats(memcg, atomic64_read(&memcg->vmstats->stats_updates),
602+
trace_memcg_flush_stats(memcg, atomic_read(&memcg->vmstats->stats_updates),
601603
force, needs_flush);
602604

603605
if (!force && !needs_flush)
@@ -4119,8 +4121,8 @@ static void mem_cgroup_css_rstat_flush(struct cgroup_subsys_state *css, int cpu)
41194121
}
41204122
WRITE_ONCE(statc->stats_updates, 0);
41214123
/* We are in a per-cpu loop here, only do the atomic write once */
4122-
if (atomic64_read(&memcg->vmstats->stats_updates))
4123-
atomic64_set(&memcg->vmstats->stats_updates, 0);
4124+
if (atomic_read(&memcg->vmstats->stats_updates))
4125+
atomic_set(&memcg->vmstats->stats_updates, 0);
41244126
}
41254127

41264128
static void mem_cgroup_fork(struct task_struct *task)

0 commit comments

Comments
 (0)