Page MenuHomeFreeBSD

D60367.1794186414.diff
No OneTemporary

Authored By
Unknown
Size
1 KB
Referenced Files
None
Subscribers
None

D60367.1794186414.diff

diff --git a/sys/dev/hwpmc/hwpmc_ibs.c b/sys/dev/hwpmc/hwpmc_ibs.c
--- a/sys/dev/hwpmc/hwpmc_ibs.c
+++ b/sys/dev/hwpmc/hwpmc_ibs.c
@@ -97,6 +97,7 @@
struct ibs_cpu {
int pc_status;
+ int pc_nmi_credit; /* latched NMIs already serviced */
struct pmc_hw pc_ibspmcs[IBS_NPMCS];
};
static struct ibs_cpu **ibs_pcpu;
@@ -702,24 +703,46 @@
pac = ibs_pcpu[cpu];
+ /*
+ * Fetch and op share an NMI. Both valid bits may be set on entry,
+ * so service each valid source or the skipped unit can stay frozen
+ * with no NMI pending to re-arm it.
+ */
config = rdmsr(IBS_FETCH_CTL);
if ((config & IBS_FETCH_CTL_VALID) != 0) {
pm = pac->pc_ibspmcs[IBS_PMC_FETCH].phw_pmc;
- retval = 1;
+ retval++;
pmc_ibs_process_fetch(pm, tf, config);
}
config = rdmsr(IBS_OP_CTL);
- if ((retval == 0) && ((config & IBS_OP_CTL_VALID) != 0)) {
+ if ((config & IBS_OP_CTL_VALID) != 0) {
pm = pac->pc_ibspmcs[IBS_PMC_OP].phw_pmc;
- retval = 1;
+ retval++;
pmc_ibs_process_op(pm, tf, config);
}
+ /*
+ * When both units were serviced, the second unit's NMI is still
+ * owed and will arrive with no valid bit set. It is not always
+ * the next NMI: on Zen 6 one or more NMIs carrying a single new
+ * sample can arrive first. Keep the credit until an NMI with no
+ * valid bit consumes it, so the owed NMI is not reported as
+ * unknown.
+ */
+ if (retval == 2)
+ pac->pc_nmi_credit = 1;
+ else if (retval == 0 && pac->pc_nmi_credit != 0) {
+ pac->pc_nmi_credit = 0;
+ retval = 1;
+ }
+ if (retval > 1)
+ retval = 1;
+
if (retval == 0) {
// Lets check for a stray NMI when stopping
if (atomic_load_int(&pac->pc_status) == IBS_CPU_STOPPING) {

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 9, 1:06 AM (17 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40302143
Default Alt Text
D60367.1794186414.diff (1 KB)

Event Timeline