From: Dave Jiang <dave.jiang@intel.com>
To: linux-cxl@vger.kernel.org, linux-perf-users@vger.kernel.org
Cc: jic23@kernel.org, will@kernel.org, mark.rutland@arm.com,
dave@stgolabs.net, robin.murphy@arm.com, sashiko-bot@kernel.org
Subject: [PATCH v3 7/9] perf/cxl: Unfreeze counters after handling an overflow interrupt
Date: Fri, 31 Jul 2026 16:28:25 -0700 [thread overview]
Message-ID: <20260731232827.401447-8-dave.jiang@intel.com> (raw)
In-Reply-To: <20260731232827.401447-1-dave.jiang@intel.com>
The counters run with Freeze on Overflow set, so one overflow freezes every
counter in the block (CXL r4.0 8.2.7.2.1). cxl_pmu_irq() reads the
overflowed counters and clears the overflow status, but never unfreezes.
Everything stays frozen until the next pmu_enable(), and events in that
window are lost.
Unfreeze after clearing the status, unless the PMU has been disabled in the
meantime. cxl_pmu_disable() freezes the block deliberately, and
cxl_pmu_offline_cpu() migrates the context before it moves the interrupt's
affinity, so an overflow can still land on the old CPU while the new one
reprograms. Track the enabled state and leave the block frozen in that
case. pmu_enable() unfreezes anyway.
Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260715191454.459673-1-dave@stgolabs.net?part=1
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v3:
- Don't unfreeze if the PMU has been disabled (Robin, Jonathan). Review tag
dropped as the patch grew a hunk.
- Robin also asked whether this can release a counter that overflowed after
the status read. It cannot. Global Freeze on Overflow stops every
non-free-running counter and they stay frozen until software unfreezes
them, so nothing the driver owns can advance, let alone newly overflow,
between the readq and here. Two counters overflowing together both show
up in the same pass. Only free-running counters move while frozen, and
the driver never programs those.
- The enabled check is not a full exclusion, since the flag is read outside
any lock. Say so in the comment rather than implying otherwise. A lock
would buy nothing: pmu_disable() normally runs on the pinned CPU with
interrupts off, and in the one window where it does not - the migration
in cxl_pmu_offline_cpu() - event_stop() has already cleared Counter
Enable, so a stray unfreeze resumes nothing (sashiko-bot).
---
drivers/perf/cxl_pmu.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 6fdc66a01fb6..580a75bc9210 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -108,6 +108,8 @@ struct cxl_pmu_info {
bool filter_hdm;
int msi_vec;
int irq;
+ /* Set between pmu_enable() and pmu_disable(), read by the IRQ handler */
+ bool enabled;
};
#define pmu_to_cxl_pmu_info(_pmu) container_of(_pmu, struct cxl_pmu_info, pmu)
@@ -596,6 +598,7 @@ static void cxl_pmu_enable(struct pmu *pmu)
void __iomem *base = info->base;
/* Can assume frozen at this stage */
+ WRITE_ONCE(info->enabled, true);
writeq(0, base + CXL_PMU_FREEZE_REG);
}
@@ -604,6 +607,7 @@ static void cxl_pmu_disable(struct pmu *pmu)
struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(pmu);
void __iomem *base = info->base;
+ WRITE_ONCE(info->enabled, false);
/*
* Whilst bits above number of counters are RsvdZ
* they are unlikely to be repurposed given
@@ -803,6 +807,9 @@ static irqreturn_t cxl_pmu_irq(int irq, void *data)
writeq(overflowed, base + CXL_PMU_OVERFLOW_REG);
+ if (READ_ONCE(info->enabled))
+ writeq(0, base + CXL_PMU_FREEZE_REG);
+
return IRQ_HANDLED;
}
--
2.55.0
next prev parent reply other threads:[~2026-07-31 23:28 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 23:28 [PATCH v3 0/9] perf/cxlpmu: Misc sashiko raised issues fixes Dave Jiang
2026-07-31 23:28 ` [PATCH v3 1/9] perf/cxl: Program the requested event group on configurable counters Dave Jiang
2026-07-31 23:38 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 2/9] perf/cxl: Clear stale event fields before reprogramming a counter Dave Jiang
2026-07-31 23:40 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 3/9] perf/cxl: Fix the counter overflow delta fixup Dave Jiang
2026-07-31 23:37 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 4/9] perf/cxl: Split the MSI vector out of info->irq Dave Jiang
2026-07-31 23:45 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 5/9] perf/cxl: Accept an overflow interrupt on MSI message number 0 Dave Jiang
2026-07-31 23:28 ` [PATCH v3 6/9] perf/cxl: Don't share the overflow interrupt, and keep it pinned Dave Jiang
2026-07-31 23:50 ` sashiko-bot
2026-07-31 23:28 ` Dave Jiang [this message]
2026-07-31 23:40 ` [PATCH v3 7/9] perf/cxl: Unfreeze counters after handling an overflow interrupt sashiko-bot
2026-07-31 23:28 ` [PATCH v3 8/9] perf/cxl: Validate the hardware-reported counter width Dave Jiang
2026-07-31 23:28 ` [PATCH v3 9/9] perf/cxl: Don't log through pmu.dev in the overflow interrupt handler Dave Jiang
2026-07-31 23:46 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731232827.401447-8-dave.jiang@intel.com \
--to=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=robin.murphy@arm.com \
--cc=sashiko-bot@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox