x86/resctrl: Support wider MBM counters
authorReinette Chatre <reinette.chatre@intel.com>
Tue, 5 May 2020 22:36:18 +0000 (15:36 -0700)
committerBorislav Petkov <bp@suse.de>
Wed, 6 May 2020 16:08:32 +0000 (18:08 +0200)
The original Memory Bandwidth Monitoring (MBM) architectural
definition defines counters of up to 62 bits in the
IA32_QM_CTR MSR while the first-generation MBM implementation
uses statically defined 24 bit counters.

The MBM CPUID enumeration properties have been expanded to include
the MBM counter width, encoded as an offset from 24 bits.

While eight bits are available for the counter width offset IA32_QM_CTR
MSR only supports 62 bit counters. Add a sanity check, with warning
printed when encountered, to ensure counters cannot exceed the 62 bit
limit.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/69d52abd5b14794d3a0f05ba7c755ed1f4c0d5ed.1588715690.git.reinette.chatre@intel.com
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/monitor.c

index 58b002c..f20a47d 100644 (file)
@@ -31,7 +31,7 @@
 
 #define CQM_LIMBOCHECK_INTERVAL        1000
 
-#define MBM_CNTR_WIDTH                 24
+#define MBM_CNTR_WIDTH_BASE            24
 #define MBM_OVERFLOW_INTERVAL          1000
 #define MAX_MBA_BW                     100u
 #define MBA_IS_LINEAR                  0x4
 
 #define RMID_VAL_ERROR                 BIT_ULL(63)
 #define RMID_VAL_UNAVAIL               BIT_ULL(62)
+/*
+ * With the above fields in use 62 bits remain in MSR_IA32_QM_CTR for
+ * data to be returned. The counter width is discovered from the hardware
+ * as an offset from MBM_CNTR_WIDTH_BASE.
+ */
+#define MBM_CNTR_WIDTH_OFFSET_MAX (62 - MBM_CNTR_WIDTH_BASE)
 
 
 struct rdt_fs_context {
index df964c0..837d7d0 100644 (file)
@@ -618,12 +618,18 @@ static void l3_mon_evt_init(struct rdt_resource *r)
 
 int rdt_get_mon_l3_config(struct rdt_resource *r)
 {
+       unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
        unsigned int cl_size = boot_cpu_data.x86_cache_size;
        int ret;
 
        r->mon_scale = boot_cpu_data.x86_cache_occ_scale;
        r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
-       r->mbm_width = MBM_CNTR_WIDTH;
+       r->mbm_width = MBM_CNTR_WIDTH_BASE;
+
+       if (mbm_offset > 0 && mbm_offset <= MBM_CNTR_WIDTH_OFFSET_MAX)
+               r->mbm_width += mbm_offset;
+       else if (mbm_offset > MBM_CNTR_WIDTH_OFFSET_MAX)
+               pr_warn("Ignoring impossible MBM counter offset\n");
 
        /*
         * A reasonable upper limit on the max threshold is the number