Skip to content

Commit 85b9679

Browse files
committed
mm: memcg: use READ_ONCE()/WRITE_ONCE() to access stock->cached
jira KERNEL-325 Rebuild_History Non-Buildable kernel-4.18.0-553.89.1.el8_10 commit-author Roman Gushchin <roman.gushchin@linux.dev> commit f785a8f A memcg pointer in the percpu stock can be accessed by drain_all_stock() from another cpu in a lockless way. In theory it might lead to an issue, similar to the one which has been discovered with stock->cached_objcg, where the pointer was zeroed between the check for being NULL and dereferencing. In this case the issue is unlikely a real problem, but to make it bulletproof and similar to stock->cached_objcg, let's annotate all accesses to stock->cached with READ_ONCE()/WTRITE_ONCE(). Link: https://lkml.kernel.org/r/20230502160839.361544-2-roman.gushchin@linux.dev Signed-off-by: Roman Gushchin <roman.gushchin@linux.dev> Acked-by: Shakeel Butt <shakeelb@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Yosry Ahmed <yosryahmed@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> (cherry picked from commit f785a8f) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 86dfd78 commit 85b9679

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

mm/memcontrol.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,7 +2307,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
23072307
local_irq_save(flags);
23082308

23092309
stock = this_cpu_ptr(&memcg_stock);
2310-
if (memcg == stock->cached && stock->nr_pages >= nr_pages) {
2310+
if (memcg == READ_ONCE(stock->cached) && stock->nr_pages >= nr_pages) {
23112311
stock->nr_pages -= nr_pages;
23122312
ret = true;
23132313
}
@@ -2322,7 +2322,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
23222322
*/
23232323
static void drain_stock(struct memcg_stock_pcp *stock)
23242324
{
2325-
struct mem_cgroup *old = stock->cached;
2325+
struct mem_cgroup *old = READ_ONCE(stock->cached);
23262326

23272327
if (!old)
23282328
return;
@@ -2335,7 +2335,7 @@ static void drain_stock(struct memcg_stock_pcp *stock)
23352335
}
23362336

23372337
css_put(&old->css);
2338-
stock->cached = NULL;
2338+
WRITE_ONCE(stock->cached, NULL);
23392339
}
23402340

23412341
static void drain_local_stock(struct work_struct *dummy)
@@ -2371,10 +2371,10 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages)
23712371
local_irq_save(flags);
23722372

23732373
stock = this_cpu_ptr(&memcg_stock);
2374-
if (stock->cached != memcg) { /* reset if necessary */
2374+
if (READ_ONCE(stock->cached) != memcg) { /* reset if necessary */
23752375
drain_stock(stock);
23762376
css_get(&memcg->css);
2377-
stock->cached = memcg;
2377+
WRITE_ONCE(stock->cached, memcg);
23782378
}
23792379
stock->nr_pages += nr_pages;
23802380

@@ -2408,7 +2408,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)
24082408
bool flush = false;
24092409

24102410
rcu_read_lock();
2411-
memcg = stock->cached;
2411+
memcg = READ_ONCE(stock->cached);
24122412
if (memcg && stock->nr_pages &&
24132413
mem_cgroup_is_descendant(memcg, root_memcg))
24142414
flush = true;

0 commit comments

Comments
 (0)