Commit 8814e3b8 authored by Shakeel Butt's avatar Shakeel Butt Committed by Andrew Morton
Browse files

memcg: make mod_memcg_state re-entrant safe against irqs

Let's make mod_memcg_state re-entrant safe against irqs.  The only thing
needed is to convert the usage of __this_cpu_add() to this_cpu_add().  In
addition, with re-entrant safety, there is no need to disable irqs.

mod_memcg_state() is not safe against nmi, so let's add warning if someone
tries to call it in nmi context.

Link: https://lkml.kernel.org/r/20250514184158.3471331-4-shakeel.butt@linux.dev


Signed-off-by: default avatarShakeel Butt <shakeel.butt@linux.dev>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent c7163535
Loading
Loading
Loading
Loading
+2 −18
Original line number Diff line number Diff line
@@ -903,19 +903,9 @@ struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
					    struct mem_cgroup *oom_domain);
void mem_cgroup_print_oom_group(struct mem_cgroup *memcg);

void __mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
		       int val);

/* idx can be of type enum memcg_stat_item or node_stat_item */
static inline void mod_memcg_state(struct mem_cgroup *memcg,
				   enum memcg_stat_item idx, int val)
{
	unsigned long flags;

	local_irq_save(flags);
	__mod_memcg_state(memcg, idx, val);
	local_irq_restore(flags);
}
void mod_memcg_state(struct mem_cgroup *memcg,
		     enum memcg_stat_item idx, int val);

static inline void mod_memcg_page_state(struct page *page,
					enum memcg_stat_item idx, int val)
@@ -1375,12 +1365,6 @@ static inline void mem_cgroup_print_oom_group(struct mem_cgroup *memcg)
{
}

static inline void __mod_memcg_state(struct mem_cgroup *memcg,
				     enum memcg_stat_item idx,
				     int nr)
{
}

static inline void mod_memcg_state(struct mem_cgroup *memcg,
				   enum memcg_stat_item idx,
				   int nr)
+4 −4
Original line number Diff line number Diff line
@@ -679,12 +679,12 @@ static int memcg_state_val_in_pages(int idx, int val)
}

/**
 * __mod_memcg_state - update cgroup memory statistics
 * mod_memcg_state - update cgroup memory statistics
 * @memcg: the memory cgroup
 * @idx: the stat item - can be enum memcg_stat_item or enum node_stat_item
 * @val: delta to add to the counter, can be negative
 */
void __mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
void mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
		       int val)
{
	int i = memcg_stats_index(idx);
@@ -698,7 +698,7 @@ void __mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,

	cpu = get_cpu();

	__this_cpu_add(memcg->vmstats_percpu->state[i], val);
	this_cpu_add(memcg->vmstats_percpu->state[i], val);
	val = memcg_state_val_in_pages(idx, val);
	memcg_rstat_updated(memcg, val, cpu);
	trace_mod_memcg_state(memcg, idx, val);
@@ -2918,7 +2918,7 @@ static void drain_obj_stock(struct obj_stock_pcp *stock)

			memcg = get_mem_cgroup_from_objcg(old);

			__mod_memcg_state(memcg, MEMCG_KMEM, -nr_pages);
			mod_memcg_state(memcg, MEMCG_KMEM, -nr_pages);
			memcg1_account_kmem(memcg, -nr_pages);
			if (!mem_cgroup_is_root(memcg))
				memcg_uncharge(memcg, nr_pages);