All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/6] x86: Intel Cache Allocation Support
@ 2015-01-28  0:00 Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

This patch adds a new cgroup subsystem to support the new Cache Allocation 
Technology (CAT) feature found in future Intel Xeon processors.

Cache Allocation Technology(CAT) provides a way for the Software
(OS/VMM) to restrict cache allocation to a defined 'subset' of cache
which may be overlapping with other 'subsets'. This feature is used
when allocating a line in cache ie when pulling new data into the cache.

This patch series is dependent on the patches for Intel Cache QOS Monitoring 
from Matt since the series also implements a common software cache for the 
IA32_PQR_MSR :
https://lkml.kernel.org/r/1422038748-21397-1-git-send-email-matt@codeblueprint.co.uk

Changes in V3:
- Implements a common software cache for IA32_PQR_MSR
- Implements support for hsw CAT enumeration. This does not use the brand 
strings like earlier version but does a probe test. The probe test is done only 
on hsw family of processors
- Made a few coding convention, name changes and minor fixes

Changes in V2:
- Removed HSW specific enumeration changes. Plan to include it later as a
  seperate patch.  
- Fixed the code in prep_arch_switch to be specific for x86 and removed
  x86 defines.
- Fixed cbm_write to not write all 1s when a cgroup is freed.
- Fixed one possible memory leak in init.  
- Changed some of manual bitmap
  manipulation to use the predefined bitmap APIs to make code more readable
- Changed name in sources from cqe to cat
- Global cat enable flag changed to static_key and disabled cgroup early_init

Vikas Shivappa (6):
  x86/intel_cat: Intel Cache Allocation Technology detection
  x86/intel_cat: Adds support for Class of service management
  x86/intel_cat: Support cache bit mask for Intel CAT
  x86/intel_cat: Implement scheduling support for Intel CAT
  x86/intel_rdt: Software Cache for IA32_PQR_MSR
  x86/intel_cat: Intel haswell CAT enumeration

 arch/x86/include/asm/cpufeature.h          |   6 +-
 arch/x86/include/asm/intel_cat.h           |  99 ++++++++
 arch/x86/include/asm/processor.h           |   3 +
 arch/x86/include/asm/rdt.h                 |  13 +
 arch/x86/include/asm/switch_to.h           |   3 +
 arch/x86/kernel/cpu/Makefile               |   1 +
 arch/x86/kernel/cpu/common.c               |  16 ++
 arch/x86/kernel/cpu/intel_cat.c            | 367 +++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/perf_event_intel_cqm.c |  20 +-
 include/linux/cgroup_subsys.h              |   4 +
 init/Kconfig                               |  11 +
 kernel/sched/core.c                        |   1 +
 kernel/sched/sched.h                       |   3 +
 13 files changed, 533 insertions(+), 14 deletions(-)
 create mode 100644 arch/x86/include/asm/intel_cat.h
 create mode 100644 arch/x86/include/asm/rdt.h
 create mode 100644 arch/x86/kernel/cpu/intel_cat.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  2015-01-28 22:11   ` Paul Bolle
  2015-02-03 10:57   ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Matt Fleming
  2015-01-28  0:00 ` [PATCH 2/6] x86/intel_cat: Adds support for Class of service management Vikas Shivappa
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

This patch adds support for the new Cache Allocation Technology (CAT)
feature found in future Intel Xeon processors.  It includes CPUID
enumeration routines for CAT and new values to track CAT resources to
the cpuinfo_x86 structure.

Cache Allocation Technology(CAT) provides a way for the Software
(OS/VMM) to restrict cache allocation to a defined 'subset' of cache
which may be overlapping with other 'subsets'.  This feature is used
when allocating a line in cache ie when pulling new data into the cache.
The programming of the h/w is done via programming  MSRs.

More information about CAT be found in the Intel (R) x86 Architecture
Software Developer Manual, section 17.15.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/include/asm/cpufeature.h |  6 ++++-
 arch/x86/include/asm/processor.h  |  3 +++
 arch/x86/kernel/cpu/Makefile      |  1 +
 arch/x86/kernel/cpu/common.c      | 16 ++++++++++++
 arch/x86/kernel/cpu/intel_cat.c   | 51 +++++++++++++++++++++++++++++++++++++++
 init/Kconfig                      | 11 +++++++++
 6 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/kernel/cpu/intel_cat.c

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 54fd8eb..358b15b 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -12,7 +12,7 @@
 #include <asm/disabled-features.h>
 #endif
 
-#define NCAPINTS	13	/* N 32-bit words worth of info */
+#define NCAPINTS	14	/* N 32-bit words worth of info */
 #define NBUGINTS	1	/* N 32-bit bug flags */
 
 /*
@@ -227,6 +227,7 @@
 #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_CAT		( 9*32+15) /* Cache QOS Enforcement */
 #define X86_FEATURE_AVX512F	( 9*32+16) /* AVX-512 Foundation */
 #define X86_FEATURE_RDSEED	( 9*32+18) /* The RDSEED instruction */
 #define X86_FEATURE_ADX		( 9*32+19) /* The ADCX and ADOX instructions */
@@ -248,6 +249,9 @@
 /* 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 */
 
+/* Intel-defined CPU features, CPUID level 0x00000010:0 (ebx), word 13 */
+#define X86_FEATURE_CAT_L3	(13*32 + 1) /*Cache QOS Enforcement L3*/
+
 /*
  * BUG word(s)
  */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 242ceed..62863e9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -112,6 +112,9 @@ struct cpuinfo_x86 {
 	/* Cache QoS architectural values: */
 	int			x86_cache_max_rmid;	/* max index */
 	int			x86_cache_occ_scale;	/* scale to bytes */
+	/* Cache Allocation Technology values */
+	int			x86_cat_cbmlength;
+	int			x86_cat_closs;
 	int			x86_power;
 	unsigned long		loops_per_jiffy;
 	/* cpuid returned max cores value: */
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 6c1ca13..f008cd8 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE)	+= perf_event_intel_uncore.o \
 					   perf_event_intel_uncore_nhmex.o
 endif
 
+obj-$(CONFIG_CGROUP_CAT) 		+=intel_cat.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9b0fb70..18e8d75 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -668,6 +668,22 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
 		}
 	}
 
+	/* Additional Intel-defined flags: level 0x00000010 */
+	if (c->cpuid_level >= 0x00000010) {
+		u32 eax, ebx, ecx, edx;
+
+		cpuid_count(0x00000010, 0, &eax, &ebx, &ecx, &edx);
+		c->x86_capability[13] = ebx;
+
+		if (cpu_has(c, X86_FEATURE_CAT) &&
+			   cpu_has(c, X86_FEATURE_CAT_L3)) {
+
+			cpuid_count(0x00000010, 1, &eax, &ebx, &ecx, &edx);
+			c->x86_cat_closs = (edx & 0xffff) + 1;
+			c->x86_cat_cbmlength = (eax & 0xf) + 1;
+		}
+	}
+
 	/* AMD-defined flags: level 0x80000001 */
 	xlvl = cpuid_eax(0x80000000);
 	c->extended_cpuid_level = xlvl;
diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
new file mode 100644
index 0000000..2f4b19b
--- /dev/null
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -0,0 +1,51 @@
+/*
+ * Processor Cache Allocation Technology(CAT) code
+ *
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * 2014-09-10 Written by Vikas Shivappa
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * More information about CAT be found in the Intel (R) x86 Architecture
+ * Software Developer Manual, section 17.15.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+
+static inline bool cat_supported(struct cpuinfo_x86 *c)
+{
+	if (cpu_has(c, X86_FEATURE_CAT_L3))
+		return true;
+
+	return false;
+}
+
+static int __init cat_late_init(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+	int maxid, cbmlen;
+
+	if (!cat_supported(c))
+		return -ENODEV;
+
+	maxid = c->x86_cat_closs;
+	cbmlen = c->x86_cat_cbmlength;
+
+	pr_info("cbmlength:%u,Closs: %u\n", cbmlen, maxid);
+
+	return 0;
+}
+
+late_initcall(cat_late_init);
diff --git a/init/Kconfig b/init/Kconfig
index 9afb971..475b7b7 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -961,6 +961,17 @@ config CPUSETS
 
 	  Say N if unsure.
 
+config CGROUP_CAT
+  bool "Cache Allocation Technology cgroup subsystem"
+  depends on X86_64
+	help
+	  This option provides framework to allocate cache lines when
+	  applications fill cache.
+	  This can be used by users to configure how much cache that can be
+	  allocated to different PIDs.
+
+	  Say N if unsure.
+
 config PROC_PID_CPUSET
 	bool "Include legacy /proc/<pid>/cpuset file"
 	depends on CPUSETS
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/6] x86/intel_cat: Adds support for Class of service management
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 3/6] x86/intel_cat: Support cache bit mask for Intel CAT Vikas Shivappa
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

This patch adds a cgroup subsystem to support cache allocation. When a
CAT cgroup is created it has a CLOSid and CBM associated with it which
are inherited from its parent. A Class of service(CLOS) in Cache
Allocation is represented by a CLOSid. CLOSid is internal to the kernel
and not exposed to user. Cache bitmask(CBM) represents one cache
'subset'. Root cgroup would have all available bits set for its CBM and
would be assigned the CLOSid 0.

CLOSid allocation is tracked using a separate bitmap. The maximum number
of CLOSids is specified by the h/w during CPUID enumeration and the
kernel simply throws an -ENOSPC when it runs out of CLOSids.

Each CBM has an associated CLOSid. If multiple cgroups have the same CBM
they would also have the same CLOSid. The reference count parameter in
CLOSid-CBM map keeps track of how many cgroups are using each
CLOSid<->CBM mapping.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/include/asm/intel_cat.h |  40 +++++++++++++
 arch/x86/kernel/cpu/intel_cat.c  | 126 +++++++++++++++++++++++++++++++++++++--
 include/linux/cgroup_subsys.h    |   4 ++
 3 files changed, 165 insertions(+), 5 deletions(-)
 create mode 100644 arch/x86/include/asm/intel_cat.h

diff --git a/arch/x86/include/asm/intel_cat.h b/arch/x86/include/asm/intel_cat.h
new file mode 100644
index 0000000..da277a2
--- /dev/null
+++ b/arch/x86/include/asm/intel_cat.h
@@ -0,0 +1,40 @@
+#ifndef _CAT_H_
+#define _CAT_H_
+
+#ifdef CONFIG_CGROUP_CAT
+
+#include <linux/cgroup.h>
+
+struct cat_subsys_info {
+	/* Clos Bitmap to keep track of available CLOSids.*/
+	unsigned long *closmap;
+};
+
+struct cache_alloc {
+	struct cgroup_subsys_state css;
+	/* Class of service for the cgroup.*/
+	unsigned int clos;
+	/* Corresponding cache bit mask.*/
+	unsigned long *cbm;
+};
+
+struct clos_cbm_map {
+	unsigned long cbm;
+	unsigned int cgrp_count;
+};
+
+/*
+ * Return cat group corresponding to this container.
+ */
+static inline struct cache_alloc *css_cat(struct cgroup_subsys_state *css)
+{
+	return css ? container_of(css, struct cache_alloc, css) : NULL;
+}
+
+static inline struct cache_alloc *parent_cat(struct cache_alloc *cq)
+{
+	return css_cat(cq->css.parent);
+}
+
+#endif
+#endif
diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
index 2f4b19b..37864f8 100644
--- a/arch/x86/kernel/cpu/intel_cat.c
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -23,6 +23,15 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/spinlock.h>
+#include <asm/intel_cat.h>
+
+/*
+ * ccmap maintains 1:1 mapping between CLOSid and cbm.
+ */
+static struct clos_cbm_map *ccmap;
+static struct cat_subsys_info catss_info;
+static DEFINE_MUTEX(cat_group_mutex);
+struct cache_alloc cat_root_group;
 
 static inline bool cat_supported(struct cpuinfo_x86 *c)
 {
@@ -35,17 +44,124 @@ static inline bool cat_supported(struct cpuinfo_x86 *c)
 static int __init cat_late_init(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
-	int maxid, cbmlen;
+	static struct clos_cbm_map *ccm;
+	size_t sizeb;
+	int maxid, cbm_len;
 
-	if (!cat_supported(c))
+	if (!cat_supported(c)) {
+		cat_root_group.css.ss->disabled = 1;
 		return -ENODEV;
 
-	maxid = c->x86_cat_closs;
-	cbmlen = c->x86_cat_cbmlength;
+	} else {
+		maxid = c->x86_cat_closs;
+		cbm_len = c->x86_cat_cbmlength;
+		sizeb = BITS_TO_LONGS(maxid) * sizeof(long);
+
+		catss_info.closmap = kzalloc(sizeb, GFP_KERNEL);
+		if (!catss_info.closmap)
+			return -ENOMEM;
+
+		sizeb = maxid * sizeof(struct clos_cbm_map);
+		ccmap = kzalloc(sizeb, GFP_KERNEL);
+		if (!ccmap) {
+			kfree(catss_info.closmap);
+			return -ENOMEM;
+		}
 
-	pr_info("cbmlength:%u,Closs: %u\n", cbmlen, maxid);
+		set_bit(0, catss_info.closmap);
+		cat_root_group.clos = 0;
+
+		ccm = &ccmap[0];
+		ccm->cbm = (u32)((u64)(1 << cbm_len) - 1);
+		cat_root_group.cbm = &(ccm->cbm);
+		ccm->cgrp_count++;
+	}
+
+	pr_info("cbmlength:%u,Closs: %u\n", cbm_len, maxid);
 
 	return 0;
 }
 
 late_initcall(cat_late_init);
+
+/*
+ * Allocates a new closid from unused closids.
+ * Called with the cat_group_mutex held.
+ */
+
+static int cat_alloc_closid(struct cache_alloc *cq)
+{
+	unsigned int id;
+	unsigned int maxid;
+
+	lockdep_assert_held(&cat_group_mutex);
+
+	maxid = boot_cpu_data.x86_cat_closs;
+	id = find_next_zero_bit(catss_info.closmap, maxid, 0);
+	if (id == maxid)
+		return -ENOSPC;
+
+	set_bit(id, catss_info.closmap);
+	ccmap[id].cgrp_count++;
+	cq->clos = id;
+
+	return 0;
+}
+
+/*
+* Called with the cat_group_mutex held.
+*/
+static int cat_free_closid(struct cache_alloc *cq)
+{
+
+	lockdep_assert_held(&cat_group_mutex);
+
+	WARN_ON(!ccmap[cq->clos].cgrp_count);
+	ccmap[cq->clos].cgrp_count--;
+	if (!ccmap[cq->clos].cgrp_count)
+		clear_bit(cq->clos, catss_info.closmap);
+
+	return 0;
+}
+
+static struct cgroup_subsys_state *
+cat_css_alloc(struct cgroup_subsys_state *parent_css)
+{
+	struct cache_alloc *parent = css_cat(parent_css);
+	struct cache_alloc *cq;
+
+	/*
+	 * Cannot return failure on systems with no Cache Allocation
+	 * as the cgroup_init does not handle failures gracefully.
+	 */
+	if (!parent)
+		return &cat_root_group.css;
+
+	cq = kzalloc(sizeof(struct cache_alloc), GFP_KERNEL);
+	if (!cq)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&cat_group_mutex);
+	cq->clos = parent->clos;
+	ccmap[parent->clos].cgrp_count++;
+	mutex_unlock(&cat_group_mutex);
+
+	cq->cbm = parent->cbm;
+	return &cq->css;
+}
+
+static void cat_css_free(struct cgroup_subsys_state *css)
+{
+	struct cache_alloc *cq = css_cat(css);
+
+	mutex_lock(&cat_group_mutex);
+	cat_free_closid(cq);
+	kfree(cq);
+	mutex_unlock(&cat_group_mutex);
+}
+
+struct cgroup_subsys cat_cgrp_subsys = {
+	.css_alloc			= cat_css_alloc,
+	.css_free			= cat_css_free,
+	.early_init			= 0,
+};
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index 98c4f9b..271c2c7 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -47,6 +47,10 @@ SUBSYS(net_prio)
 SUBSYS(hugetlb)
 #endif
 
