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: nmi-safe slab stats updates

The objcg based kmem [un]charging can be called in nmi context and it may
need to update NR_SLAB_[UN]RECLAIMABLE_B stats. So, let's correctly
handle the updates of these stats in the nmi context.

Link: https://lkml.kernel.org/r/20250519063142.111219-5-shakeel.butt@linux.dev
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Shakeel Butt and committed by
Andrew Morton
15ca4fa9 9d3edf96

+33 -3
+33 -3
mm/memcontrol.c
··· 2515 2515 folio->memcg_data = (unsigned long)memcg; 2516 2516 } 2517 2517 2518 + #ifdef CONFIG_MEMCG_NMI_SAFETY_REQUIRES_ATOMIC 2519 + static inline void account_slab_nmi_safe(struct mem_cgroup *memcg, 2520 + struct pglist_data *pgdat, 2521 + enum node_stat_item idx, int nr) 2522 + { 2523 + struct lruvec *lruvec; 2524 + 2525 + if (likely(!in_nmi())) { 2526 + lruvec = mem_cgroup_lruvec(memcg, pgdat); 2527 + mod_memcg_lruvec_state(lruvec, idx, nr); 2528 + } else { 2529 + struct mem_cgroup_per_node *pn = memcg->nodeinfo[pgdat->node_id]; 2530 + 2531 + /* TODO: add to cgroup update tree once it is nmi-safe. */ 2532 + if (idx == NR_SLAB_RECLAIMABLE_B) 2533 + atomic_add(nr, &pn->slab_reclaimable); 2534 + else 2535 + atomic_add(nr, &pn->slab_unreclaimable); 2536 + } 2537 + } 2538 + #else 2539 + static inline void account_slab_nmi_safe(struct mem_cgroup *memcg, 2540 + struct pglist_data *pgdat, 2541 + enum node_stat_item idx, int nr) 2542 + { 2543 + struct lruvec *lruvec; 2544 + 2545 + lruvec = mem_cgroup_lruvec(memcg, pgdat); 2546 + mod_memcg_lruvec_state(lruvec, idx, nr); 2547 + } 2548 + #endif 2549 + 2518 2550 static inline void mod_objcg_mlstate(struct obj_cgroup *objcg, 2519 2551 struct pglist_data *pgdat, 2520 2552 enum node_stat_item idx, int nr) 2521 2553 { 2522 2554 struct mem_cgroup *memcg; 2523 - struct lruvec *lruvec; 2524 2555 2525 2556 rcu_read_lock(); 2526 2557 memcg = obj_cgroup_memcg(objcg); 2527 - lruvec = mem_cgroup_lruvec(memcg, pgdat); 2528 - mod_memcg_lruvec_state(lruvec, idx, nr); 2558 + account_slab_nmi_safe(memcg, pgdat, idx, nr); 2529 2559 rcu_read_unlock(); 2530 2560 } 2531 2561