CommitFest 7381 Review: doc: Document Linux cgroup memory limits
code-review · generated from canonical Markdown
code-review
postgresql-master
commitfest-7381-review2026-10-02T20:36:06.587416+00:00
Front matter
schema: review-report-v2 slug: commitfest-7381-review source: postgresql-master title: "CommitFest 7381 Review: doc: Document Linux cgroup memory limits" verdict: ready-for-committer target: "CommitFest 7381 — staged diff on doc/src/sgml/runtime.sgml (+51 lines, new <sect2 id=\"linux-memory-cgroups\">)" base: 6f3bdadaadc4692050ca20dff53d3890088b9272 head: 6f3bdadaadc4692050ca20dff53d3890088b9272 blocker_verified: 0 blocker_unverified: 0
CommitFest 7381 Review: doc: Document Linux cgroup memory limits
Scope
| Field | Value |
|---|---|
| Patch | CommitFest 7381 — doc: Document Linux cgroup memory limits |
| Author | joao.detomini@enterprisedb.com |
| Message-ID | CABH8dKwkp1_TzR7nxfvSpRSLD1b33xw7N_VLMLy3MiaEjAEPNw@mail.gmail.com |
| Thread-ID | 657829 (pgsql-hackers, 2026-10-01) |
| Base/HEAD | 6f3bdadaadc4692050ca20dff53d3890088b9272 (== origin/master) |
| Diff SHA-256 | 207a37b869a4e9c442f1de4d0a88717a3f9b4ffa55b3b704da1cd1b651e2aea7 |
| Changed file | doc/src/sgml/runtime.sgml (added lines 1441–1490) |
| Changed symbols | NONE — documentation-only (SGML prose) |
| Scope type | Uncommitted staged diff against frozen HEAD |
The patch adds a new <sect2 id="linux-memory-cgroups"> titled "Linux Control Group Memory Limits" to doc/src/sgml/runtime.sgml, placed between the existing linux-memory-overcommit section and the linux-huge-pages section. It documents:
- cgroup v2
memory.maxlimits - OOM killer behavior within a cgroup
- postmaster crash-restart behavior when a backend is OOM-killed
- which PostgreSQL memory (shared buffers, per-session
work_mem, etc.) counts towards the cgroup limit - huge pages caveat (not counted towards cgroup usage by default)
- cross-references to 8 existing GUC/section anchors (all verified to resolve)
Verdict
PostgreSQL readiness: ready-for-committer
Blocker split: 0 verified / 0 unverified
The patch is technically accurate, well-structured, and fills a genuine documentation gap for operators running PostgreSQL in containers. All factual claims about cgroup v2 behavior were verified against the kernel documentation and the PostgreSQL postmaster source code. All cross-references resolve. SGML is well-formed. The 5 findings are all MINOR or NIT — completeness suggestions that would improve the documentation but do not represent errors. The patch is suitable for committer application; the nits can be addressed at the committer's discretion or in a follow-up.
Deterministic verdict logic
- 0 surviving BLOCKER findings → not
waiting-on-author - 0 correctness/security MAJOR findings → not
needs-review - 0 test-only MAJOR findings → not
ready-for-committer (test follow-up required) - 3 MINOR + 2 NIT docs findings, all verified →
ready-for-committer
Findings Summary
| ID | Severity | Class | Location | Verification | Description |
|---|---|---|---|---|---|
| F1 | MINOR | docs | doc/src/sgml/runtime.sgml:1462-1463 | verified | cgroup v1 dismissal too terse; does not name memory.limit_in_bytes |
| F2 | MINOR | docs | doc/src/sgml/runtime.sgml:1466-1468 | verified | OOM victim selection nuance omitted; postmaster could be victim; memory.oom.group not mentioned |
| F3 | MINOR | docs | doc/src/sgml/runtime.sgml:1476-1487 | verified | Sizing guidance omits temp buffers and other per-process memory |
| F4 | NIT | docs | doc/src/sgml/runtime.sgml:1485-1487 | verified | Huge pages caveat could mention memory_hugetlb_accounting mount option |
| F5 | NIT | docs | doc/src/sgml/runtime.sgml:1444-1450 | verified | Indexterm entries could use <see> cross-reference for better index structure |
Verification Summary
All 5 findings were independently verified by the pg-finding-verifier seat. No findings were refuted.
| Finding | Status | Method | Repair Patch | Repair Validation |
|---|---|---|---|---|
| F1 | verified | source inspection + kernel-doc cross-reference | provided (shared with F2/F4) | partial (xmllint structural) |
| F2 | verified | source inspection + kernel-doc cross-reference | provided (shared with F1/F4) | partial (xmllint structural) |
| F3 | verified | source inspection + GUC anchor cross-reference | provided | partial (xmllint structural + anchor check) |
| F4 | verified | source inspection + kernel-doc cross-reference | provided (shared with F1/F2) | partial (xmllint structural) |
| F5 | verified | source inspection + codebase convention cross-reference | provided | partial (xmllint structural + convention match) |
Verification methodology
- Read the actual added lines (1441–1490) of
doc/src/sgml/runtime.sgmlin the read-only worktree. - Fetched the authoritative Linux kernel cgroup-v2 documentation and confirmed all factual claims:
memory.maxis the v2 hard limit file- v1 equivalent is
memory.limit_in_bytes memory.oom.groupkills all tasks together when setmemory_hugetlb_accountingmount option results in SIGBUS on charge failure
- Inspected SGML conventions in the same file/codebase (
<see>,<secondary>,<systemitem>,<option>are all established elements). - Built disposable scratch worktree copies, applied candidate edits, ran
git apply --checkandxmllint --noout --noneton each patched file — no new parse errors introduced. - Full
make docs/FOP build was not run (no doc build infrastructure in scratch environment);xmllintstructural check is the strongest available automated gate.
Repair Validation Summary
All 5 findings have concrete provided repair patches (unified diffs bound to frozen HEAD). Repair validation status is partial for all findings: git apply --check succeeded and xmllint --noout --nonet confirmed no new structural errors in the edited regions, but a full DocBook HTML/PDF render was not possible in the disposable scratch environment (no DTD catalog/FOP toolchain).
| Patch | Covers | SHA-256 | Validation |
|---|---|---|---|
cf7381-f1-f2-f4-v2.patch | F1, F2, F4 | 1da14ce56ee4eed2b8bb47d38dc541c0b54c5261da10a8832e1f3d29d1fc212d | partial: apply-check + xmllint |
cf7381-f3.patch | F3 | 183ee7e7f1254b4a84962e8c10b3ce883843bc414961357463e41471cccb1e2d | partial: apply-check + xmllint + anchor check |
cf7381-f5.patch | F5 | 67a3c85cff78ce0800d6b03a73eb1cab831458bd14616041cfd41390d3312db1 | partial: apply-check + xmllint + convention match |
Patch application order note
F1+F2+F4 and F3 both touch the sizing paragraph around lines 1484–1494. If both are applied, F3 should be applied after the F1+F2+F4 patch. F5 is independent and applies cleanly in any order. All three patches were validated independently against the original staged diff.
Changed-Code Coverage
Status: not-applicable
The patch is documentation-only: it adds SGML prose to doc/src/sgml/runtime.sgml (a new <sect2> subsection on Linux cgroup memory limits). There are no changed C/C++/SQL/catalog/test files, no changed executable implementation lines, no changed branches, and no changed functions. Coverage instrumentation is not applicable to SGML documentation files.
| Field | Value |
|---|---|
coverage_requirement.status | not-applicable |
coverage_requirement.changed_instrumentable_paths | [] (empty) |
coverage.status | not-applicable |
coverage.reason | Documentation-only patch; no executable code introduced or modified |
| Non-instrumented changes | doc/src/sgml/runtime.sgml — SGML documentation source; not instrumentable by gcov/gcovr |
Security Assessment
CLEAN — no security issues. (from pg-security-reviewer seat)
The patch is documentation-only with no C, SQL, catalog, GUC-default, authentication, TLS, or extension-script changes. The PG-specific vulnerability classes (privilege escalation, SECURITY DEFINER search_path, catalog-write TOCTOU, SQL injection, crypto/TLS, superuser guards) are not applicable.
The documentation content was reviewed for security-sensitive operational guidance:
- OOM-kill → postmaster crash-restart semantics: accurate
- Memory sizing guidance: sound operational advice
- Huge-pages caveat: accurate and security-useful (warns admins that huge-page memory can escape cgroup accounting)
- No recommendation to disable OOM protection
- External URL (
https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html): official kernel.org HTTPS documentation, consistent with existing citations in the same file
Thread Reconciliation
Status: no-thread-found
The patch was posted to pgsql-hackers on 2026-10-01 by joao.detomini@enterprisedb.com as Thread-ID 657829. No reviews or replies have been posted to this thread as of the review date. A related but separate thread (Thread-ID 657840, subject "Exposing the cgroup memory limit to SQL?") exists but discusses a different feature proposal and contains no review of this documentation patch.
All 5 findings are classified as new (no prior discussion in the thread).
Detailed Findings
— MINOR (docs): cgroup v1 dismissal too terse
- Location:
doc/src/sgml/runtime.sgml:1462-1463 - Mechanism: Text says "Version 1 uses different files and is not covered here" but does not name the v1 equivalent (
memory.limit_in_bytes). Some production deployments still run cgroup v1. - Failure: A reader on a v1 system may find this section via the index but be unable to map the advice to their system without external research.
- Verification: verified — kernel cgroup-v2 doc explicitly references "the original
memory.limit_in_bytes" as the v1 hard-limit file. - Repair: Extend the parenthetical to name
memory.limit_in_bytes:
<filename>memory.max</filename> file. (Version 1 uses different files and is not covered here; in version 1 the equivalent file is <filename>memory.limit_in_bytes</filename>.)
- Test example:
cd doc/src/sgml && make html && grep -q 'memory.limit_in_bytes' postgresql.html(oracle: exit 0)
— MINOR (docs): OOM victim selection nuance omitted
- Location:
doc/src/sgml/runtime.sgml:1466-1468 - Mechanism: Text says "the OOM killer terminates a process of the cgroup." Kernel docs describe
memory.oom.group(kills all tasks together when set) and note the OOM killer may select the postmaster itself as victim. - Failure: The phrasing "terminates a process" (singular) does not alert the operator that the postmaster itself could be the OOM victim, or that
memory.oom.groupwould kill all PostgreSQL processes simultaneously. - Verification: verified — kernel
memory.oom.groupdoc: "If set, all tasks belonging to the cgroup or to its descendants are killed together or not at all." - Repair: Add
memory.oom.groupparenthetical and postmaster-victim sentence:
the OOM killer terminates a process of the cgroup (or, if the cgroup has <filename>memory.oom.group</filename> set, all processes in the cgroup). The OOM victim could be the postmaster itself.
- Test example:
cd doc/src/sgml && make html && grep -q 'memory.oom.group' postgresql.html && grep -q 'postmaster itself' postgresql.html
— MINOR (docs): Sizing guidance omits temp buffers and other per-process memory
- Location:
doc/src/sgml/runtime.sgml:1476-1487 - Mechanism: The paragraph enumerates
shared_buffers,work_mem,hash_mem_multiplier,maintenance_work_mem, andmax_connectionsbut omitstemp_buffers, WAL buffers, autovacuum worker memory, parallel worker memory, catalog cache, etc. - Failure: An operator following this guidance literally might underestimate actual cgroup memory usage and still hit OOM.
- Verification: verified —
guc-temp-buffersanchor exists inconfig.sgml(line 1935); WAL buffers, autovacuum workers, parallel workers are all real per-process consumers not mentioned. - Repair: Add a non-exhaustive caveat with
temp_buffersexample:
total stays below the limit. Note that this list is not exhaustive; other per-process memory such as <xref linkend="guc-temp-buffers"/>, WAL buffers, and catalog caches also counts towards the cgroup usage.
- Test example:
cd doc/src/sgml && make html && grep -q 'not exhaustive' postgresql.html
— NIT (docs): Huge pages caveat could mention memory_hugetlb_accounting
- Location:
doc/src/sgml/runtime.sgml:1485-1487 - Mechanism: Text says huge pages are "by default not counted" but doesn't name the
memory_hugetlb_accountingmount option that changes this, or that it results in SIGBUS rather than OOM kill. - Failure: An operator whose system has
memory_hugetlb_accountingenabled would get SIGBUS rather than OOM kill and would not be warned. - Verification: verified — kernel doc: "Failure to charge a HugeTLB folio to the memory controller results in SIGBUS."
- Repair: Extend the caveat to name the mount option and SIGBUS:
(see <xref linkend="guc-huge-pages"/>) is by default not counted towards the memory usage of the cgroup, unless the cgroup v2 mount option <option>memory_hugetlb_accounting</option> is used; with that option, a charge failure results in <systemitem>SIGBUS</systemitem> rather than an OOM kill.
- Test example:
cd doc/src/sgml && make html && grep -q 'memory_hugetlb_accounting' postgresql.html && grep -q 'SIGBUS' postgresql.html
— NIT (docs/style): Indexterm entries could use <see> cross-reference
- Location:
doc/src/sgml/runtime.sgml:1444-1450 - Mechanism: "cgroup" and "control group" are near-synonyms; a
<see>cross-reference between them would improve index usability. The codebase already uses this pattern for TSC and GEQO. - Failure: The index will have two separate entries for essentially the same concept without a cross-reference.
- Verification: verified —
config.sgmlhas<primary>Time-Stamp Counter</primary><see>TSC</see>and<primary>GEQO</primary><see>genetic query optimization</see>. - Repair: Add
<see>control group</see>to the cgroup indexterm:
<indexterm> <primary>cgroup</primary> <see>control group</see> </indexterm>
- Test example:
cd doc/src/sgml && make html && grep -qi 'cgroup.*see.*control group' postgresql.html
Verified Clean (Non-Findings)
- SGML well-formedness: PASS —
xmllint --nooutreports no well-formedness errors in the new section. - Cross-reference target integrity: PASS — all 8
<xref linkend="..."/>targets verified to exist in the doc tree. - Section ID uniqueness: PASS —
linux-memory-cgroupsappears exactly once in the entire doc tree. - Section placement: PASS — placed between
linux-memory-overcommitandlinux-huge-pageswithin<sect1 id="kernel-resources">, forming a coherent progression. - Technical accuracy: PASS — all factual claims about cgroup v2 behavior verified against kernel documentation and PostgreSQL postmaster source code.
- DocBook style compliance: PASS — correct use of
<firstterm>,<filename>,<varname>,<productname>,<xref>; two-space sentence separation maintained; indexterm placement follows existing pattern.
Aggregated Test Plan
| Test | Vehicle | Target | Oracle |
|---|---|---|---|
| Full doc build | doc-build | doc/src/sgml/runtime.sgml | make html succeeds without broken-xref or validation warnings |
| F1 verification | doc-build | doc/src/sgml/runtime.sgml | grep -q 'memory.limit_in_bytes' postgresql.html exits 0 |
| F2 verification | doc-build | doc/src/sgml/runtime.sgml | grep -q 'memory.oom.group' postgresql.html && grep -q 'postmaster itself' postgresql.html exits 0 |
| F3 verification | doc-build | doc/src/sgml/runtime.sgml | grep -q 'not exhaustive' postgresql.html exits 0 |
| F4 verification | doc-build | doc/src/sgml/runtime.sgml | grep -q 'memory_hugetlb_accounting' postgresql.html && grep -q 'SIGBUS' postgresql.html exits 0 |
| F5 verification | doc-build | doc/src/sgml/runtime.sgml | grep -qi 'cgroup.*see.*control group' postgresql.html exits 0 |
| Structural check | inspection | doc/src/sgml/runtime.sgml | xmllint --noout --nonet reports no new errors in lines 1441-1490 |
Residual Risk
Low. The patch is documentation-only with no runtime impact. All findings are MINOR/NIT completeness suggestions. The repair patches are concrete and validated structurally but not rendered (full doc build unavailable in scratch environment). The committer should run make html or equivalent to confirm the rendered output before applying any repair patches.
Provenance
| Seat | Model | Role | Handoff Slug | Status |
|---|---|---|---|---|
| pg-patch-reviewer | glm-5.2:cloud | Generic review, PG filter, readiness, test mapping | commitfest-7381-review-handoff-patch-reviewer | completed |
| pg-security-reviewer | glm-5.2:cloud | PG security + delegated C memory safety | commitfest-7381-review-handoff-security-reviewer | completed |
| pg-finding-verifier | glm-5.2:cloud | Finding + repair verification | commitfest-7381-review-handoff-verifier | completed |
| pg-review-harness (coordinator) | glm-5.2:cloud | Orchestration, coverage, verdict, artifact | — | completed |
Validator
- Validator: run-scoped
validate_review_artifact.py(SHA-256edbcb304ffbd062627196c1ee0ce3d9b60cae80dd7b201e420335fea0a31979e) - Result:
ok: pg-review-artifact-v2 is structurally complete - Artifact:
review-artifact-v2.json(run-scoped v2 JSON artifact, validated before rendering)
Hard Constraints Compliance
- The reviewed worktree was not modified (read-only).
- All candidate repair patches were validated only in disposable scratch worktree copies.
- No commits, pushes, or staging operations were performed.
- All citations use repo-relative paths.
- No local absolute paths or credentials are persisted in durable output.
- Every run/repair claim came from a seat that executed it.
- The v2 artifact passed the SHA-256-bound validator before rendering.