+#if IS_ENABLED(CONFIG_CGROUP_CAT)
+SUBSYS(cat)
+#endif
+
 /*
  * The following subsystems are not supported on the default hierarchy.
  */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/6] x86/intel_cat: Support cache bit mask for Intel CAT
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 2/6] x86/intel_cat: Adds support for Class of service management Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 4/6] x86/intel_cat: Implement scheduling support " Vikas Shivappa
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

Add support for cache bit mask manipulation. The change adds a file to
the CAT cgroup which represents the CBM for the cgroup.

The CAT cgroup follows cgroup hierarchy ,mkdir and adding tasks to the
cgroup never fails.  When a child cgroup is created it inherits the
CLOSid and the CBM from its parent.  When a user changes the default
CBM for a cgroup, a new CLOSid may be allocated if the CBM was not
used before. If the new CBM is the one that is already used, the
reference for that CLOSid<->CBM is incremented. The changing of 'cbm'
may fail with -ERRNOSPC once the kernel runs out of maximum CLOSids it
can support.
User can create as many cgroups as he wants but having different CBMs
at the same time is restricted by the maximum number of CLOSids
(multiple cgroups can have the same CBM).
Kernel maintains a CLOSid<->cbm mapping which keeps reference counter
for each cgroup using a CLOSid.

The tasks in the CAT cgroup would get to fill the LLC cache represented
by the cgroup's 'cbm' file.

Reuse of CLOSids for cgroups with same bitmask also has following
goodness:
- This helps to use the scant CLOSids optimally.
- This also implies that during context switch, write to PQR-MSR is done
only when a task with a different bitmask is scheduled in.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/include/asm/intel_cat.h |   3 +
 arch/x86/kernel/cpu/intel_cat.c  | 155 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+)

diff --git a/arch/x86/include/asm/intel_cat.h b/arch/x86/include/asm/intel_cat.h
index da277a2..b19df52 100644
--- a/arch/x86/include/asm/intel_cat.h
+++ b/arch/x86/include/asm/intel_cat.h
@@ -4,6 +4,9 @@
 #ifdef CONFIG_CGROUP_CAT
 
 #include <linux/cgroup.h>
+#define MAX_CBM_LENGTH			32
+#define IA32_L3_CBM_BASE		0xc90
+#define CBM_FROM_INDEX(x)		(IA32_L3_CBM_BASE + x)
 
 struct cat_subsys_info {
 	/* Clos Bitmap to keep track of available CLOSids.*/
diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
index 37864f8..049e840 100644
--- a/arch/x86/kernel/cpu/intel_cat.c
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -33,6 +33,9 @@ static struct cat_subsys_info catss_info;
 static DEFINE_MUTEX(cat_group_mutex);
 struct cache_alloc cat_root_group;
 
+#define cat_for_each_child(pos_css, parent_cq)		\
+	css_for_each_child((pos_css), &(parent_cq)->css)
+
 static inline bool cat_supported(struct cpuinfo_x86 *c)
 {
 	if (cpu_has(c, X86_FEATURE_CAT_L3))
@@ -160,8 +163,160 @@ static void cat_css_free(struct cgroup_subsys_state *css)
 	mutex_unlock(&cat_group_mutex);
 }
 
+/*
+ * Tests if atleast two contiguous bits are set.
+ */
+
+static inline bool cbm_is_contiguous(unsigned long var)
+{
+	unsigned long first_bit, zero_bit;
+	unsigned long maxcbm = MAX_CBM_LENGTH;
+
+	if (bitmap_weight(&var, maxcbm) < 2)
+		return false;
+
+	first_bit = find_next_bit(&var, maxcbm, 0);
+	zero_bit = find_next_zero_bit(&var, maxcbm, first_bit);
+
+	if (find_next_bit(&var, maxcbm, zero_bit) < maxcbm)
+		return false;
+
+	return true;
+}
+
+static int cat_cbm_read(struct seq_file *m, void *v)
+{
+	struct cache_alloc *cq = css_cat(seq_css(m));
+
+	seq_bitmap(m, cq->cbm, MAX_CBM_LENGTH);
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static int validate_cbm(struct cache_alloc *cq, unsigned long cbmvalue)
+{
+	struct cache_alloc *par, *c;
+	struct cgroup_subsys_state *css;
+
+	if (!cbm_is_contiguous(cbmvalue)) {
+		pr_info("cbm should have >= 2 bits and be contiguous\n");
+		return -EINVAL;
+	}
+
+	par = parent_cat(cq);
+	if (!bitmap_subset(&cbmvalue, par->cbm, MAX_CBM_LENGTH))
+		return -EINVAL;
+
+	rcu_read_lock();
+	cat_for_each_child(css, cq) {
+		c = css_cat(css);
+		if (!bitmap_subset(c->cbm, &cbmvalue, MAX_CBM_LENGTH)) {
+			pr_info("Children's mask not a subset\n");
+			rcu_read_unlock();
+			return -EINVAL;
+		}
+	}
+
+	rcu_read_unlock();
+	return 0;
+}
+
+static bool cbm_search(unsigned long cbm, int *closid)
+{
+	int maxid = boot_cpu_data.x86_cat_closs;
+	unsigned int i;
+
+	for (i = 0; i < maxid; i++)
+		if (bitmap_equal(&cbm, &ccmap[i].cbm, MAX_CBM_LENGTH)) {
+			*closid = i;
+			return true;
+		}
+
+	return false;
+}
+
+static void cbmmap_dump(void)
+{
+	int i;
+
+	pr_debug("CBMMAP\n");
+	for (i = 0; i < boot_cpu_data.x86_cat_closs; i++)
+		pr_debug("cbm: 0x%x,cgrp_count: %u\n",
+		 (unsigned int)ccmap[i].cbm, ccmap[i].cgrp_count);
+}
+
+/*
+ * cat_cbm_write() - Validates and writes the cache bit mask(cbm)
+ * to the IA32_L3_MASK_n and also store the same in the ccmap.
+ *
+ * CLOSids are reused for cgroups which have same bitmask.
+ * - This helps to use the scant CLOSids optimally.
+ * - This also implies that at context switch write
+ * to PQR-MSR is done only when a task with a
+ * different bitmask is scheduled in.
+ */
+
+static int cat_cbm_write(struct cgroup_subsys_state *css,
+				 struct cftype *cft, u64 cbmvalue)
+{
+	struct cache_alloc *cq = css_cat(css);
+	ssize_t err = 0;
+	unsigned long cbm;
+	unsigned int closid;
+	u32 cbm_mask =
+		(u32)((u64)(1 << boot_cpu_data.x86_cat_cbmlength) - 1);
+
+	if (cq == &cat_root_group)
+		return -EPERM;
+
+	/*
+	* Need global mutex as cbm write may allocate a closid.
+	*/
+	mutex_lock(&cat_group_mutex);
+	cbm = cbmvalue & cbm_mask;
+
+	if (bitmap_equal(&cbm, cq->cbm, MAX_CBM_LENGTH))
+		goto out;
+
+	err = validate_cbm(cq, cbm);
+	if (err)
+		goto out;
+
+	cat_free_closid(cq);
+	if (cbm_search(cbm, &closid)) {
+		cq->clos = closid;
+		ccmap[cq->clos].cgrp_count++;
+	} else {
+		err = cat_alloc_closid(cq);
+		if (err)
+			goto out;
+
+		wrmsrl(CBM_FROM_INDEX(cq->clos), cbm);
+	}
+
+	ccmap[cq->clos].cbm = cbm;
+	cq->cbm = &ccmap[cq->clos].cbm;
+	cbmmap_dump();
+
+out:
+
+	mutex_unlock(&cat_group_mutex);
+	return err;
+}
+
+static struct cftype cat_files[] = {
+	{
+		.name = "cbm",
+		.seq_show = cat_cbm_read,
+		.write_u64 = cat_cbm_write,
+		.mode = 0666,
+	},
+	{ }	/* terminate */
+};
+
 struct cgroup_subsys cat_cgrp_subsys = {
 	.css_alloc			= cat_css_alloc,
 	.css_free			= cat_css_free,
+	.legacy_cftypes		= cat_files,
 	.early_init			= 0,
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/6] x86/intel_cat: Implement scheduling support for Intel CAT
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
                   ` (2 preceding siblings ...)
  2015-01-28  0:00 ` [PATCH 3/6] x86/intel_cat: Support cache bit mask for Intel CAT Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 5/6] x86/intel_rdt: Software Cache for IA32_PQR_MSR Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 6/6] x86/intel_cat: Intel haswell CAT enumeration Vikas Shivappa
  5 siblings, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

Adds support for IA32_PQR_ASSOC MSR writes during task scheduling.

The high 32 bits in the per processor MSR IA32_PQR_ASSOC represents the
CLOSid. During context switch kernel implements this by writing the
CLOSid of the cgroup to which the task belongs to the CPU's
IA32_PQR_ASSOC MSR.

This would let the task fill in the cache 'subset' represented by the
cgroup's Cache bit mask(CBM).

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/include/asm/intel_cat.h | 54 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/switch_to.h |  3 +++
 arch/x86/kernel/cpu/intel_cat.c  |  3 +++
 kernel/sched/core.c              |  1 +
 kernel/sched/sched.h             |  3 +++
 5 files changed, 64 insertions(+)

diff --git a/arch/x86/include/asm/intel_cat.h b/arch/x86/include/asm/intel_cat.h
index b19df52..eda86b1 100644
--- a/arch/x86/include/asm/intel_cat.h
+++ b/arch/x86/include/asm/intel_cat.h
@@ -4,9 +4,12 @@
 #ifdef CONFIG_CGROUP_CAT
 
 #include <linux/cgroup.h>
+#define MSR_IA32_PQR_ASSOC		0xc8f
 #define MAX_CBM_LENGTH			32
 #define IA32_L3_CBM_BASE		0xc90
 #define CBM_FROM_INDEX(x)		(IA32_L3_CBM_BASE + x)
+DECLARE_PER_CPU(unsigned int, x86_cpu_clos);
+extern struct static_key cat_enable_key;
 
 struct cat_subsys_info {
 	/* Clos Bitmap to keep track of available CLOSids.*/
@@ -26,6 +29,11 @@ struct clos_cbm_map {
 	unsigned int cgrp_count;
 };
 
+static inline bool cat_enabled(void)
+{
+	return static_key_false(&cat_enable_key);
+}
+
 /*
  * Return cat group corresponding to this container.
  */
@@ -39,5 +47,51 @@ static inline struct cache_alloc *parent_cat(struct cache_alloc *cq)
 	return css_cat(cq->css.parent);
 }
 
