Re: [RFC PATCH 0/8] mm/memcontrol: introduce per-tier memory accounting and control

From: Gregory Price

Date: Wed Aug 19 2026 - 11:35:04 EST


On Wed, Aug 19, 2026 at 09:22:11PM +0800, liuqiqi@xxxxxxxxxx wrote:
> From: Qiqi Liu <liuqiqi@xxxxxxxxxx>
>
> Hi all,

Hi! Thank you for following up. A few things.

>
> Thank you all for your replies. I am not very familiar with the
> community's workflow and should have reviewed the mailing list
> archives and existing implementations more carefully. I sincerely
> apologize for any inconvenience this may have caused.
>

Less of an inconvience, we want to save you time as much as we want to
save the larger community's time. Having multiple interested parties
vet common work - rather than propose differing solutions - does that.

Welcome to the discussion, glad to have more eyes on the problem!

Hopefully I can provide some context on the history here, since I've
been working with Joshua for a while on this in the background.

> My work is based on
> https://lore.kernel.org/all/20260528134212.240492-1-liuqiqi@xxxxxxxxxx/

On this patch, It's not clear why an RCU-protected pointer is
unsuitable. RCU is hot-path safe, it's just not stable nor
sleep-safe, which should be sufficient for any operation which
may be looking up this particular mapping.

These values are not expected to be aggressively written to, so RCU
essentially becomes a NOP on the reader side - it's extremely cheap.

More ideologically - adding a cached value of an RCU protected value
is somewhat anti-thetical to the entire purpose of using RCU in the
first place - it creates more footguns than it solves.

That aside, getting to the tier-aware memcg limits...

> aiming to develop memory tiering limits for cgroups. During
> development, I referenced Joshua's v2, but failed to notice that
> v3 had already been posted when I submitted my series.
>
> I have studied Joshua's v3, and our core mechanisms are largely
> consistent. However, there are two differences:
>
> 1. Read/write per-tier interface (memory.tier): each cgroup
> tracks its memory usage by tier (e.g., DRAM, CXL), exposed
> via a new memory.tier control file. This file reports
> per-tier usage and accepts per-tier high (soft limit) and
> max (hard limit) settings. By default, these limits are
> automatically derived from memory.high/max based on each
> tier's capacity ratio, but manual overrides are supported,
> allowing administrators to constrain specific tiers on a
> per-cgroup basis.
>

There's two levels of operation we need to think about here:

1) What the kernel does by default without tuning
2) What the kernel enables admins to tune

If we don't have a cogent story around how #1 should occur for
this feature - then every knob you expose for #2 is just creating
a mess of tunables no one can possibly understand (let alone maintain).

That's why Joshua's series has no tunable knobs - any such knob is
simply unwarranted at this point. (This decision was born from both
on-list and in-person feedback).

> Its advantages are:
> - It can express allocations that fixed capacity ratios
> cannot.

Which should come from a use case born out of demonstrating fixed ratios
are actually insufficient and cannot be made to self-tune.

But we don't even have those yet.

> - Latency-sensitive tenants can be given a larger share of
> the fast tier.
> - High-capacity tenants can have their soft limits removed
> for the slow tier.
>

These are the same issue as the first bullet, just differently shaped.

> Whether or not to constrain a specific tier should be a
> decision made by the administrator on a per-cgroup basis.

This is an opinion, not a fact, and should be based on data that
demonstrates the kernel is incapable of making the (or a) "right"
decision in a sufficiently common scenario.

> When the fast tier cannot accommodate the working sets of all
> workloads, it should be the administrator's scheduling decision to
> determine fast-tier allocations.

There's basically 3 use-cases that have been collected that I've seen
which tier-aware memcg looks to address:


1) Self-policed fairness

Stiff per-tier limits that cgroups impose on themselves.
i.e. proactively applying tier(memory.high/max) to ensure no
container's tier(memory.min) is ever violated.

This creates reduced variance in exchange for lower throughput.

This is paradigm essentially does not exist today except via
cpuset.mems (e.g. putting everything for a task on CXL). This
is intended for things that want stronger QoS controls.

2) Opportunistic fairness

While there is sufficient space on a higher tier, cgroups should
be allowed to "over-use" the upper tier opportunistically to maximize
thoughput - but when someone's tier(memory.min) is violated because
another container is over-using, we nudge everyone toward fairness.

This creates higher throughput in exchange for increase variance.

This is milder modification to the existing global opportunistic
behavior. Think of it like trying to apply a soft memory QoS.

It's unclear whether this actually has value, but can probably
be accomplished via existing min/high/max, rather than needing new
sysfs toggles.

3) Per-cgroup adjustable tier limits.

A scheduler knows something about the workloads it wants to
have custom tier limits per-workload.

This should be seen as an evolution born out of finding where
1 and 2 are insufficient. It's putting the cart before the horse
to go directly to this point.

Very few of us are convinced such complexity is actually warranted,
especially because the simpler (and less ABI-permanent) #1 and #2
haven't even been fully explored.

> As Shakeel suggested, and given that Joshua's v3 already
> contains the core mechanism, I am dropping my current
> standalone patchset. I would like to ask if Joshua would be
> willing to collaborate with me on this, treating memory.tier
> as an extension to the patch series and proposing it as
> follow-up patches based on v3.
>

Joshua can speak for himself, but more eyes and testing and data is
always welcome.

~Gregory