Skip to content

Add Linux PSI memory pressure monitor - #59

Closed
novadusk wants to merge 2 commits into
troglobit:masterfrom
novadusk:feat/issue-25-memory-pressure-psi-20260905
Closed

novadusk wants to merge 2 commits into
troglobit:masterfrom
novadusk:feat/issue-25-memory-pressure-psi-20260905

Conversation

@novadusk

@novadusk novadusk commented Oct 11, 2026 •

Copy link
Copy Markdown

Add an optional Linux PSI memory pressure monitor (--with-pressure) reading /proc/pressure/memory. Select some or full and avg10, avg60, or avg300, then compare against warning and critical thresholds expressed as fractions (0.10 = 10%). The monitor is disabled by default.

PSI parsing uses a small sscanf() loop in pressure.c. Unknown lines are skipped; an unavailable or invalid selected metric skips that poll. Invalid scope/window settings stop the previous monitor on reload and propagate an initialization error from conf_parse_file().

Includes configuration, documentation, build integration, and a ChangeLog entry. Logs display percent; script arguments use fractions, consistent with other monitors.

Validation for the updated revision:

  • 93 host checks pass with Clang -Wall -Wextra -Werror and UBSan, covering the production PSI callback, initialization, and extracted configuration functions with mocked timers/configuration dependencies. The original revision fails 14 of these checks.
  • git diff --check passes; the complete updated PR applies to current upstream master.
  • Full Linux autotools build, real SIGHUP integration, and target-board PSI/watchdog runtime have not been rerun for this update.

AI assistance was used to prepare this update and its host validation.

Closes #25

Closes: troglobit#25
Signed-off-by: berringtoni36-commits <berringtoni36-commits@users.noreply.github.com>

@troglobit troglobit left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review, I've been swamped with work this past week.

Thanks for picking up #25! It builds cleanly here and make check passes. A few things before I merge:

  1. The docs get the threshold units wrong. The code divides the PSI value by 100, so warning = 0.10 means 10%, not "0.10 percent" as doc/features.md says. This also means the example critical = 1.00 (100%) can never trigger. Please fix the examples in watchdogd.conf, watchdogd.conf.5 and features.md, e.g. critical = 0.50.

  2. conf_parse_file() ignores the return value from pressure_checker(). With an invalid scope or window on SIGHUP, pressure_init() returns before touching the timer, so the monitor keeps running with the old settings and only logs an error. It should stop the monitor and pass the error on.

  3. The parser is a lot of code for a two-line file. Something like the sscanf() approach in meminfo.c would be enough, and then the separate parser files and the unit test could go. The strict checks also make it fragile: an unexpected line from a future kernel fails the whole read.

Nits:

  • Please add a ChangeLog.md entry.
  • src/pressure-test.c is missing a license header, and it hardcodes /tmp instead of using $TMPDIR. (Moot if the test goes away.)
  • The man page example has enabled = true, but watchdogd.conf has it commented out.
  • WARN/EMERG log the fraction (0.12 > 0.10) while INFO/DEBUG log percent. Percent everywhere would match /proc/pressure/memory.

Thanks again!

Correct fraction thresholds and percentage logging, and keep the sample
configuration disabled consistently. Stop the previous timer before
validating reload settings and propagate pressure initialization errors
through conf_parse_file().

Use a small sscanf loop in pressure.c, ignoring unknown PSI lines, instead
of maintaining separate parser and unit-test files. Add a ChangeLog entry.

Host callback and reload checks pass with UBSan. Full Linux integration
and target hardware have not been retested for this revision.
@novadusk

Copy link
Copy Markdown
Author

Thanks for the review!

I've corrected the threshold examples (0.10 = 10%, 0.50 = 50%), kept the sample monitor disabled in both configuration examples, and made all pressure log levels use percent. Script arguments still use fractions, matching the other monitors.

The monitor now stops its previous timer before validating a replacement configuration, and conf_parse_file() returns pressure initialization errors after freeing the configuration.

I've replaced the standalone parser with an sscanf() loop in pressure.c, removed the parser files and their unit test, and added a ChangeLog entry. Unknown PSI lines are skipped, and an unavailable or invalid selected metric skips that poll.

Validation: 93 host checks covering scopes/windows, thresholds, missing/malformed metrics, an extra future PSI line, and reload failures pass with UBSan. The original revision fails 14 of these checks. I have not rerun the full Linux autotools build locally for this update.

@troglobit

Copy link
Copy Markdown
Owner

Merged to master as a single commit, thank you for your work on this and for addressing the review so quickly!

Before merging I squashed the two commits and made a few small changes:

  • scope and window are now checked while the config file is parsed, so a typo is reported as a parse error and a reload doesn't stop halfway.
  • The plugin now uses the common checker() in conf.c and the standard pressure_init() signature, the same as the other monitors.

Tested on target with stress-ng, and the warning and critical script actions trigger as expected. Thanks again!

@troglobit troglobit closed this Oct 20, 2026
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.

Monitor memory pressure

2 participants