Re: [PATCH] Docs/admin-guide/cgroup-v2: document hierarchical cpu.max throttling behavior
Shaojie Sun <[email protected]> Mon, 27 Jul 2026 11:18:55 +0800
| Newsgroups | org.kernel.vger.cgroups,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi, Michal. On Fri, 24 Jul 2026 13:21:46, Michal wrote: >On Fri, Jul 24, 2026 at 06:25:00PM +0800, Shaojie Sun <[email protected]> wrote: >> diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst >> index 14b8c571c0d1..3572d3e7f688 100644 >> --- a/Documentation/admin-guide/cgroup-v2.rst >> +++ b/Documentation/admin-guide/cgroup-v2.rst > >> + and the resulting >> + throttling may reflect the combined effect of multiple levels >> + rather than any single level's limit alone (this differs from >> + other Limits-type controllers such as memory.max and io.max, >> + where the most restrictive limit along the hierarchy is >> + applied). > >I'm not sure from the description what the "combined effect" is. >Can you give an example where the cpu.max differs from that Limits-type >semantics? Here is an example to illustrate the difference. Consider: Parent: cpu.max = 50000 100000 (50%) Child: cpu.max = 20000 100000 (20%) With cpu.max, when the child's processes consume CPU, throttling can be triggered by either the child's own limit or the parent's limit independently — both levels participate in enforcement. This is visible in cpu.stat : the throttled_usec counter can accumulate non-zero values at both the child and parent level. Even when the child's quota is smaller than the parent's (20 < 50), the parent's limit still participates; conversely, when a child's quota is larger than the parent's, the child's own limit still participates. Compare this with memory.max. If we had: Parent: memory.max = 50M Child: memory.max = 20M The effective limit for the child is simply min(20M, 50M) = 20M — only the most restrictive limit along the path applies. The child will never see an OOM triggered by the parent's 50M limit before reaching its own 20M. In short: cpu.max enforcement is per-level independent — every level with cpu.max configured can independently throttle the group, and cpu.stat counters at multiple levels can all accumulate throttled_usec for the same workload. memory.max only enforces the tightest limit along the path. Thanks, Shaojie Sun