CommitFest 7381 Review: doc: Document Linux cgroup memory limits

code-review · generated from canonical Markdown

Type
code-review
Source
postgresql-master
Slug
commitfest-7381-review
Tags
code-reviewdocspg-review-harnesspostgresql
Updated
2026-10-02T20:36:06.587416+00:00
Verdict / Summaryready-for-committer
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

FieldValue
PatchCommitFest 7381 — doc: Document Linux cgroup memory limits
Authorjoao.detomini@enterprisedb.com
Message-IDCABH8dKwkp1_TzR7nxfvSpRSLD1b33xw7N_VLMLy3MiaEjAEPNw@mail.gmail.com
Thread-ID657829 (pgsql-hackers, 2026-10-01)
Base/HEAD6f3bdadaadc4692050ca20dff53d3890088b9272 (== origin/master)
Diff SHA-256207a37b869a4e9c442f1de4d0a88717a3f9b4ffa55b3b704da1cd1b651e2aea7
Changed filedoc/src/sgml/runtime.sgml (added lines 1441–1490)
Changed symbolsNONE — documentation-only (SGML prose)
Scope typeUncommitted 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:

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

Findings Summary

IDSeverityClassLocationVerificationDescription
F1MINORdocsdoc/src/sgml/runtime.sgml:1462-1463verifiedcgroup v1 dismissal too terse; does not name memory.limit_in_bytes
F2MINORdocsdoc/src/sgml/runtime.sgml:1466-1468verifiedOOM victim selection nuance omitted; postmaster could be victim; memory.oom.group not mentioned
F3MINORdocsdoc/src/sgml/runtime.sgml:1476-1487verifiedSizing guidance omits temp buffers and other per-process memory
F4NITdocsdoc/src/sgml/runtime.sgml:1485-1487verifiedHuge pages caveat could mention memory_hugetlb_accounting mount option
F5NITdocsdoc/src/sgml/runtime.sgml:1444-1450verifiedIndexterm 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.

FindingStatusMethodRepair PatchRepair Validation
F1verifiedsource inspection + kernel-doc cross-referenceprovided (shared with F2/F4)partial (xmllint structural)
F2verifiedsource inspection + kernel-doc cross-referenceprovided (shared with F1/F4)partial (xmllint structural)
F3verifiedsource inspection + GUC anchor cross-referenceprovidedpartial (xmllint structural + anchor check)
F4verifiedsource inspection + kernel-doc cross-referenceprovided (shared with F1/F2)partial (xmllint structural)
F5verifiedsource inspection + codebase convention cross-referenceprovidedpartial (xmllint structural + convention match)

Verification methodology

  1. Read the actual added lines (1441–1490) of doc/src/sgml/runtime.sgml in the read-only worktree.
  2. Fetched the authoritative Linux kernel cgroup-v2 documentation and confirmed all factual claims:
  1. Inspected SGML conventions in the same file/codebase (<see>, <secondary>, <systemitem>, <option> are all established elements).
  2. Built disposable scratch worktree copies, applied candidate edits, ran git apply --check and xmllint --noout --nonet on each patched file — no new parse errors introduced.
  3. Full make docs/FOP build was not run (no doc build infrastructure in scratch environment); xmllint structural 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).

PatchCoversSHA-256Validation
cf7381-f1-f2-f4-v2.patchF1, F2, F41da14ce56ee4eed2b8bb47d38dc541c0b54c5261da10a8832e1f3d29d1fc212dpartial: apply-check + xmllint
cf7381-f3.patchF3183ee7e7f1254b4a84962e8c10b3ce883843bc414961357463e41471cccb1e2dpartial: apply-check + xmllint + anchor check
cf7381-f5.patchF567a3c85cff78ce0800d6b03a73eb1cab831458bd14616041cfd41390d3312db1partial: 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.

FieldValue
coverage_requirement.statusnot-applicable
coverage_requirement.changed_instrumentable_paths[] (empty)
coverage.statusnot-applicable
coverage.reasonDocumentation-only patch; no executable code introduced or modified
Non-instrumented changesdoc/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:

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

F1

— 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:
sgml
<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)
F2

— 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.group would kill all PostgreSQL processes simultaneously.
  • Verification: verified — kernel memory.oom.group doc: "If set, all tasks belonging to the cgroup or to its descendants are killed together or not at all."
  • Repair: Add memory.oom.group parenthetical and postmaster-victim sentence:
sgml
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
F3

— 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, and max_connections but omits temp_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-buffers anchor exists in config.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_buffers example:
sgml
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
F4

— 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_accounting mount option that changes this, or that it results in SIGBUS rather than OOM kill.
  • Failure: An operator whose system has memory_hugetlb_accounting enabled 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:
sgml
(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
F5

— 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.sgml has <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:
sgml
<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)

Aggregated Test Plan

TestVehicleTargetOracle
Full doc builddoc-builddoc/src/sgml/runtime.sgmlmake html succeeds without broken-xref or validation warnings
F1 verificationdoc-builddoc/src/sgml/runtime.sgmlgrep -q 'memory.limit_in_bytes' postgresql.html exits 0
F2 verificationdoc-builddoc/src/sgml/runtime.sgmlgrep -q 'memory.oom.group' postgresql.html && grep -q 'postmaster itself' postgresql.html exits 0
F3 verificationdoc-builddoc/src/sgml/runtime.sgmlgrep -q 'not exhaustive' postgresql.html exits 0
F4 verificationdoc-builddoc/src/sgml/runtime.sgmlgrep -q 'memory_hugetlb_accounting' postgresql.html && grep -q 'SIGBUS' postgresql.html exits 0
F5 verificationdoc-builddoc/src/sgml/runtime.sgmlgrep -qi 'cgroup.*see.*control group' postgresql.html exits 0
Structural checkinspectiondoc/src/sgml/runtime.sgmlxmllint --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

SeatModelRoleHandoff SlugStatus
pg-patch-reviewerglm-5.2:cloudGeneric review, PG filter, readiness, test mappingcommitfest-7381-review-handoff-patch-reviewercompleted
pg-security-reviewerglm-5.2:cloudPG security + delegated C memory safetycommitfest-7381-review-handoff-security-reviewercompleted
pg-finding-verifierglm-5.2:cloudFinding + repair verificationcommitfest-7381-review-handoff-verifiercompleted
pg-review-harness (coordinator)glm-5.2:cloudOrchestration, coverage, verdict, artifact—completed

Validator

Hard Constraints Compliance