From nobody Tue Apr 7 14:05:32 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B19C382F1C for ; Fri, 3 Apr 2026 14:13:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775225599; cv=none; b=aJhJuGnKtm3DfSUHqELit7FzDeE6C91WRHi4WfZ22TH8GxUAqJvhx6/KcPk6xfZhkHC7TFxjUV+wiGekOzU05hO7aF5agSzAKfr7oa6jH+IP8hzsOEiWWUgs0qKOezF1CExwUIgtSF8SJ3VNOqL8AOzqJvxH2ni4il9nFlI4dr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775225599; c=relaxed/simple; bh=i3I3h69ANM+/CCAB91aIzVIiJh++XXV/lD/iV3+eRWw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iVJ2Roh77uRhGYW/lqkYkHbDeEmrPYnTDP5kka3lmT1LxIcB++lnBftwiLwpJC1heUCHk02cKGaLVl/UOYEjLDWuV4+ZVTd+C8frTml0k3EiesYcewQ4evh+E+xBNZywfmjnGSf0qnDiDrP9kqX99+6WJmmfaKjxS1SbAQI/9yA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Mvw43mvB; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=eTsJc/P1; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Mvw43mvB"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="eTsJc/P1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775225596; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q7VPU0rCKfWfvPJl/4bosCPDJZ8iv97Cw6zG7IjIUB0=; b=Mvw43mvBveue6wUU4etsmb4EtRnjUYBj4bo1UKsZTpKeKvmVuZm46xXPF53caUFMCjLtzv pqARb/hvVXm1ylR5iG1HVzIU2/DAQuo8ioQQaI4Mpd80hKEd30DeVtw3QVhC32C3/MZU5u QgpXzoBRFvlbNp2kUIIU2dGjORILyVk= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-45-IdGBq2PDOpiXs63heSuF7Q-1; Fri, 03 Apr 2026 10:13:15 -0400 X-MC-Unique: IdGBq2PDOpiXs63heSuF7Q-1 X-Mimecast-MFC-AGG-ID: IdGBq2PDOpiXs63heSuF7Q_1775225595 Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-509044f54aaso55643381cf.1 for ; Fri, 03 Apr 2026 07:13:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1775225595; x=1775830395; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Q7VPU0rCKfWfvPJl/4bosCPDJZ8iv97Cw6zG7IjIUB0=; b=eTsJc/P1kHw69IiIhfYrk/I4z3vWCmEWlzY4zeWmInON+aRsCWSNFC6x/g4k1+ToK3 ntkHDsse1/ctunrPW6lpwWliy4rRdl7uB2BdWVP2UvkQMJKM87R0aBEil/vP0buP4/y5 9+CkVumhLaAdLqdpm1wo3YNcuDMS4/6FUfec7F2DKT4hWfn62gycGMCdqO09urM+t3mK q+XO3w3QpWd8YXVKio/HmWWKCXwngC5PDK2JddRgBCBD1k2wi+M/PaJ/BM3d4/bPxkav v/sMtzuVVbaHerr9JG5powDnNPNKRj2fH3+H5NQlxBdCfTANWWgyWXcMMGdD6T/34LoG 3Wqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775225595; x=1775830395; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Q7VPU0rCKfWfvPJl/4bosCPDJZ8iv97Cw6zG7IjIUB0=; b=K24XeOoY8oj3xQ5y7egG2qYAQozfibF3UZfNcAXxDW9UeYvnoOFk2/JR+jP55ifgzT rYcfOfHBjXgxz6yHgwWAXAaCv8SGJ4qrC2Z07qfJ8ZsEfoIf7LAuKBIMddXhAw7JOOal L2YNT+h7Hgzo9LK0YY6KiwGmihey+rz1KVUYH3S8VJGc6LA/91PE9XfzTuE830je8Vm3 xezqiN6wf0V6cpUCleMehVrbyCxxajyeeugTqtaOKwylkF7GKT/SJ3LLOXYl7pzPN5mI zN+O58UYa2RkdYLA4oBxZ7Z8INBRSnO0h8u7embxlvlSQ62AvDwiOVKAypTIZQvoaolM a9Ig== X-Forwarded-Encrypted: i=1; AJvYcCUXuAtPn363QDaf6yX20V7+PuubYflErCZHEelpyh34tILrPkQbuhWqafFIYTB928WX0LK1nC7fJuszrxw=@vger.kernel.org X-Gm-Message-State: AOJu0YwJ2Jf+p9CzA46FX8I8zeuVPcvOBpQ8lW+M/125DKI9UTr0sgDc 7AVXlGs66+Iu2GKFLArmjkgsqNS5i5nmc3J5rdaRo9IHtME7wf5Ea/gUBGP0wZZFpothTdR30eZ bopUsJwIuj5rEOK7WEV7IJgGcAvGXvVv6Bxb1xwkxvlHzyxGKg+ycQ6xahHwKrLisyw== X-Gm-Gg: ATEYQzyoWg/Ecd1wz4qNh5u41N5WMiTW3cPX3w+d8UUINF0Zem1pPjm+NVFpgqlVHdQ njlO/Tv4yBp0927YD+2eS44YKhqe6fUlTCzZt4xIDyZh+brhK7TZl6wWFrd0OBEOp5VhamfTvek 1f5m9nypwDoK6ifpDF5gsvFkWiwJmkLTzT9himVrgaEGXgX+DvOPeiD+rpS6t+C8r14knaKlffN d7VweL+4k2aNVYEyWftw55ZuJnV8BiDgoJaFvbX4ixXNg7nX9XnCbde9Et4tK9yt3uOCOrl61hc rkX0dsdsLfaoH6BiSgNEj3CnMrQLaMVKgmXAVUjzqINV+mZejj36Uja+RH/9N1mplziQtonyptz NpgEiYkzArCYYkKZZ9v1oTqfLG91iegYaj+efhMHOH9rQfhhG6zKXQlB1Mo9coYA= X-Received: by 2002:a05:622a:1922:b0:509:2ef7:7048 with SMTP id d75a77b69052e-50d62cd74e1mr43969861cf.66.1775225594376; Fri, 03 Apr 2026 07:13:14 -0700 (PDT) X-Received: by 2002:a05:622a:1922:b0:509:2ef7:7048 with SMTP id d75a77b69052e-50d62cd74e1mr43969031cf.66.1775225593742; Fri, 03 Apr 2026 07:13:13 -0700 (PDT) Received: from localhost (pool-100-17-19-56.bstnma.fios.verizon.net. [100.17.19.56]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50d4d9ad4b6sm40723031cf.15.2026.04.03.07.13.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 07:13:12 -0700 (PDT) From: Eric Chanudet Date: Fri, 03 Apr 2026 10:08:36 -0400 Subject: [PATCH RFC 2/2] cgroup/dmem: add a node to double charge in memcg Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260403-cgroup-dmem-memcg-double-charge-v1-2-c371d155de2a@redhat.com> References: <20260403-cgroup-dmem-memcg-double-charge-v1-0-c371d155de2a@redhat.com> In-Reply-To: <20260403-cgroup-dmem-memcg-double-charge-v1-0-c371d155de2a@redhat.com> To: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , Andrew Morton , Maarten Lankhorst , Maxime Ripard , Natalie Vock , Tejun Heo , =?utf-8?q?Michal_Koutn=C3=BD?= Cc: cgroups@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Maxime Ripard , Albert Esteve , Dave Airlie , Eric Chanudet X-Mailer: b4 0.14.2 Introduce /cgroupfs/<>/dmem.memcg to make allocations in a dmem controlled region also be charged in memcg. This is disabled by default and requires the administrator to configure it through the cgroupfs before the first charge occurs. The memcg is derived from the pool's cgroup, if it exists, since the pool holds a ref to the dmem cgroup state keeping the cgroup alive and stable. The behavior is quirky. Since keeping track of each allocation would add a fair amount of logic without solving the problem entirely, disable the memcg switch once the first charge is issued. Having this as a dynamic configuration doesn't seem relevant anyway. Signed-off-by: Eric Chanudet --- kernel/cgroup/dmem.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c index 9d95824dc6fa09422274422313b63c25986596de..b65ae8cf0c302ce3773a7aa5f0d= 6d8223d2c10c9 100644 --- a/kernel/cgroup/dmem.c +++ b/kernel/cgroup/dmem.c @@ -17,6 +17,7 @@ #include #include #include +#include =20 struct dmem_cgroup_region { /** @@ -76,6 +77,9 @@ struct dmem_cgroup_pool_state { =20 refcount_t ref; bool inited; + + bool memcg; + bool memcg_locked; }; =20 /* @@ -162,6 +166,14 @@ set_resource_max(struct dmem_cgroup_pool_state *pool, = u64 val) page_counter_set_max(&pool->cnt, val); } =20 +static void +set_resource_memcg(struct dmem_cgroup_pool_state *pool, u64 val) +{ + /* Cannot change once a charge happened. */ + if (!pool->memcg_locked) + pool->memcg =3D !!val; +} + static u64 get_resource_low(struct dmem_cgroup_pool_state *pool) { return pool ? READ_ONCE(pool->cnt.low) : 0; @@ -182,11 +194,17 @@ static u64 get_resource_current(struct dmem_cgroup_po= ol_state *pool) return pool ? page_counter_read(&pool->cnt) : 0; } =20 +static u64 get_resource_memcg(struct dmem_cgroup_pool_state *pool) +{ + return pool ? READ_ONCE(pool->memcg) : 0; +} + static void reset_all_resource_limits(struct dmem_cgroup_pool_state *rpool) { set_resource_min(rpool, 0); set_resource_low(rpool, 0); set_resource_max(rpool, PAGE_COUNTER_MAX); + set_resource_memcg(rpool, 0); } =20 static void dmemcs_offline(struct cgroup_subsys_state *css) @@ -609,6 +627,20 @@ get_cg_pool_unlocked(struct dmemcg_state *cg, struct d= mem_cgroup_region *region) return pool; } =20 +static struct mem_cgroup *mem_cgroup_from_cgroup(struct cgroup *c) +{ + struct cgroup_subsys_state *css; + + if (mem_cgroup_disabled()) + return NULL; + + rcu_read_lock(); + css =3D cgroup_e_css(c, &memory_cgrp_subsys); + rcu_read_unlock(); + + return mem_cgroup_from_css(css); +} + /** * dmem_cgroup_uncharge() - Uncharge a pool. * @pool: Pool to uncharge. @@ -624,6 +656,13 @@ void dmem_cgroup_uncharge(struct dmem_cgroup_pool_stat= e *pool, u64 size) return; =20 page_counter_uncharge(&pool->cnt, size); + + struct mem_cgroup *memcg =3D mem_cgroup_from_cgroup(pool->cs->css.cgroup); + + if (pool->memcg && memcg) + mem_cgroup_uncharge_pages(memcg, + PAGE_ALIGN(size) >> PAGE_SHIFT); + css_put(&pool->cs->css); dmemcg_pool_put(pool); } @@ -655,6 +694,8 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *r= egion, u64 size, struct dmemcg_state *cg; struct dmem_cgroup_pool_state *pool; struct page_counter *fail; + struct mem_cgroup *memcg; + unsigned long nr_pages =3D PAGE_ALIGN(size) >> PAGE_SHIFT; int ret; =20 *ret_pool =3D NULL; @@ -670,7 +711,22 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *= region, u64 size, pool =3D get_cg_pool_unlocked(cg, region); if (IS_ERR(pool)) { ret =3D PTR_ERR(pool); - goto err; + goto err_css_put; + } + + pool->memcg_locked =3D true; + memcg =3D get_mem_cgroup_from_current(); + if (pool->memcg && memcg) { + ret =3D mem_cgroup_try_charge_pages(memcg, GFP_KERNEL, nr_pages); + if (ret) { + /* + * No dmem_cgroup_state_evict_valuable() could help, + * there's no ret_limit_pool to return. + */ + ret =3D -ENOMEM; + dmemcg_pool_put(pool); + goto err_memcg_put; + } } =20 if (!page_counter_try_charge(&pool->cnt, size, &fail)) { @@ -681,14 +737,21 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region = *region, u64 size, } dmemcg_pool_put(pool); ret =3D -EAGAIN; - goto err; + goto err_uncharge_memcg; } =20 + mem_cgroup_put(memcg); + /* On success, reference from get_current_dmemcs is transferred to *ret_p= ool */ *ret_pool =3D pool; return 0; =20 -err: +err_uncharge_memcg: + if (pool->memcg && memcg) + mem_cgroup_uncharge_pages(memcg, nr_pages); +err_memcg_put: + mem_cgroup_put(memcg); +err_css_put: css_put(&cg->css); return ret; } @@ -846,6 +909,17 @@ static ssize_t dmem_cgroup_region_max_write(struct ker= nfs_open_file *of, return dmemcg_limit_write(of, buf, nbytes, off, set_resource_max); } =20 +static int dmem_cgroup_memcg_show(struct seq_file *sf, void *v) +{ + return dmemcg_limit_show(sf, v, get_resource_memcg); +} + +static ssize_t dmem_cgroup_memcg_write(struct kernfs_open_file *of, char *= buf, + size_t nbytes, loff_t off) +{ + return dmemcg_limit_write(of, buf, nbytes, off, set_resource_memcg); +} + static struct cftype files[] =3D { { .name =3D "capacity", @@ -874,6 +948,12 @@ static struct cftype files[] =3D { .seq_show =3D dmem_cgroup_region_max_show, .flags =3D CFTYPE_NOT_ON_ROOT, }, + { + .name =3D "memcg", + .write =3D dmem_cgroup_memcg_write, + .seq_show =3D dmem_cgroup_memcg_show, + .flags =3D CFTYPE_NOT_ON_ROOT, + }, { } /* Zero entry terminates. */ }; =20 --=20 2.52.0