Unloading hwpmc while processes own PMCs frees state they still use.
Return EBUSY instead. Use a try-lock on pmc_sx, since MOD_UNLOAD runs
with kld_sx held. MOD_SHUTDOWN still always cleans up.
Details
- Reviewers
mhorne gnn ali_mashtizadeh.com - Group Reviewers
pmc - Commits
- rGc37b83055406: hwpmc: refuse MOD_UNLOAD while PMC owners exist
Built amd64 GENERIC + hwpmc.ko, GENERIC without HWPMC_HOOKS, and arm64.
Ran tests/sys/pmc on AMD Zen 6 (LBR v2).
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped - Build Status
Buildable 78204 Build 75087: arc lint + arc unit
Event Timeline
What is the consequence here, can the unload race cause a panic or memory leak? Or is it purely functional (lost samples)?
I ask because, there is an additional module state, MOD_QUIESCE. It immediately precedes MOD_UNLOAD in the linker_file_unload() path, and functions similarly, but its errors can be overridden by force (kldunload -f / LINKER_UNLOAD_FORCE).
MOD_QUIESCE might be the appropriate state for this cleanup.
See module(9), kldunload(2), kldunload(8) man pages for more information.
| sys/dev/hwpmc/hwpmc_mod.c | ||
|---|---|---|
| 6119 | Here and EBUSY above is a great opportunity to use EXTERROR. This way the kldunload(8) will provide additional information. | |
Thanks, the problem is more than lost samples. It is that a queued sample keeps a reference to its PMC until we process it.
Cleanup disables the hooks that process those samples, then waits for the references to reach zero. If samples remain in the queue, that wait can last forever. With INVARIANTS, it can panic with “waiting too long for pmc to be free” instead.
Yeah, the owner check is conservative, but I think it avoids this unsafe cleanup. Couldn't we have an issue moving the check to MOD_QUIESCE and then let -f proceed with samples still queued ? Couldn't cleanup disable sample processing before those samples release their PMC reference?
| sys/dev/hwpmc/hwpmc_mod.c | ||
|---|---|---|
| 6119 | Nice, I will do that | |
Based on your description of the problem, the current use of MOD_UNLOAD is correct, and you can forget my suggestion about MOD_QUIESCE. As done here, refusing to unload with samples in-flight is the safest course of action. The extended errors will inform the user precisely why unload fails.
Use EXTERROR for lock contention and existing PMC owners. amd64 GENERIC and hwpmc.ko build passed.