+/*
+ * Return cat group to which this task belongs.
+ */
+static inline struct cache_alloc *task_cat(struct task_struct *task)
+{
+	return css_cat(task_css(task, cat_cgrp_id));
+}
+
+/*
+ * cat_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR
+ * if the current Closid is different than the new one.
+ */
+
+static inline void cat_sched_in(struct task_struct *task)
+{
+	struct cache_alloc *cq;
+	unsigned int clos;
+
+	if (!cat_enabled())
+		return;
+
+	/*
+	 * This needs to be fixed after CQM code stabilizes
+	 * to cache the whole PQR instead of just CLOSid.
+	 * PQR has closid in high 32 bits and CQM-RMID in low 10 bits.
+	 * Should not write a 0 to the low 10 bits of PQR
+	 * and corrupt RMID.
+	 */
+	clos = this_cpu_read(x86_cpu_clos);
+
+	rcu_read_lock();
+	cq = task_cat(task);
+	if (cq->clos == clos) {
+		rcu_read_unlock();
+		return;
+	}
+
+	wrmsr(MSR_IA32_PQR_ASSOC, 0, cq->clos);
+	this_cpu_write(x86_cpu_clos, cq->clos);
+	rcu_read_unlock();
+}
+
+#else
+
+static inline void cat_sched_in(struct task_struct *task) {}
+
 #endif
 #endif
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index 751bf4b..0662877 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -8,6 +8,9 @@ struct tss_struct;
 void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 		      struct tss_struct *tss);
 
+#include <asm/intel_cat.h>
+#define post_arch_switch(current)	cat_sched_in(current)
+
 #ifdef CONFIG_X86_32
 
 #ifdef CONFIG_CC_STACKPROTECTOR
diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
index 049e840..ebd5ed8 100644
--- a/arch/x86/kernel/cpu/intel_cat.c
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -32,6 +32,8 @@ static struct clos_cbm_map *ccmap;
 static struct cat_subsys_info catss_info;
 static DEFINE_MUTEX(cat_group_mutex);
 struct cache_alloc cat_root_group;
+struct static_key __read_mostly cat_enable_key = STATIC_KEY_INIT_FALSE;
+DEFINE_PER_CPU(unsigned int, x86_cpu_clos);
 
 #define cat_for_each_child(pos_css, parent_cq)		\
 	css_for_each_child((pos_css), &(parent_cq)->css)
@@ -78,6 +80,7 @@ static int __init cat_late_init(void)
 		ccm->cbm = (u32)((u64)(1 << cbm_len) - 1);
 		cat_root_group.cbm = &(ccm->cbm);
 		ccm->cgrp_count++;
+		static_key_slow_inc(&cat_enable_key);
 	}
 
 	pr_info("cbmlength:%u,Closs: %u\n", cbm_len, maxid);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d22fb16..a5c4d87 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2249,6 +2249,7 @@ static struct rq *finish_task_switch(struct task_struct *prev)
 	prev_state = prev->state;
 	vtime_task_switch(prev);
 	finish_arch_switch(prev);
+	post_arch_switch(current);
 	perf_event_task_sched_in(prev, current);
 	finish_lock_switch(rq, prev);
 	finish_arch_post_lock_switch();
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 9a2a45c..49e77d7 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1008,6 +1008,9 @@ static inline int task_on_rq_migrating(struct task_struct *p)
 #ifndef finish_arch_switch
 # define finish_arch_switch(prev)	do { } while (0)
 #endif
+#ifndef post_arch_switch
+# define post_arch_switch(current)	do { } while (0)
+#endif
 #ifndef finish_arch_post_lock_switch
 # define finish_arch_post_lock_switch()	do { } while (0)
 #endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/6] x86/intel_rdt: Software Cache for IA32_PQR_MSR
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
                   ` (3 preceding siblings ...)
  2015-01-28  0:00 ` [PATCH 4/6] x86/intel_cat: Implement scheduling support " Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  2015-01-28  0:00 ` [PATCH 6/6] x86/intel_cat: Intel haswell CAT enumeration Vikas Shivappa
  5 siblings, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

This patch implements a common software cache for IA32_PQR_MSR(RMID 0:9,
    CLOSId 32:63) to be used by both CMT and CAT. CMT updates the RMID
where as CAT updates the CLOSid in the software cache. When the new
RMID/CLOSid value is different from the cached values, IA32_PQR_MSR is
updated. Since the measured rdmsr latency for IA32_PQR_MSR is very
high(~250 cycles) this software cache is necessary to avoid reading the
MSR to compare the current CLOSid value.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/include/asm/intel_cat.h           | 36 ++++++++++++++++--------------
 arch/x86/include/asm/rdt.h                 | 13 +++++++++++
 arch/x86/kernel/cpu/perf_event_intel_cqm.c | 20 ++++++-----------
 3 files changed, 39 insertions(+), 30 deletions(-)
 create mode 100644 arch/x86/include/asm/rdt.h

diff --git a/arch/x86/include/asm/intel_cat.h b/arch/x86/include/asm/intel_cat.h
index eda86b1..a534e94 100644
--- a/arch/x86/include/asm/intel_cat.h
+++ b/arch/x86/include/asm/intel_cat.h
@@ -4,11 +4,13 @@
 #ifdef CONFIG_CGROUP_CAT
 
 #include <linux/cgroup.h>
-#define MSR_IA32_PQR_ASSOC		0xc8f
-#define MAX_CBM_LENGTH			32
-#define IA32_L3_CBM_BASE		0xc90
+#include <asm/rdt.h>
+
+#define MAX_CBM_LENGTH		32
+#define IA32_L3_CBM_BASE	0xc90
 #define CBM_FROM_INDEX(x)		(IA32_L3_CBM_BASE + x)
