Skip to content

Deflake PageFlagsTest.Locked: collapse hugepages before measuring and assert on the confirming read. - #952

Draft
copybara-service[bot] wants to merge 1 commit into
masterfrom
test_982755344
Draft

copybara-service[bot] wants to merge 1 commit into
masterfrom
test_982755344

Conversation

@copybara-service

Copy link
Copy Markdown

Deflake PageFlagsTest.Locked: collapse hugepages before measuring and assert on the confirming read.

PageFlagsTest.Locked mmaps six hugepages, applies MADV_HUGEPAGE to two of the
regions, mlock()s the range, and expects PageFlags to report the whole range as
locked. It flaked (~0.15% in -c opt, ~0.05% in -c dbg at 2000 runs/mode).

Root cause is a test-measurement race, not a PageFlags bug. khugepaged forms the
MADV_HUGEPAGE regions asynchronously. While a collapse is in flight the kernel's
per-page flags are transiently inconsistent: a compound head can briefly lack
KPF_COMPOUND_HEAD while its tails already carry KPF_COMPOUND_TAIL (yielding the
"Did not see head page before tail page" path), and KPF_MLOCKED/KPF_UNEVICTABLE
can momentarily be missing on a page under migration. The reported locked byte
count therefore oscillates a few pages around the true value. The wait loop
could break on a transient full reading, but the assertion then did a separate
Get() (a TOCTOU) that could sample a short, mid-collapse state; in -c dbg the
churn could keep the count short for the whole 60s window.

Fix the measurement without weakening the check:

  • MADV_COLLAPSE the MADV_HUGEPAGE regions synchronously before mlock() so the
    hugepages are already formed and no async collapse runs during measurement.
    It must precede mlock() (collapse can fail on pinned pages) and is best-effort
    (Linux 6.1+); failures on older kernels are ignored.
  • Assert on the same reading the wait loop used to observe the full count,
    eliminating the TOCTOU re-read.

The test still verifies that PageFlags correctly counts locked bytes across THP
head/tail propagation and mixed NOHUGEPAGE/HUGEPAGE regions.

… assert on the confirming read.

PageFlagsTest.Locked mmaps six hugepages, applies MADV_HUGEPAGE to two of the
regions, mlock()s the range, and expects PageFlags to report the whole range as
locked. It flaked (~0.15% in -c opt, ~0.05% in -c dbg at 2000 runs/mode).

Root cause is a test-measurement race, not a PageFlags bug. khugepaged forms the
MADV_HUGEPAGE regions asynchronously. While a collapse is in flight the kernel's
per-page flags are transiently inconsistent: a compound head can briefly lack
KPF_COMPOUND_HEAD while its tails already carry KPF_COMPOUND_TAIL (yielding the
"Did not see head page before tail page" path), and KPF_MLOCKED/KPF_UNEVICTABLE
can momentarily be missing on a page under migration. The reported locked byte
count therefore oscillates a few pages around the true value. The wait loop
could break on a transient full reading, but the assertion then did a *separate*
Get() (a TOCTOU) that could sample a short, mid-collapse state; in -c dbg the
churn could keep the count short for the whole 60s window.

Fix the measurement without weakening the check:
- MADV_COLLAPSE the MADV_HUGEPAGE regions synchronously before mlock() so the
  hugepages are already formed and no async collapse runs during measurement.
  It must precede mlock() (collapse can fail on pinned pages) and is best-effort
  (Linux 6.1+); failures on older kernels are ignored.
- Assert on the same reading the wait loop used to observe the full count,
  eliminating the TOCTOU re-read.

The test still verifies that PageFlags correctly counts locked bytes across THP
head/tail propagation and mixed NOHUGEPAGE/HUGEPAGE regions.

PiperOrigin-RevId: 982755344
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant