Patch "memcg: make mem_cgroup_read_stat() unsigned" has been added to the 4.2-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
memcg: make mem_cgroup_read_stat() unsigned
to the 4.2-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
memcg-make-mem_cgroup_read_stat-unsigned.patch
and it can be found in the queue-4.2 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
484ebb3b8c8b27dd2171696462a3116edb9ff801Mon Sep 17 00:00:00 2001
From: Greg Thelen <[email protected]>
Date: Thu, 1 Oct 2015 15:37:05 -0700
Subject: memcg: make mem_cgroup_read_stat() unsigned
From: Greg Thelen <[email protected]>
commit 484ebb3b8c8b27dd2171696462a3116edb9ff801 upstream.
mem_cgroup_read_stat() returns a page count by summing per cpu page counters. The summing is racy wrt. updates, so a transient negative sum is possible. Callers don't want negative values:
- mem_cgroup_wb_stats() doesn't want negative nr_dirty or nr_writeback. This could confuse dirty throttling.
- oom reports and memory.stat shouldn't show confusing negative usage.
- tree_usage() already avoids negatives.
Avoid returning negative page counts from mem_cgroup_read_stat() and convert it to unsigned.
--- mm/memcontrol.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
mm/memcontrol.c +18 -12
@@ -806,12 +806,14 @@ mem_cgroup_largest_soft_limit_node(struc }/* +* Return page count for single (non recursive) @memcg. +* * Implementation Note: reading percpu statistics for memcg. * * Both of vmstat[] and percpu_counter has threshold and do periodic * synchronization to implement "quick" read. There are trade-off between * reading cost and precision of value. Then, we may have a chance to implement -* a periodic synchronizion of counter in memcg's counter. +* a periodic synchronization of counter in memcg's counter. * * But this _read() function is used for user interface now. The user accounts * memory usage by memory cgroup and he _always_ requires exact value because
@@ -821,17 +823,24 @@ mem_cgroup_largest_soft_limit_node(struc* * If there are kernel internal actions which can make use of some not-exact * value, and reading all cpu value can be performance bottleneck in some -* common workload, threashold and synchonization as vmstat[] should be +* common workload, threshold and synchronization as vmstat[] should be * implemented. */ -static long mem_cgroup_read_stat (struct mem_cgroup *memcg, -enum mem_cgroup_stat_index idx) +static unsigned long +mem_cgroup_read_stat (struct mem_cgroup *memcg,enum mem_cgroup_stat_index idx) {long val =0 ;int cpu; +/* Per-cpu values can be negative, use a signed accumulator */ for_each_possible_cpu (cpu) val +=per_cpu (memcg->stat->count[idx], cpu); +/* +* Summing races with updates, so val may be negative. Avoid exposing +* transient negative values. +*/ +if (val <0 ) + val =0 ;return val; }
@@ -1498,7 +1507,7 @@ void mem_cgroup_print_oom_info(struct mefor (i =0 ; i <MEM_CGROUP_STAT_NSTATS ; i++) {if (i ==MEM_CGROUP_STAT_SWAP && !do_swap_account)continue ; -pr_cont (" %s:%ldKB" , mem_cgroup_stat_names[i], +pr_cont (" %s:%luKB" , mem_cgroup_stat_names[i],K (mem_cgroup_read_stat (iter, i))); }
@@ -3119,14 +3128,11 @@ static unsigned long tree_stat(struct me enum mem_cgroup_stat_index idx) {struct mem_cgroup *iter; -long val =0 ; +unsigned long val =0 ; -/* Per-cpu values can be negative, use a signed accumulator */ for_each_mem_cgroup_tree (iter, memcg) val +=mem_cgroup_read_stat (iter, idx); -if (val <0 )/* race ? */ - val =0 ;return val; }
@@ -3469,7 +3475,7 @@ static int memcg_stat_show(struct seq_fifor (i =0 ; i <MEM_CGROUP_STAT_NSTATS ; i++) {if (i ==MEM_CGROUP_STAT_SWAP && !do_swap_account)continue ; -seq_printf (m,"%s %ld\n" , mem_cgroup_stat_names[i], +seq_printf (m,"%s %lu\n" , mem_cgroup_stat_names[i],mem_cgroup_read_stat (memcg, i) *PAGE_SIZE ); }
@@ -3494,13 +3500,13 @@ static int memcg_stat_show(struct seq_fi (u64)memsw * PAGE_SIZE);for (i =0 ; i <MEM_CGROUP_STAT_NSTATS ; i++) { -long long val =0 ; +unsigned long long val =0 ;if (i ==MEM_CGROUP_STAT_SWAP && !do_swap_account)continue ;for_each_mem_cgroup_tree (mi, memcg) val +=mem_cgroup_read_stat (mi, i) *PAGE_SIZE ; -seq_printf (m,"total_%s %lld\n" , mem_cgroup_stat_names[i], val); +seq_printf (m,"total_%s %llu\n" , mem_cgroup_stat_names[i], val); }for (i =0 ; i <MEM_CGROUP_EVENTS_NSTATS ; i++) {
Patches currently in stable-queue which might be from [email protected] are
queue-4.2/memcg-make-mem_cgroup_read_stat-unsigned.patch