-DECLARE_PER_CPU(unsigned int, x86_cpu_clos);
+
+DECLARE_PER_CPU(struct intel_pqr_state, pqr_state);
 extern struct static_key cat_enable_key;
 
 struct cat_subsys_info {
@@ -63,30 +65,30 @@ static inline struct cache_alloc *task_cat(struct task_struct *task)
 static inline void cat_sched_in(struct task_struct *task)
 {
 	struct cache_alloc *cq;
-	unsigned int clos;
+	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+	unsigned long flags;
 
 	if (!cat_enabled())
 		return;
 
-	/*
-	 * This needs to be fixed after CQM code stabilizes
-	 * to cache the whole PQR instead of just CLOSid.
-	 * PQR has closid in high 32 bits and CQM-RMID in low 10 bits.
-	 * Should not write a 0 to the low 10 bits of PQR
-	 * and corrupt RMID.
-	 */
-	clos = this_cpu_read(x86_cpu_clos);
-
+	raw_spin_lock_irqsave(&state->lock, flags);
 	rcu_read_lock();
 	cq = task_cat(task);
-	if (cq->clos == clos) {
+	if (cq->clos == state->clos) {
 		rcu_read_unlock();
+		raw_spin_unlock_irqrestore(&state->lock, flags);
 		return;
 	}
 
-	wrmsr(MSR_IA32_PQR_ASSOC, 0, cq->clos);
-	this_cpu_write(x86_cpu_clos, cq->clos);
+	/*
+	 * PQR has closid in high 32 bits and CQM-RMID
+	 * in low 10 bits. Rewrite the exsting rmid from
+	 * software cache.
+	 */
+	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, cq->clos);
+	state->clos = cq->clos;
 	rcu_read_unlock();
+	raw_spin_unlock_irqrestore(&state->lock, flags);
 }
 
 #else
diff --git a/arch/x86/include/asm/rdt.h b/arch/x86/include/asm/rdt.h
new file mode 100644
index 0000000..c87f908
--- /dev/null
+++ b/arch/x86/include/asm/rdt.h
@@ -0,0 +1,13 @@
+#ifndef _X86_RDT_H_
+#define _X86_RDT_H_
+
+#define MSR_IA32_PQR_ASSOC	0x0c8f
+
+struct intel_pqr_state {
+	raw_spinlock_t    lock;
+	int     rmid;
+	int     clos;
+	int       cnt;
+};
+
+#endif
diff --git a/arch/x86/kernel/cpu/perf_event_intel_cqm.c b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
index 596d1ec..15564e2 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
@@ -7,22 +7,16 @@
 #include <linux/perf_event.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
+#include <asm/rdt.h>
 #include "perf_event.h"
 
-#define MSR_IA32_PQR_ASSOC	0x0c8f
 #define MSR_IA32_QM_CTR		0x0c8e
 #define MSR_IA32_QM_EVTSEL	0x0c8d
 
 static unsigned int cqm_max_rmid = -1;
 static unsigned int cqm_l3_scale; /* supposedly cacheline size */
 
-struct intel_cqm_state {
-	raw_spinlock_t		lock;
-	int			rmid;
-	int 			cnt;
-};
-
-static DEFINE_PER_CPU(struct intel_cqm_state, cqm_state);
+DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
 
 /*
  * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
@@ -931,7 +925,7 @@ out:
 
 static void intel_cqm_event_start(struct perf_event *event, int mode)
 {
-	struct intel_cqm_state *state = this_cpu_ptr(&cqm_state);
+	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
 	unsigned int rmid = event->hw.cqm_rmid;
 	unsigned long flags;
 
@@ -948,14 +942,14 @@ static void intel_cqm_event_start(struct perf_event *event, int mode)
 		WARN_ON_ONCE(state->rmid);
 
 	state->rmid = rmid;
-	wrmsrl(MSR_IA32_PQR_ASSOC, state->rmid);
+	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, state->clos);
 
 	raw_spin_unlock_irqrestore(&state->lock, flags);
 }
 
 static void intel_cqm_event_stop(struct perf_event *event, int mode)
 {
-	struct intel_cqm_state *state = this_cpu_ptr(&cqm_state);
+	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
 	unsigned long flags;
 
 	if (event->hw.cqm_state & PERF_HES_STOPPED)
@@ -968,7 +962,7 @@ static void intel_cqm_event_stop(struct perf_event *event, int mode)
 
 	if (!--state->cnt) {
 		state->rmid = 0;
-		wrmsrl(MSR_IA32_PQR_ASSOC, 0);
+		wrmsr(MSR_IA32_PQR_ASSOC, 0, state->clos);
 	} else {
 		WARN_ON_ONCE(!state->rmid);
 	}
@@ -1213,7 +1207,7 @@ static inline void cqm_pick_event_reader(int cpu)
 
 static void intel_cqm_cpu_prepare(unsigned int cpu)
 {
-	struct intel_cqm_state *state = &per_cpu(cqm_state, cpu);
+	struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	raw_spin_lock_init(&state->lock);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/6] x86/intel_cat: Intel haswell CAT enumeration
  2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
                   ` (4 preceding siblings ...)
  2015-01-28  0:00 ` [PATCH 5/6] x86/intel_rdt: Software Cache for IA32_PQR_MSR Vikas Shivappa
@ 2015-01-28  0:00 ` Vikas Shivappa
  5 siblings, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28  0:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: vikas.shivappa, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

CAT(Cache Allocation Technology) on hsw needs to be enumerated
separately. CAT is only supported on certain HSW SKUs.  This patch does
a probe test for hsw CPUs by writing a CLOSid into high 32 bits of
IA32_PQR_MSR and see if the bits stick. The probe test is only done
after confirming that the CPU is HSW.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
 arch/x86/kernel/cpu/intel_cat.c | 42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
index ebd5ed8..becddf0 100644
--- a/arch/x86/kernel/cpu/intel_cat.c
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -38,11 +38,53 @@ DEFINE_PER_CPU(unsigned int, x86_cpu_clos);
 #define cat_for_each_child(pos_css, parent_cq)		\
 	css_for_each_child((pos_css), &(parent_cq)->css)
 
+/*
+ * hsw_probetest() - Have to do probe
+ * test for Intel haswell CPUs as it does not have
+ * CPUID enumeration support for CAT.
+ *
+ * Probes by writing to the high 32 bits(CLOSid)
+ * of the IA32_PQR_MSR and testing if the bits stick.
+ * Then hardcode the max CLOS and max bitmask length on hsw.
+ */
+
+static inline bool hsw_probetest(void)
+{
+	u32 l, h_old, h_new, h_tmp;
+
+	if (rdmsr_safe(MSR_IA32_PQR_ASSOC, &l, &h_old))
+		return false;
+
+	/*
+	 * Default value is always 0 if feature is present.
+	 */
+	h_tmp = h_old ^ 0x1U;
+	if (wrmsr_safe(MSR_IA32_PQR_ASSOC, l, h_tmp) ||
+	    rdmsr_safe(MSR_IA32_PQR_ASSOC, &l, &h_new))
+		return false;
+
+	if (h_tmp != h_new)
+		return false;
+
+	wrmsr_safe(MSR_IA32_PQR_ASSOC, l, h_old);
+
+	boot_cpu_data.x86_cat_closs = 4;
+	boot_cpu_data.x86_cat_cbmlength = 20;
+
+	return true;
+}
+
 static inline bool cat_supported(struct cpuinfo_x86 *c)
 {
 	if (cpu_has(c, X86_FEATURE_CAT_L3))
 		return true;
 
+	/*
+	 * Probe test for Haswell CPUs.
+	 */
+	if (c->x86 == 6 && c->x86_model == 0x3f)
+		return hsw_probetest();
+
 	return false;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection
  2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
@ 2015-01-28 22:11   ` Paul Bolle
  2015-01-28 23:17     ` Vikas Shivappa
  2015-02-09 19:50     ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology Vikas Shivappa
  2015-02-03 10:57   ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Matt Fleming
  1 sibling, 2 replies; 11+ messages in thread
From: Paul Bolle @ 2015-01-28 22:11 UTC (permalink / raw)
  To: Vikas Shivappa
  Cc: linux-kernel, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

Trivial nit below.

On Tue, 2015-01-27 at 16:00 -0800, Vikas Shivappa wrote:
> This patch adds support for the new Cache Allocation Technology (CAT)
> feature found in future Intel Xeon processors.  It includes CPUID
> enumeration routines for CAT and new values to track CAT resources to
> the cpuinfo_x86 structure.
> 
> Cache Allocation Technology(CAT) provides a way for the Software
> (OS/VMM) to restrict cache allocation to a defined 'subset' of cache
> which may be overlapping with other 'subsets'.  This feature is used
> when allocating a line in cache ie when pulling new data into the cache.
> The programming of the h/w is done via programming  MSRs.
> 
> More information about CAT be found in the Intel (R) x86 Architecture
> Software Developer Manual, section 17.15.
> 
> Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>

[...]

> diff --git a/init/Kconfig b/init/Kconfig
> index 9afb971..475b7b7 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -961,6 +961,17 @@ config CPUSETS
>  
>  	  Say N if unsure.
>  
> +config CGROUP_CAT
> +  bool "Cache Allocation Technology cgroup subsystem"
> +  depends on X86_64

Odd indentation. Just make it a tab (as I suppose the indentation of
"help" already is).

> +	help
> +	  This option provides framework to allocate cache lines when
> +	  applications fill cache.
> +	  This can be used by users to configure how much cache that can be
> +	  allocated to different PIDs.
> +
> +	  Say N if unsure.
> +
>  config PROC_PID_CPUSET
>  	bool "Include legacy /proc/<pid>/cpuset file"
>  	depends on CPUSETS


Paul Bolle


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection
  2015-01-28 22:11   ` Paul Bolle
@ 2015-01-28 23:17     ` Vikas Shivappa
  2015-02-09 19:50     ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology Vikas Shivappa
  1 sibling, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-01-28 23:17 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Vikas Shivappa, linux-kernel, vikas.shivappa, hpa, tglx, mingo,
	tj, peterz, Matt Fleming, Auld, Will



On Wed, 28 Jan 2015, Paul Bolle wrote:

> Trivial nit below.
>
> On Tue, 2015-01-27 at 16:00 -0800, Vikas Shivappa wrote:
>> This patch adds support for the new Cache Allocation Technology (CAT)
>> feature found in future Intel Xeon processors.  It includes CPUID
>> enumeration routines for CAT and new values to track CAT resources to
>> the cpuinfo_x86 structure.
>>
>> Cache Allocation Technology(CAT) provides a way for the Software
>> (OS/VMM) to restrict cache allocation to a defined 'subset' of cache
>> which may be overlapping with other 'subsets'.  This feature is used
>> when allocating a line in cache ie when pulling new data into the cache.
>> The programming of the h/w is done via programming  MSRs.
>>
>> More information about CAT be found in the Intel (R) x86 Architecture
>> Software Developer Manual, section 17.15.
>>
>> Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
>
> [...]
>
>> diff --git a/init/Kconfig b/init/Kconfig
>> index 9afb971..475b7b7 100644
>> --- a/init/Kconfig
>> +++ b/init/Kconfig
>> @@ -961,6 +961,17 @@ config CPUSETS
>>
>>  	  Say N if unsure.
>>
>> +config CGROUP_CAT
>> +  bool "Cache Allocation Technology cgroup subsystem"
>> +  depends on X86_64
>
> Odd indentation. Just make it a tab (as I suppose the indentation of
> "help" already is).

ok , Will fix. Wish the checkpatch.pl caught that :)

Thanks,
Vikas

>
>> +	help
>> +	  This option provides framework to allocate cache lines when
>> +	  applications fill cache.
>> +	  This can be used by users to configure how much cache that can be
>> +	  allocated to different PIDs.
>> +
>> +	  Say N if unsure.
>> +
>>  config PROC_PID_CPUSET
>>  	bool "Include legacy /proc/<pid>/cpuset file"
>>  	depends on CPUSETS
>
>
> Paul Bolle
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection
  2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
  2015-01-28 22:11   ` Paul Bolle
@ 2015-02-03 10:57   ` Matt Fleming
  1 sibling, 0 replies; 11+ messages in thread
From: Matt Fleming @ 2015-02-03 10:57 UTC (permalink / raw)
  To: Vikas Shivappa
  Cc: linux-kernel, vikas.shivappa, hpa, tglx, mingo, tj, peterz,
	matt.fleming, will.auld

On Tue, 27 Jan, at 04:00:04PM, Vikas Shivappa wrote:
> This patch adds support for the new Cache Allocation Technology (CAT)
> feature found in future Intel Xeon processors.  It includes CPUID
> enumeration routines for CAT and new values to track CAT resources to
> the cpuinfo_x86 structure.
> 
> Cache Allocation Technology(CAT) provides a way for the Software
> (OS/VMM) to restrict cache allocation to a defined 'subset' of cache
> which may be overlapping with other 'subsets'.  This feature is used
> when allocating a line in cache ie when pulling new data into the cache.
> The programming of the h/w is done via programming  MSRs.
> 
> More information about CAT be found in the Intel (R) x86 Architecture
> Software Developer Manual, section 17.15.
> 
> Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
> ---
>  arch/x86/include/asm/cpufeature.h |  6 ++++-
>  arch/x86/include/asm/processor.h  |  3 +++
>  arch/x86/kernel/cpu/Makefile      |  1 +
>  arch/x86/kernel/cpu/common.c      | 16 ++++++++++++
>  arch/x86/kernel/cpu/intel_cat.c   | 51 +++++++++++++++++++++++++++++++++++++++
>  init/Kconfig                      | 11 +++++++++
>  6 files changed, 87 insertions(+), 1 deletion(-)
>  create mode 100644 arch/x86/kernel/cpu/intel_cat.c

Acked-by: Matt Fleming <matt.fleming@intel.com>

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology
  2015-01-28 22:11   ` Paul Bolle
  2015-01-28 23:17     ` Vikas Shivappa
@ 2015-02-09 19:50     ` Vikas Shivappa
  1 sibling, 0 replies; 11+ messages in thread
From: Vikas Shivappa @ 2015-02-09 19:50 UTC (permalink / raw)
  To: vikas.shivappa
  Cc: vikas.shivappa, linux-kernel, pebolle, hpa, tglx, mingo, tj,
	peterz, matt.fleming, will.auld

This patch adds support for the new Cache Allocation Technology (CAT)
feature found in future Intel Xeon processors.  It includes CPUID
enumeration routines for CAT and new values to track CAT resources to
the cpuinfo_x86 structure.

Cache Allocation Technology(CAT) provides a way for the Software
(OS/VMM) to restrict cache allocation to a defined 'subset' of cache
which may be overlapping with other 'subsets'.  This feature is used
when allocating a line in cache ie when pulling new data into the cache.
The programming of the h/w is done via programming  MSRs.

More information about CAT be found in the Intel (R) x86 Architecture
Software Developer Manual, section 17.15.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---

A minor change with Corrected indentation in init/Kconfig

 arch/x86/include/asm/cpufeature.h |  6 ++++-
 arch/x86/include/asm/processor.h  |  3 +++
 arch/x86/kernel/cpu/Makefile      |  1 +
 arch/x86/kernel/cpu/common.c      | 16 ++++++++++++
 arch/x86/kernel/cpu/intel_cat.c   | 51 +++++++++++++++++++++++++++++++++++++++
 init/Kconfig                      | 11 +++++++++
 6 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/kernel/cpu/intel_cat.c

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 54fd8eb..358b15b 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -12,7 +12,7 @@
 #include <asm/disabled-features.h>
 #endif
 
-#define NCAPINTS	13	/* N 32-bit words worth of info */
+#define NCAPINTS	14	/* N 32-bit words worth of info */
 #define NBUGINTS	1	/* N 32-bit bug flags */
 
 /*
@@ -227,6 +227,7 @@
 #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_CAT		( 9*32+15) /* Cache QOS Enforcement */
 #define X86_FEATURE_AVX512F	( 9*32+16) /* AVX-512 Foundation */
 #define X86_FEATURE_RDSEED	( 9*32+18) /* The RDSEED instruction */
 #define X86_FEATURE_ADX		( 9*32+19) /* The ADCX and ADOX instructions */
@@ -248,6 +249,9 @@
 /* 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 */
 
+/* Intel-defined CPU features, CPUID level 0x00000010:0 (ebx), word 13 */
+#define X86_FEATURE_CAT_L3	(13*32 + 1) /*Cache QOS Enforcement L3*/
+
 /*
  * BUG word(s)
  */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 242ceed..62863e9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -112,6 +112,9 @@ struct cpuinfo_x86 {
 	/* Cache QoS architectural values: */
 	int			x86_cache_max_rmid;	/* max index */
 	int			x86_cache_occ_scale;	/* scale to bytes */
+	/* Cache Allocation Technology values */
+	int			x86_cat_cbmlength;
+	int			x86_cat_closs;
 	int			x86_power;
 	unsigned long		loops_per_jiffy;
 	/* cpuid returned max cores value: */
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 6c1ca13..f008cd8 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE)	+= perf_event_intel_uncore.o \
 					   perf_event_intel_uncore_nhmex.o
 endif
 
+obj-$(CONFIG_CGROUP_CAT) 		+=intel_cat.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9b0fb70..18e8d75 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -668,6 +668,22 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
 		}
 	}
 
+	/* Additional Intel-defined flags: level 0x00000010 */
+	if (c->cpuid_level >= 0x00000010) {
+		u32 eax, ebx, ecx, edx;
+
+		cpuid_count(0x00000010, 0, &eax, &ebx, &ecx, &edx);
+		c->x86_capability[13] = ebx;
+
+		if (cpu_has(c, X86_FEATURE_CAT) &&
+			   cpu_has(c, X86_FEATURE_CAT_L3)) {
+
+			cpuid_count(0x00000010, 1, &eax, &ebx, &ecx, &edx);
+			c->x86_cat_closs = (edx & 0xffff) + 1;
+			c->x86_cat_cbmlength = (eax & 0xf) + 1;
+		}
+	}
+
 	/* AMD-defined flags: level 0x80000001 */
 	xlvl = cpuid_eax(0x80000000);
 	c->extended_cpuid_level = xlvl;
diff --git a/arch/x86/kernel/cpu/intel_cat.c b/arch/x86/kernel/cpu/intel_cat.c
new file mode 100644
index 0000000..2f4b19b
--- /dev/null
+++ b/arch/x86/kernel/cpu/intel_cat.c
@@ -0,0 +1,51 @@
+/*
+ * Processor Cache Allocation Technology(CAT) code
+ *
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * 2014-09-10 Written by Vikas Shivappa
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * More information about CAT be found in the Intel (R) x86 Architecture
+ * Software Developer Manual, section 17.15.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+
+static inline bool cat_supported(struct cpuinfo_x86 *c)
+{
+	if (cpu_has(c, X86_FEATURE_CAT_L3))
+		return true;
+
+	return false;
+}
+
+static int __init cat_late_init(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+	int maxid, cbmlen;
+
+	if (!cat_supported(c))
+		return -ENODEV;
+
+	maxid = c->x86_cat_closs;
+	cbmlen = c->x86_cat_cbmlength;
+
+	pr_info("cbmlength:%u,Closs: %u\n", cbmlen, maxid);
+
+	return 0;
+}
+
+late_initcall(cat_late_init);
diff --git a/init/Kconfig b/init/Kconfig
index 9afb971..f4b602b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -961,6 +961,17 @@ config CPUSETS
 
 	  Say N if unsure.
 
+config CGROUP_CAT
+	bool "Cache Allocation Technology cgroup subsystem"
+	depends on X86_64
+	help
+	  This option provides framework to allocate cache lines when
+	  applications fill cache.
+	  This can be used by users to configure how much cache that can be
+	  allocated to different PIDs.
+
+	  Say N if unsure.
+
 config PROC_PID_CPUSET
 	bool "Include legacy /proc/<pid>/cpuset file"
 	depends on CPUSETS
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-02-09 19:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-28  0:00 [PATCH V3 0/6] x86: Intel Cache Allocation Support Vikas Shivappa
2015-01-28  0:00 ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Vikas Shivappa
2015-01-28 22:11   ` Paul Bolle
2015-01-28 23:17     ` Vikas Shivappa
2015-02-09 19:50     ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology Vikas Shivappa
2015-02-03 10:57   ` [PATCH 1/6] x86/intel_cat: Intel Cache Allocation Technology detection Matt Fleming
2015-01-28  0:00 ` [PATCH 2/6] x86/intel_cat: Adds support for Class of service management Vikas Shivappa
2015-01-28  0:00 ` [PATCH 3/6] x86/intel_cat: Support cache bit mask for Intel CAT Vikas Shivappa
2015-01-28  0:00 ` [PATCH 4/6] x86/intel_cat: Implement scheduling support " Vikas Shivappa
2015-01-28  0:00 ` [PATCH 5/6] x86/intel_rdt: Software Cache for IA32_PQR_MSR Vikas Shivappa
2015-01-28  0:00 ` [PATCH 6/6] x86/intel_cat: Intel haswell CAT enumeration Vikas Shivappa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.