x86: Fix various typos in comments
[linux-2.6-microblaze.git] / arch / x86 / kernel / cpu / resctrl / monitor.c
index 54dffe5..98c0e21 100644 (file)
@@ -64,6 +64,69 @@ unsigned int rdt_mon_features;
  */
 unsigned int resctrl_cqm_threshold;
 
+#define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5))
+
+/*
+ * The correction factor table is documented in Documentation/x86/resctrl.rst.
+ * If rmid > rmid threshold, MBM total and local values should be multiplied
+ * by the correction factor.
+ *
+ * The original table is modified for better code:
+ *
+ * 1. The threshold 0 is changed to rmid count - 1 so don't do correction
+ *    for the case.
+ * 2. MBM total and local correction table indexed by core counter which is
+ *    equal to (x86_cache_max_rmid + 1) / 8 - 1 and is from 0 up to 27.
+ * 3. The correction factor is normalized to 2^20 (1048576) so it's faster
+ *    to calculate corrected value by shifting:
+ *    corrected_value = (original_value * correction_factor) >> 20
+ */
+static const struct mbm_correction_factor_table {
+       u32 rmidthreshold;
+       u64 cf;
+} mbm_cf_table[] __initdata = {
+       {7,     CF(1.000000)},
+       {15,    CF(1.000000)},
+       {15,    CF(0.969650)},
+       {31,    CF(1.000000)},
+       {31,    CF(1.066667)},
+       {31,    CF(0.969650)},
+       {47,    CF(1.142857)},
+       {63,    CF(1.000000)},
+       {63,    CF(1.185115)},
+       {63,    CF(1.066553)},
+       {79,    CF(1.454545)},
+       {95,    CF(1.000000)},
+       {95,    CF(1.230769)},
+       {95,    CF(1.142857)},
+       {95,    CF(1.066667)},
+       {127,   CF(1.000000)},
+       {127,   CF(1.254863)},
+       {127,   CF(1.185255)},
+       {151,   CF(1.000000)},
+       {127,   CF(1.066667)},
+       {167,   CF(1.000000)},
+       {159,   CF(1.454334)},
+       {183,   CF(1.000000)},
+       {127,   CF(0.969744)},
+       {191,   CF(1.280246)},
+       {191,   CF(1.230921)},
+       {215,   CF(1.000000)},
+       {191,   CF(1.143118)},
+};
+
+static u32 mbm_cf_rmidthreshold __read_mostly = UINT_MAX;
+static u64 mbm_cf __read_mostly;
+
+static inline u64 get_corrected_mbm_count(u32 rmid, unsigned long val)
+{
+       /* Correct MBM value. */
+       if (rmid > mbm_cf_rmidthreshold)
+               val = (val * mbm_cf) >> 20;
+
+       return val;
+}
+
 static inline struct rmid_entry *__rmid_entry(u32 rmid)
 {
        struct rmid_entry *entry;
@@ -260,7 +323,8 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
        m->chunks += chunks;
        m->prev_msr = tval;
 
-       rr->val += m->chunks;
+       rr->val += get_corrected_mbm_count(rmid, m->chunks);
+
        return 0;
 }
 
@@ -279,8 +343,7 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
                return;
 
        chunks = mbm_overflow_count(m->prev_bw_msr, tval, rr->r->mbm_width);
-       m->chunks += chunks;
-       cur_bw = (chunks * r->mon_scale) >> 20;
+       cur_bw = (get_corrected_mbm_count(rmid, chunks) * r->mon_scale) >> 20;
 
        if (m->delta_comp)
                m->delta_bw = abs(cur_bw - m->prev_bw);
@@ -324,7 +387,7 @@ void mon_event_count(void *info)
  * adjust the bandwidth percentage values via the IA32_MBA_THRTL_MSRs so
  * that:
  *
- *   current bandwdith(cur_bw) < user specified bandwidth(user_bw)
+ *   current bandwidth(cur_bw) < user specified bandwidth(user_bw)
  *
  * This uses the MBM counters to measure the bandwidth and MBA throttle
  * MSRs to control the bandwidth for a particular rdtgrp. It builds on the
@@ -450,15 +513,14 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
        }
        if (is_mbm_local_enabled()) {
                rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID;
+               __mon_event_count(rmid, &rr);
 
                /*
                 * Call the MBA software controller only for the
                 * control groups and when user has enabled
                 * the software controller explicitly.
                 */
-               if (!is_mba_sc(NULL))
-                       __mon_event_count(rmid, &rr);
-               else
+               if (is_mba_sc(NULL))
                        mbm_bw_count(rmid, &rr);
        }
 }
@@ -644,3 +706,17 @@ int rdt_get_mon_l3_config(struct rdt_resource *r)
 
        return 0;
 }
+
+void __init intel_rdt_mbm_apply_quirk(void)
+{
+       int cf_index;
+
+       cf_index = (boot_cpu_data.x86_cache_max_rmid + 1) / 8 - 1;
+       if (cf_index >= ARRAY_SIZE(mbm_cf_table)) {
+               pr_info("No MBM correction factor available\n");
+               return;
+       }
+
+       mbm_cf_rmidthreshold = mbm_cf_table[cf_index].rmidthreshold;
+       mbm_cf = mbm_cf_table[cf_index].cf;
+}