[PATCH 7/8][SRU][OEM-5.17] mm/memcg: disable migration instead of preemption in drain_all_stock().

AceLan Kao acelan.kao at canonical.com
Wed Sep 21 03:19:23 UTC 2022


From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

BugLink: https://launchpad.net/bugs/1990330

Before the for-each-CPU loop, preemption is disabled so that so that
drain_local_stock() can be invoked directly instead of scheduling a
worker.  Ensuring that drain_local_stock() completed on the local CPU is
not correctness problem.  It _could_ be that the charging path will be
forced to reclaim memory because cached charges are still waiting for
their draining.

Disabling preemption before invoking drain_local_stock() is problematic
on PREEMPT_RT due to the sleeping locks involved.  To ensure that no CPU
migrations happens across for_each_online_cpu() it is enouhg to use
migrate_disable() which disables migration and keeps context preemptible
to a sleeping lock can be acquired.  A race with CPU hotplug is not a
problem because pcp data is not going away.  In the worst case we just
schedule draining of an empty stock.

Use migrate_disable() instead of get_cpu() around the
for_each_online_cpu() loop.

Link: https://lkml.kernel.org/r/20220226204144.1008339-7-bigeasy@linutronix.de
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
Acked-by: Michal Hocko <mhocko at suse.com>
Cc: Johannes Weiner <hannes at cmpxchg.org>
Cc: kernel test robot <oliver.sang at intel.com>
Cc: Michal Hocko <mhocko at kernel.org>
Cc: Michal Koutný <mkoutny at suse.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Roman Gushchin <roman.gushchin at linux.dev>
Cc: Shakeel Butt <shakeelb at google.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Vladimir Davydov <vdavydov.dev at gmail.com>
Cc: Waiman Long <longman at redhat.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
(cherry picked from commit 0790ed623847bbdd440ae29cc01da81c99834ea5)
Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao at canonical.com>
---
 mm/memcontrol.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a0da8c7d5808..9bda9cd91fde 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2318,7 +2318,8 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)
 	 * as well as workers from this path always operate on the local
 	 * per-cpu data. CPU up doesn't touch memcg_stock at all.
 	 */
-	curcpu = get_cpu();
+	migrate_disable();
+	curcpu = smp_processor_id();
 	for_each_online_cpu(cpu) {
 		struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu);
 		struct mem_cgroup *memcg;
@@ -2341,7 +2342,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)
 				schedule_work_on(cpu, &stock->work);
 		}
 	}
-	put_cpu();
+	migrate_enable();
 	mutex_unlock(&percpu_charge_mutex);
 }
 
-- 
2.25.1




More information about the kernel-team mailing list