On Thu, Nov 14, 2024 at 11:31:25AM +0100, Peter Newman wrote: > At least for the purposes of reporting the mbps rate to userspace, my > users will record from the files one per second, so it would be fine > to just report Unavailable (or Unassigned when it's clear that the > error is because counter wasn't unassigned) whenever either the > current or previous reading was not successful. Then they can assume > the value or error reported always refers to the most > recently-completed one-second window. First hack at keeping status for memory bandwidth values. Simple state machine. Compile tested. diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index 6345ab3e0890..80de5c6b0754 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -359,14 +359,22 @@ struct rftype { char *buf, size_t nbytes, loff_t off); }; +enum mbm_state_status { + MBM_INVALID, + MBM_ONE_VALUE, + MBM_VALID +}; + /** * struct mbm_state - status for each MBM counter in each domain * @prev_bw_bytes: Previous bytes value read for bandwidth calculation * @prev_bw: The most recent bandwidth in MBps + * @status: Validity of @prev_bw */ struct mbm_state { - u64 prev_bw_bytes; - u32 prev_bw; + u64 prev_bw_bytes; + u32 prev_bw; + enum mbm_state_status status; }; /** diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index da4ae21350c8..767a526af2f5 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -670,6 +670,17 @@ static void mbm_bw_count(u32 closid, u32 rmid, struct rmid_read *rr) if (WARN_ON_ONCE(!m)) return; + if (rr->err || !rr->val) { + m->status = MBM_INVALID; + return; + } + + if (m->status == MBM_INVALID) { + m->status = MBM_ONE_VALUE; + m->prev_bw_bytes = rr->val; + return; + } + cur_bytes = rr->val; bytes = cur_bytes - m->prev_bw_bytes; m->prev_bw_bytes = cur_bytes; @@ -677,6 +688,7 @@ static void mbm_bw_count(u32 closid, u32 rmid, struct rmid_read *rr) cur_bw = bytes / SZ_1M; m->prev_bw = cur_bw; + m->status = MBM_VALID; } /* @@ -781,6 +793,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm) if (WARN_ON_ONCE(!pmbm_data)) return; + if (pmbm_data->status != MBM_VALID) + return; + dom_mba = get_ctrl_domain_from_cpu(smp_processor_id(), r_mba); if (!dom_mba) { pr_warn_once("Failure to get domain for MBA update\n"); @@ -801,6 +816,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm) cmbm_data = get_mbm_state(dom_mbm, entry->closid, entry->mon.rmid, evt_id); if (WARN_ON_ONCE(!cmbm_data)) return; + if (cmbm_data->status != MBM_VALID) + return; + cur_bw += cmbm_data->prev_bw; }