x86: Add support for Intel Cache QoS Monitoring (CQM) detection
authorPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Fri, 23 Jan 2015 18:45:43 +0000 (18:45 +0000)
committerIngo Molnar <mingo@kernel.org>
Wed, 25 Feb 2015 12:53:31 +0000 (13:53 +0100)
This patch adds support for the new Cache QoS Monitoring (CQM)
feature found in future Intel Xeon processors.  It includes the
new values to track CQM resources to the cpuinfo_x86 structure,
plus the CPUID detection routines for CQM.

CQM allows a process, or set of processes, to be tracked by the CPU
to determine the cache usage of that task group.  Using this data
from the CPU, software can be written to extract this data and
report cache usage and occupancy for a particular process, or
group of processes.

More information about Cache QoS Monitoring can be found in the
Intel (R) x86 Architecture Software Developer Manual, section 17.14.

Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Chris Webb <chris@arachsys.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jacob Shin <jacob.w.shin@gmail.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kanaka Juvva <kanaka.d.juvva@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Steven Honeyman <stevenhoneyman@gmail.com>
Cc: Steven Rostedt <srostedt@redhat.com>
Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Link: http://lkml.kernel.org/r/1422038748-21397-5-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c

index 90a54851aedc98b29c65856986ade222818381b8..361922dcc9b1fc32308fef578c2d3268b678df71 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/disabled-features.h>
 #endif
 
-#define NCAPINTS       11      /* N 32-bit words worth of info */
+#define NCAPINTS       13      /* N 32-bit words worth of info */
 #define NBUGINTS       1       /* N 32-bit bug flags */
 
 /*
 #define X86_FEATURE_ERMS       ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
 #define X86_FEATURE_INVPCID    ( 9*32+10) /* Invalidate Processor Context ID */
 #define X86_FEATURE_RTM                ( 9*32+11) /* Restricted Transactional Memory */
+#define X86_FEATURE_CQM                ( 9*32+12) /* Cache QoS Monitoring */
 #define X86_FEATURE_MPX                ( 9*32+14) /* Memory Protection Extension */
 #define X86_FEATURE_AVX512F    ( 9*32+16) /* AVX-512 Foundation */
 #define X86_FEATURE_RDSEED     ( 9*32+18) /* The RDSEED instruction */
 #define X86_FEATURE_XGETBV1    (10*32+ 2) /* XGETBV with ECX = 1 */
 #define X86_FEATURE_XSAVES     (10*32+ 3) /* XSAVES/XRSTORS */
 
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
+#define X86_FEATURE_CQM_LLC    (11*32+ 1) /* LLC QoS if 1 */
+
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
+#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
+
 /*
  * BUG word(s)
  */
index ec1c93588cefd0c4e3a4705c6d966e2555ba95aa..a12d50e04d7a16316493c845c37408940c953a57 100644 (file)
@@ -109,6 +109,9 @@ struct cpuinfo_x86 {
        /* in KB - valid for CPUS which support this call: */
        int                     x86_cache_size;
        int                     x86_cache_alignment;    /* In bytes */
+       /* Cache QoS architectural values: */
+       int                     x86_cache_max_rmid;     /* max index */
+       int                     x86_cache_occ_scale;    /* scale to bytes */
        int                     x86_power;
        unsigned long           loops_per_jiffy;
        /* cpuid returned max cores value: */
index 07f2fc3c13a4d614b76fdad3b99ee6ec8e9c3683..9fa00b2ea0eed1acd5e758c6eb7aa6b417a1f2d5 100644 (file)
@@ -645,6 +645,30 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
                c->x86_capability[10] = eax;
        }
 
+       /* Additional Intel-defined flags: level 0x0000000F */
+       if (c->cpuid_level >= 0x0000000F) {
+               u32 eax, ebx, ecx, edx;
+
+               /* QoS sub-leaf, EAX=0Fh, ECX=0 */
+               cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx);
+               c->x86_capability[11] = edx;
+               if (cpu_has(c, X86_FEATURE_CQM_LLC)) {
+                       /* will be overridden if occupancy monitoring exists */
+                       c->x86_cache_max_rmid = ebx;
+
+                       /* QoS sub-leaf, EAX=0Fh, ECX=1 */
+                       cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
+                       c->x86_capability[12] = edx;
+                       if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) {
+                               c->x86_cache_max_rmid = ecx;
+                               c->x86_cache_occ_scale = ebx;
+                       }
+               } else {
+                       c->x86_cache_max_rmid = -1;
+                       c->x86_cache_occ_scale = -1;
+               }
+       }
+
        /* AMD-defined flags: level 0x80000001 */
        xlvl = cpuid_eax(0x80000000);
        c->extended_cpuid_level = xlvl;
@@ -833,6 +857,20 @@ static void generic_identify(struct cpuinfo_x86 *c)
        detect_nopl(c);
 }
 
+static void x86_init_cache_qos(struct cpuinfo_x86 *c)
+{
+       /*
+        * The heavy lifting of max_rmid and cache_occ_scale are handled
+        * in get_cpu_cap().  Here we just set the max_rmid for the boot_cpu
+        * in case CQM bits really aren't there in this CPU.
+        */
+       if (c != &boot_cpu_data) {
+               boot_cpu_data.x86_cache_max_rmid =
+                       min(boot_cpu_data.x86_cache_max_rmid,
+                           c->x86_cache_max_rmid);
+       }
+}
+
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
@@ -922,6 +960,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 
        init_hypervisor(c);
        x86_init_rdrand(c);
+       x86_init_cache_qos(c);
 
        /*
         * Clear/Set all flags overriden by options, need do it