Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memcg: Prepare to protect against concurrent isolated cpuset change

The HK_TYPE_DOMAIN housekeeping cpumask will soon be made modifiable at
runtime. In order to synchronize against memcg workqueue to make sure
that no asynchronous draining is pending or executing on a newly made
isolated CPU, target and queue a drain work under the same RCU critical
section.

Whenever housekeeping will update the HK_TYPE_DOMAIN cpumask, a memcg
workqueue flush will also be issued in a further change to make sure
that no work remains pending after a CPU has been made isolated.

Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Marco Crivellari <marco.crivellari@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Waiman Long <longman@redhat.com>

+17 -4
+17 -4
mm/memcontrol.c
··· 2003 2003 return flush; 2004 2004 } 2005 2005 2006 + static void schedule_drain_work(int cpu, struct work_struct *work) 2007 + { 2008 + /* 2009 + * Protect housekeeping cpumask read and work enqueue together 2010 + * in the same RCU critical section so that later cpuset isolated 2011 + * partition update only need to wait for an RCU GP and flush the 2012 + * pending work on newly isolated CPUs. 2013 + */ 2014 + guard(rcu)(); 2015 + if (!cpu_is_isolated(cpu)) 2016 + schedule_work_on(cpu, work); 2017 + } 2018 + 2006 2019 /* 2007 2020 * Drains all per-CPU charge caches for given root_memcg resp. subtree 2008 2021 * of the hierarchy under it. ··· 2045 2032 &memcg_st->flags)) { 2046 2033 if (cpu == curcpu) 2047 2034 drain_local_memcg_stock(&memcg_st->work); 2048 - else if (!cpu_is_isolated(cpu)) 2049 - schedule_work_on(cpu, &memcg_st->work); 2035 + else 2036 + schedule_drain_work(cpu, &memcg_st->work); 2050 2037 } 2051 2038 2052 2039 if (!test_bit(FLUSHING_CACHED_CHARGE, &obj_st->flags) && ··· 2055 2042 &obj_st->flags)) { 2056 2043 if (cpu == curcpu) 2057 2044 drain_local_obj_stock(&obj_st->work); 2058 - else if (!cpu_is_isolated(cpu)) 2059 - schedule_work_on(cpu, &obj_st->work); 2045 + else 2046 + schedule_drain_work(cpu, &obj_st->work); 2060 2047 } 2061 2048 } 2062 2049 migrate_enable();