Page MenuHomeFreeBSD

D60004.id187640.diff
No OneTemporary

D60004.id187640.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,42 @@
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 may still be
+ * latched and will arrive with no valid bit set. Claim that one
+ * NMI so it is not reported as unknown.
+ */
+ if (retval != 0) {
+ pac->pc_nmi_credit = (retval > 1);
+ retval = 1;
+ } else if (pac->pc_nmi_credit != 0) {
+ pac->pc_nmi_credit = 0;
+ 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
Wed, Sep 30, 4:35 AM (12 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39623440
Default Alt Text
D60004.id187640.diff (1 KB)

Event Timeline