x86/intel_rdt/mba_sc: Prepare for feedback loop
authorVikas Shivappa <vikas.shivappa@linux.intel.com>
Fri, 20 Apr 2018 22:36:20 +0000 (15:36 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Sat, 19 May 2018 11:16:44 +0000 (13:16 +0200)
This is a preparatory patch for the mba feedback loop. Add support to
measure the "bandwidth in MBps" and the "delta bandwidth". Measure it by
reading the MBM IA32_QM_CTR MSRs and calculating the amount of "bytes"
moved. There is no user space interface for this and will only be used by
the feedback loop patch.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: vikas.shivappa@intel.com
Cc: ak@linux.intel.com
Cc: hpa@zytor.com
Link: https://lkml.kernel.org/r/1524263781-14267-6-git-send-email-vikas.shivappa@linux.intel.com
arch/x86/kernel/cpu/intel_rdt.h
arch/x86/kernel/cpu/intel_rdt_monitor.c

index 91cc31087e8abf05508339d88722a871dcb5f752..66a0ba37a8a3a5460be711450635267448c5a399 100644 (file)
@@ -180,10 +180,20 @@ struct rftype {
  * struct mbm_state - status for each MBM counter in each domain
  * @chunks:    Total data moved (multiply by rdt_group.mon_scale to get bytes)
  * @prev_msr   Value of IA32_QM_CTR for this RMID last time we read it
+ * @chunks_bw  Total local data moved. Used for bandwidth calculation
+ * @prev_bw_msr:Value of previous IA32_QM_CTR for bandwidth counting
+ * @prev_bw    The most recent bandwidth in MBps
+ * @delta_bw   Difference between the current and previous bandwidth
+ * @delta_comp Indicates whether to compute the delta_bw
  */
 struct mbm_state {
        u64     chunks;
        u64     prev_msr;
+       u64     chunks_bw;
+       u64     prev_bw_msr;
+       u32     prev_bw;
+       u32     delta_bw;
+       bool    delta_comp;
 };
 
 /**
index 681450eee428b8b07f9fb3a3b1fd5551a5c18cec..7690402c42b7d2f109723e955ba449c30e7eb04f 100644 (file)
@@ -225,10 +225,18 @@ void free_rmid(u32 rmid)
                list_add_tail(&entry->list, &rmid_free_lru);
 }
 
+static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr)
+{
+       u64 shift = 64 - MBM_CNTR_WIDTH, chunks;
+
+       chunks = (cur_msr << shift) - (prev_msr << shift);
+       return chunks >>= shift;
+}
+
 static int __mon_event_count(u32 rmid, struct rmid_read *rr)
 {
-       u64 chunks, shift, tval;
        struct mbm_state *m;
+       u64 chunks, tval;
 
        tval = __rmid_read(rmid, rr->evtid);
        if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) {
@@ -254,14 +262,12 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
        }
 
        if (rr->first) {
-               m->prev_msr = tval;
-               m->chunks = 0;
+               memset(m, 0, sizeof(struct mbm_state));
+               m->prev_bw_msr = m->prev_msr = tval;
                return 0;
        }
 
-       shift = 64 - MBM_CNTR_WIDTH;
-       chunks = (tval << shift) - (m->prev_msr << shift);
-       chunks >>= shift;
+       chunks = mbm_overflow_count(m->prev_msr, tval);
        m->chunks += chunks;
        m->prev_msr = tval;
 
@@ -269,6 +275,32 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
        return 0;
 }
 
+/*
+ * Supporting function to calculate the memory bandwidth
+ * and delta bandwidth in MBps.
+ */
+static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
+{
+       struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3];
+       struct mbm_state *m = &rr->d->mbm_local[rmid];
+       u64 tval, cur_bw, chunks;
+
+       tval = __rmid_read(rmid, rr->evtid);
+       if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+               return;
+
+       chunks = mbm_overflow_count(m->prev_bw_msr, tval);
+       m->chunks_bw += chunks;
+       m->chunks = m->chunks_bw;
+       cur_bw = (chunks * r->mon_scale) >> 20;
+
+       if (m->delta_comp)
+               m->delta_bw = abs(cur_bw - m->prev_bw);
+       m->delta_comp = false;
+       m->prev_bw = cur_bw;
+       m->prev_bw_msr = tval;
+}
+
 /*
  * This is called via IPI to read the CQM/MBM counters
  * on a domain.