git: 92cf9e36ecf9 - stable/15 - hwpmc: fix false runcount assertion in user callchain capture
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Sep 2026 16:29:51 UTC
The branch stable/15 has been updated by mhorne:
URL: https://cgit.FreeBSD.org/src/commit/?id=92cf9e36ecf937618a5b977b53027a4d28efe0f2
commit 92cf9e36ecf937618a5b977b53027a4d28efe0f2
Author: Andre Silva <andasilv@amd.com>
AuthorDate: 2026-08-11 16:16:20 +0000
Commit: Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-09-03 16:27:28 +0000
hwpmc: fix false runcount assertion in user callchain capture
pmc_capture_user_callchain() checks a PMC's runcount before walking
the user stack, but reads it without holding the spinlock that
protects it. hardclock() can run on the same CPU during the capture
and drop the runcount to zero in between, tripping the assertion and
panicking INVARIANTS kernels under load.
Move the check inside the existing spinlock, right where the code
already confirms the sample is still valid. No functional change on
kernels built without INVARIANTS.
Signed-off-by: Andre Silva <andasilv@amd.com>
Reviewed by: mhorne
MFC after: 1 week
Sponsored by: AMD
Differential Revision: https://reviews.freebsd.org/D58571
(cherry picked from commit 66118c3f1011d7852bce8b659899179a83781897)
---
sys/dev/hwpmc/hwpmc_mod.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 98ef14885c10..21effa80a4bb 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -4809,9 +4809,6 @@ restart:
KASSERT(pm->pm_flags & PMC_F_CALLCHAIN,
("[pmc,%d] Retrieving callchain for PMC that doesn't "
"want it", __LINE__));
- KASSERT(counter_u64_fetch(pm->pm_runcount) > 0,
- ("[pmc,%d] runcount %ju", __LINE__,
- (uintmax_t)counter_u64_fetch(pm->pm_runcount)));
if (ring == PMC_UR) {
nsamples = ps->ps_nsamples_actual;
@@ -4838,6 +4835,10 @@ restart:
* Verify that the sample hasn't been dropped in the meantime.
*/
if (ps->ps_nsamples == PMC_USER_CALLCHAIN_PENDING) {
+ KASSERT(counter_u64_fetch(pm->pm_runcount) > 0,
+ ("[pmc,%d] runcount %ju", __LINE__,
+ (uintmax_t)counter_u64_fetch(pm->pm_runcount)));
+
ps->ps_nsamples = nsamples;
/*
* If we couldn't get a sample, simply drop the