[PATCH 2/2] cgroup/dmem: introduce dmem.events.local for local counts

From: Hongfu Li

Date: Tue Jun 23 2026 - 23:13:29 EST


Add dmem.events.local for local-only low/max event counts per DMEM
region. Refactor the shared events show logic used by dmem.events.

Signed-off-by: Hongfu Li <lihongfu@xxxxxxxxxx>
---
Documentation/admin-guide/cgroup-v2.rst | 5 ++--
kernel/cgroup/dmem.c | 32 +++++++++++++++++++++----
2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index afc924539a41..5e4dbe4a75c6 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2881,7 +2881,7 @@ DMEM Interface Files
drm/0000:03:00.0/vram0 12550144
drm/0000:03:00.0/stolen 8650752

- dmem.events
+ dmem.events, dmem.events.local
A read-only file that reports the number of times each cgroup
has hit its configured memory limits. The format lists each
region on a single line, followed by the event counters::
@@ -2894,7 +2894,8 @@ DMEM Interface Files
``max`` counts how many times an allocation failed because the
cgroup or one of its ancestors hit ``dmem.max``.

- ``dmem.events`` contains hierarchical counts. This file exists
+ ``dmem.events`` contains hierarchical counts. ``dmem.events.local``
+ contains counts for only the cgroup itself. These files exist
for all cgroups except root.

HugeTLB
diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
index 79d4c5d0a046..29f8719561e6 100644
--- a/kernel/cgroup/dmem.c
+++ b/kernel/cgroup/dmem.c
@@ -60,6 +60,7 @@ struct dmemcg_state {
struct list_head pools;

struct cgroup_file events_file;
+ struct cgroup_file events_local_file;
};

enum dmemcg_memory_event {
@@ -84,6 +85,7 @@ struct dmem_cgroup_pool_state {
struct dmem_cgroup_pool_state *parent;

atomic_long_t events[DMEMCG_NR_EVENTS];
+ atomic_long_t events_local[DMEMCG_NR_EVENTS];

refcount_t ref;
bool inited;
@@ -196,6 +198,9 @@ static u64 get_resource_current(struct dmem_cgroup_pool_state *pool)
static void dmemcg_memory_event(struct dmem_cgroup_pool_state *pool,
enum dmemcg_memory_event event)
{
+ atomic_long_inc(&pool->events_local[event]);
+ cgroup_file_notify(&pool->cs->events_local_file);
+
for (; pool; pool = pool->parent) {
atomic_long_inc(&pool->events[event]);
cgroup_file_notify(&pool->cs->events_file);
@@ -203,11 +208,14 @@ static void dmemcg_memory_event(struct dmem_cgroup_pool_state *pool,
}

static long dmemcg_get_event(struct dmem_cgroup_pool_state *pool,
- enum dmemcg_memory_event event)
+ enum dmemcg_memory_event event, bool local)
{
if (!pool)
return 0;

+ if (local)
+ return atomic_long_read(&pool->events_local[event]);
+
return atomic_long_read(&pool->events[event]);
}

@@ -874,7 +882,7 @@ static int dmem_cgroup_region_max_show(struct seq_file *sf, void *v)
return dmemcg_limit_show(sf, v, get_resource_max);
}

-static int dmem_cgroup_region_events_show(struct seq_file *sf, void *v)
+static int dmemcg_events_show(struct seq_file *sf, void *v, bool local)
{
struct dmemcg_state *dmemcs = css_to_dmemcs(seq_css(sf));
struct dmem_cgroup_region *region;
@@ -885,14 +893,24 @@ static int dmem_cgroup_region_events_show(struct seq_file *sf, void *v)

seq_puts(sf, region->name);
seq_printf(sf, " low %ld max %ld\n",
- dmemcg_get_event(pool, DMEMCG_LOW),
- dmemcg_get_event(pool, DMEMCG_MAX));
+ dmemcg_get_event(pool, DMEMCG_LOW, local),
+ dmemcg_get_event(pool, DMEMCG_MAX, local));
}
rcu_read_unlock();

return 0;
}

+static int dmem_cgroup_region_events_show(struct seq_file *sf, void *v)
+{
+ return dmemcg_events_show(sf, v, false);
+}
+
+static int dmem_cgroup_region_events_local_show(struct seq_file *sf, void *v)
+{
+ return dmemcg_events_show(sf, v, true);
+}
+
static ssize_t dmem_cgroup_region_max_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{
@@ -933,6 +951,12 @@ static struct cftype files[] = {
.file_offset = offsetof(struct dmemcg_state, events_file),
.flags = CFTYPE_NOT_ON_ROOT,
},
+ {
+ .name = "events.local",
+ .seq_show = dmem_cgroup_region_events_local_show,
+ .file_offset = offsetof(struct dmemcg_state, events_local_file),
+ .flags = CFTYPE_NOT_ON_ROOT,
+ },
{ } /* Zero entry terminates. */
};

--
2.25.1