Skip to contentSkip to conversation

Intel Cache Allocation Technology

PATCH In review Fenghua Yu 3 participants 24 messages Oct 28, 2016 – Oct 31, 2016

Subsystems (3)
lore
Share & tools
lore

Fenghua Yu

author
#0 lore raw

v6 cover Intel Cache Allocation Technology

From: Fenghua Yu <[email protected]>

This version is supposed to cover all comments from Thomas.

Patch 1-4, 6-9 of 18 v5 patches are in tip x86/cache branch. We have rest of 10 patches in v6 on top of tip tree.

Change log in v6:

patch 1 (i.e. patch 5 in v5): Change max_cbm_val to cbm_mask.

patch 2 (i.e. patch 10 in v5): Change comments for rdt_find_domain and domain_add_cpu() to explain why domain list is sorted by id. Change the pos argument to optional in rdt_rind_domain and assign NULL to it in caller domain_remove_cpu.

patch 3 (i.e. patch 11 in v5): Remove arg's type cast in l3_qos_cfg_update(). Change the local variable declaration lines in more readable way. Disable CDP in umount only when it's enabled. Fix an error handling issue in rdt_mount.

patch 4 (i.e. patch 12 in v5): Change names from "num_closid" to "num_closids" and from "cbm_val" to "cbm_mask" in res_info_files. Remove the unused label "out" in rdtgroup_setup_root() and will add it later when it's used.

patch 5 (i.e. patch 13 in v5): Init closid_free_map by minimal closid instead of by maximum closid in all resources.

patch 6 (i.e. patch 14 in v5): Change local variable declaration lines to more readable way.

patch 7 (i.e. patch 15 in v5): Change for_each_process to for_each_process_thread

patch 8 (i.e. patch 16 in v5): Change local variable declaration lines to more readable way.

patch 9 (i.e. patch 17 in v5): No change.

patch 10 (i.e. patch 18 in v5): No change.

Fenghua Yu (7):
Documentation, x86: Documentation for Intel resource allocation user
interface
x86/intel_rdt: Add basic resctrl filesystem support x86/intel_rdt: Add "info" files to resctrl file system x86/intel_rdt: Add mkdir to resctrl file system x86/intel_rdt: Add tasks files
x86/intel_rdt: Add scheduler hook
MAINTAINERS: Add maintainer for Intel RDT resource allocation

Tony Luck (3):
x86/intel_rdt: Build structures for each resource based on cache
topology
x86/intel_rdt: Add cpus file
x86/intel_rdt: Add schemata file

 Documentation/x86/intel_rdt_ui.txt       |  167 +++++
 MAINTAINERS                              |    8 +
 arch/x86/include/asm/intel_rdt.h         |  145 +++++
 arch/x86/kernel/cpu/Makefile             |    2 +-
 arch/x86/kernel/cpu/intel_rdt.c          |  213 ++++++-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 1007 ++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel_rdt_schemata.c |  245 ++++++++
 arch/x86/kernel/process_32.c             |    4 +
 arch/x86/kernel/process_64.c             |    4 +
 include/linux/sched.h                    |    3 +
 include/uapi/linux/magic.h               |    1 +
 11 files changed, 1797 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/x86/intel_rdt_ui.txt
 create mode 100644 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
 create mode 100644 arch/x86/kernel/cpu/intel_rdt_schemata.c
Signature · 1 line
2.5.0
author
#1 lore raw

PATCH v6 1/10 Documentation, x86: Documentation for Intel resource allocation user interface

From: Fenghua Yu <[email protected]>

The documentation describes user interface of how to allocate resource in Intel RDT.

Please note that the documentation covers generic user interface. Current patch set code only implemente CAT L3. CAT L2 code will be sent later.

---
 Documentation/x86/intel_rdt_ui.txt | 167 +++++++++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)
 create mode 100644 Documentation/x86/intel_rdt_ui.txt
Documentation/x86/intel_rdt_ui.txt new file +167 -0
new file mode 100644
index 0000000..c4fd112
@@ -0,0 +1,167 @@
+User Interface for Resource Allocation in Intel Resource Director Technology
+
+Copyright (C) 2016 Intel Corporation
+
+Fenghua Yu <[email protected]>
+Tony Luck <[email protected]>
+
+This feature is enabled by the CONFIG_INTEL_RDT_A Kconfig and the
+X86 /proc/cpuinfo flag bits "rdt", "cat_l3" and "cdp_l3".
+
+To use the feature mount the file system:
+
+ # mount -t resctrl resctrl [-o cdp] /sys/fs/resctrl
+
+mount options are:
+
+"cdp": Enable code/data prioritization in L3 cache allocations.
+
+
+Resource groups
+---------------
+Resource groups are represented as directories in the resctrl file
+system. The default group is the root directory. Other groups may be
+created as desired by the system administrator using the "mkdir(1)"
+command, and removed using "rmdir(1)".
+
+There are three files associated with each group:
+
+"tasks": A list of tasks that belongs to this group. Tasks can be
+	added to a group by writing the task ID to the "tasks" file
+	(which will automatically remove them from the previous
+	group to which they belonged). New tasks created by fork(2)
+	and clone(2) are added to the same group as their parent.
+	If a pid is not in any sub partition, it is in root partition
+	(i.e. default partition).
+
+"cpus": A bitmask of logical CPUs assigned to this group. Writing
+	a new mask can add/remove CPUs from this group. Added CPUs
+	are removed from their previous group. Removed ones are
+	given to the default (root) group. You cannot remove CPUs
+	from the default group.
+
+"schemata": A list of all the resources available to this group.
+	Each resource has its own line and format - see below for
+	details.
+
+When a task is running the following rules define which resources
+are available to it:
+
+1) If the task is a member of a non-default group, then the schemata
+for that group is used.
+
+2) Else if the task belongs to the default group, but is running on a
+CPU that is assigned to some specific group, then the schemata for
+the CPU's group is used.
+
+3) Otherwise the schemata for the default group is used.
+
+
+Schemata files - general concepts
+---------------------------------
+Each line in the file describes one resource. The line starts with
+the name of the resource, followed by specific values to be applied
+in each of the instances of that resource on the system.
+
+Cache IDs
+---------
+On current generation systems there is one L3 cache per socket and L2
+caches are generally just shared by the hyperthreads on a core, but this
+isn't an architectural requirement. We could have multiple separate L3
+caches on a socket, multiple cores could share an L2 cache. So instead
+of using "socket" or "core" to define the set of logical cpus sharing
+a resource we use a "Cache ID". At a given cache level this will be a
+unique number across the whole system (but it isn't guaranteed to be a
+contiguous sequence, there may be gaps).  To find the ID for each logical
+CPU look in /sys/devices/system/cpu/cpu*/cache/index*/id
+
+Cache Bit Masks (CBM)
+---------------------
+For cache resources we describe the portion of the cache that is available
+for allocation using a bitmask. The maximum value of the mask is defined
+by each cpu model (and may be different for different cache levels). It
+is found using CPUID, but is also provided in the "info" directory of
+the resctrl file system in "info/{resource}/cbm_mask". X86 hardware
+requires that these masks have all the '1' bits in a contiguous block. So
+0x3, 0x6 and 0xC are legal 4-bit masks with two bits set, but 0x5, 0x9
+and 0xA are not.  On a system with a 20-bit mask each bit represents 5%
+of the capacity of the cache. You could partition the cache into four
+equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000.
+
+
+L3 details (code and data prioritization disabled)
+--------------------------------------------------
+With CDP disabled the L3 schemata format is:
+
+	L3:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L3 details (CDP enabled via mount option to resctrl)
+----------------------------------------------------
+When CDP is enabled L3 control is split into two separate resources
+so you can specify independent masks for code and data like this:
+
+	L3data:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+	L3code:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L2 details
+----------
+L2 cache does not support code and data prioritization, so the
+schemata format is always:
+
+	L2:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+Example 1
+---------
+On a two socket machine (one L3 cache per socket) with just four bits
+for cache bit masks
+
+# mount -t resctrl resctrl /sys/fs/resctrl
+# cd /sys/fs/resctrl
+# mkdir p0 p1
+# echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata
+# echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata
+
+The default resource group is unmodified, so we have access to all parts
+of all caches (its schemata file reads "L3:0=f;1=f").
+
+Tasks that are under the control of group "p0" may only allocate from the
+"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
+Tasks in group "p1" use the "lower" 50% of cache on both sockets.
+
+Example 2
+---------
+Again two sockets, but this time with a more realistic 20-bit mask.
+
+Two real time tasks pid=1234 running on processor 0 and pid=5678 running on
+processor 1 on socket 0 on a 2-socket and dual core machine. To avoid noisy
+neighbors, each of the two real-time tasks exclusively occupies one quarter
+of L3 cache on socket 0.
+
+# mount -t resctrl resctrl /sys/fs/resctrl
+# cd /sys/fs/resctrl
+
+First we reset the schemata for the default group so that the "upper"
+50% of the L3 cache on socket 0 cannot be used by ordinary tasks:
+
+# echo "L3:0=3ff;1=fffff" > schemata
+
+Next we make a resource group for our first real time task and give
+it access to the "top" 25% of the cache on socket 0.
+
+# mkdir p0
+# echo "L3:0=f8000;1=fffff" > p0/schemata
+
+Finally we move our first real time task into this resource group. We
+also use taskset(1) to ensure the task always runs on a dedicated CPU
+on socket 0. Most uses of resource groups will also constrain which
+processors tasks run on.
+
+# echo 1234 > p0/tasks
+# taskset -cp 1 1234
+
+Ditto for the second real time task (with the remaining 25% of cache):
+
+# mkdir p1
+# echo "L3:0=7c00;1=fffff" > p1/schemata
+# echo 5678 > p1/tasks
+# taskset -cp 2 5678
Signature · 1 line
2.5.0
#2 lore raw

[tip:x86/cache] Documentation, x86: Documentation for Intel resource allocation user interface

Documentation, x86: Documentation for Intel resource allocation user interface
Commit-ID:  f20e57892806ad244eaec7a7ae365e78fee53377
Gitweb:     http://git.kernel.org/tip/f20e57892806ad244eaec7a7ae365e78fee53377
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:40 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:13 -0600

Documentation, x86: Documentation for Intel resource allocation user interface

The documentation describes user interface of how to allocate resource in Intel RDT.

Please note that the documentation covers generic user interface. Current patch set code only implemente CAT L3. CAT L2 code will be sent later.

[ tglx: Added cpu example ]

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 Documentation/x86/intel_rdt_ui.txt | 195 +++++++++++++++++++++++++++++++++++++
 1 file changed, 195 insertions(+)
Documentation/x86/intel_rdt_ui.txt new file +195 -0
new file mode 100644
index 0000000..3b0ebd4
@@ -0,0 +1,195 @@
+User Interface for Resource Allocation in Intel Resource Director Technology
+
+Copyright (C) 2016 Intel Corporation
+
+Fenghua Yu <[email protected]>
+Tony Luck <[email protected]>
+
+This feature is enabled by the CONFIG_INTEL_RDT_A Kconfig and the
+X86 /proc/cpuinfo flag bits "rdt", "cat_l3" and "cdp_l3".
+
+To use the feature mount the file system:
+
+ # mount -t resctrl resctrl [-o cdp] /sys/fs/resctrl
+
+mount options are:
+
+"cdp": Enable code/data prioritization in L3 cache allocations.
+
+
+Resource groups
+---------------
+Resource groups are represented as directories in the resctrl file
+system. The default group is the root directory. Other groups may be
+created as desired by the system administrator using the "mkdir(1)"
+command, and removed using "rmdir(1)".
+
+There are three files associated with each group:
+
+"tasks": A list of tasks that belongs to this group. Tasks can be
+	added to a group by writing the task ID to the "tasks" file
+	(which will automatically remove them from the previous
+	group to which they belonged). New tasks created by fork(2)
+	and clone(2) are added to the same group as their parent.
+	If a pid is not in any sub partition, it is in root partition
+	(i.e. default partition).
+
+"cpus": A bitmask of logical CPUs assigned to this group. Writing
+	a new mask can add/remove CPUs from this group. Added CPUs
+	are removed from their previous group. Removed ones are
+	given to the default (root) group. You cannot remove CPUs
+	from the default group.
+
+"schemata": A list of all the resources available to this group.
+	Each resource has its own line and format - see below for
+	details.
+
+When a task is running the following rules define which resources
+are available to it:
+
+1) If the task is a member of a non-default group, then the schemata
+for that group is used.
+
+2) Else if the task belongs to the default group, but is running on a
+CPU that is assigned to some specific group, then the schemata for
+the CPU's group is used.
+
+3) Otherwise the schemata for the default group is used.
+
+
+Schemata files - general concepts
+---------------------------------
+Each line in the file describes one resource. The line starts with
+the name of the resource, followed by specific values to be applied
+in each of the instances of that resource on the system.
+
+Cache IDs
+---------
+On current generation systems there is one L3 cache per socket and L2
+caches are generally just shared by the hyperthreads on a core, but this
+isn't an architectural requirement. We could have multiple separate L3
+caches on a socket, multiple cores could share an L2 cache. So instead
+of using "socket" or "core" to define the set of logical cpus sharing
+a resource we use a "Cache ID". At a given cache level this will be a
+unique number across the whole system (but it isn't guaranteed to be a
+contiguous sequence, there may be gaps).  To find the ID for each logical
+CPU look in /sys/devices/system/cpu/cpu*/cache/index*/id
+
+Cache Bit Masks (CBM)
+---------------------
+For cache resources we describe the portion of the cache that is available
+for allocation using a bitmask. The maximum value of the mask is defined
+by each cpu model (and may be different for different cache levels). It
+is found using CPUID, but is also provided in the "info" directory of
+the resctrl file system in "info/{resource}/cbm_mask". X86 hardware
+requires that these masks have all the '1' bits in a contiguous block. So
+0x3, 0x6 and 0xC are legal 4-bit masks with two bits set, but 0x5, 0x9
+and 0xA are not.  On a system with a 20-bit mask each bit represents 5%
+of the capacity of the cache. You could partition the cache into four
+equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000.
+
+
+L3 details (code and data prioritization disabled)
+--------------------------------------------------
+With CDP disabled the L3 schemata format is:
+
+	L3:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L3 details (CDP enabled via mount option to resctrl)
+----------------------------------------------------
+When CDP is enabled L3 control is split into two separate resources
+so you can specify independent masks for code and data like this:
+
+	L3data:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+	L3code:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L2 details
+----------
+L2 cache does not support code and data prioritization, so the
+schemata format is always:
+
+	L2:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+Example 1
+---------
+On a two socket machine (one L3 cache per socket) with just four bits
+for cache bit masks
+
+# mount -t resctrl resctrl /sys/fs/resctrl
+# cd /sys/fs/resctrl
+# mkdir p0 p1
+# echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata
+# echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata
+
+The default resource group is unmodified, so we have access to all parts
+of all caches (its schemata file reads "L3:0=f;1=f").
+
+Tasks that are under the control of group "p0" may only allocate from the
+"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
+Tasks in group "p1" use the "lower" 50% of cache on both sockets.
+
+Example 2
+---------
+Again two sockets, but this time with a more realistic 20-bit mask.
+
+Two real time tasks pid=1234 running on processor 0 and pid=5678 running on
+processor 1 on socket 0 on a 2-socket and dual core machine. To avoid noisy
+neighbors, each of the two real-time tasks exclusively occupies one quarter
+of L3 cache on socket 0.
+
+# mount -t resctrl resctrl /sys/fs/resctrl
+# cd /sys/fs/resctrl
+
+First we reset the schemata for the default group so that the "upper"
+50% of the L3 cache on socket 0 cannot be used by ordinary tasks:
+
+# echo "L3:0=3ff;1=fffff" > schemata
+
+Next we make a resource group for our first real time task and give
+it access to the "top" 25% of the cache on socket 0.
+
+# mkdir p0
+# echo "L3:0=f8000;1=fffff" > p0/schemata
+
+Finally we move our first real time task into this resource group. We
+also use taskset(1) to ensure the task always runs on a dedicated CPU
+on socket 0. Most uses of resource groups will also constrain which
+processors tasks run on.
+
+# echo 1234 > p0/tasks
+# taskset -cp 1 1234
+
+Ditto for the second real time task (with the remaining 25% of cache):
+
+# mkdir p1
+# echo "L3:0=7c00;1=fffff" > p1/schemata
+# echo 5678 > p1/tasks
+# taskset -cp 2 5678
+
+Example 3
+---------
+
+A single socket system which has real-time tasks running on core 4-7 and
+non real-time workload assigned to core 0-3. The real-time tasks share text
+and data, so a per task association is not required and due to interaction
+with the kernel it's desired that the kernel on these cores shares L3 with
+the tasks.
+
+# mount -t resctrl resctrl /sys/fs/resctrl
+# cd /sys/fs/resctrl
+
+First we reset the schemata for the default group so that the "upper"
+50% of the L3 cache on socket 0 cannot be used by ordinary tasks:
+
+# echo "L3:0=3ff" > schemata
+
+Next we make a resource group for our real time cores and give
+it access to the "top" 50% of the cache on socket 0.
+
+# mkdir p0
+# echo "L3:0=ffc00;" > p0/schemata
+
+Finally we move core 4-7 over to the new group and make sure that the
+kernel and the tasks running there get 50% of the cache.
+
+# echo C0 > p0/cpus
author
#3 lore raw

PATCH v6 2/10 x86/intel_rdt: Build structures for each resource based on cache topology

In reply to Fenghua Yu

From: Tony Luck <[email protected]>

We use the cpu hotplug notifier to catch each cpu in turn and look at its cache topology w.r.t each of the resource groups. As we discover new resources, we initialize the bitmask array for each to the default (full access) value.

---
 arch/x86/include/asm/intel_rdt.h |  35 ++++++++
 arch/x86/kernel/cpu/intel_rdt.c  | 189 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 224 insertions(+)
arch/x86/include/asm/intel_rdt.h +35 -0
index 9780409..c0d0a6e 100644
@@ -39,6 +39,34 @@ struct rdt_resource {
 	int			cbm_idx_offset;
 };
 
+/**
+ * struct rdt_domain - group of cpus sharing an RDT resource
+ * @list:	all instances of this resource
+ * @id:		unique id for this instance
+ * @cpu_mask:	which cpus share this resource
+ * @cbm:	array of cache bit masks (indexed by CLOSID)
+ */
+struct rdt_domain {
+	struct list_head	list;
+	int			id;
+	struct cpumask		cpu_mask;
+	u32			*cbm;
+};
+
+/**
+ * struct msr_param - set a range of MSRs from a domain
+ * @res:       The resource to use
+ * @low:       Beginning index from base MSR
+ * @high:      End index
+ */
+struct msr_param {
+	struct rdt_resource	*res;
+	int			low;
+	int			high;
+};
+
+extern struct mutex rdtgroup_mutex;
+
 extern struct rdt_resource rdt_resources_all[];
 
 enum {
@@ -56,6 +84,11 @@ enum {
 	     r++) 							      \
 		if (r->capable)
 
+#define for_each_enabled_rdt_resource(r)				      \
+	for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
+	     r++)							      \
+		if (r->enabled)
+
 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
 union cpuid_0x10_1_eax {
 	struct {
@@ -71,4 +104,6 @@ union cpuid_0x10_1_edx {
 	} split;
 	unsigned int full;
 };
+
+void rdt_cbm_update(void *arg);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt.c +189 -0

219 lines not on this page · raw message

Signature · 1 line
2.5.0
#4 lore raw

[tip:x86/cache] x86/intel_rdt: Build structures for each resource based on cache topology

x86/intel_rdt: Build structures for each resource based on cache topology
Commit-ID:  2264d9c74dda1b6835ab7858204073547457dfd0
Gitweb:     http://git.kernel.org/tip/2264d9c74dda1b6835ab7858204073547457dfd0
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:41 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:13 -0600

x86/intel_rdt: Build structures for each resource based on cache topology

We use the cpu hotplug notifier to catch each cpu in turn and look at its cache topology w.r.t each of the resource groups. As we discover new resources, we initialize the bitmask array for each to the default (full access) value.

Cc "Ravi V Shankar" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h |  35 ++++++++
 arch/x86/kernel/cpu/intel_rdt.c  | 189 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 224 insertions(+)
arch/x86/include/asm/intel_rdt.h +35 -0
index 9780409..c0d0a6e 100644
@@ -39,6 +39,34 @@ struct rdt_resource {
 	int			cbm_idx_offset;
 };
 
+/**
+ * struct rdt_domain - group of cpus sharing an RDT resource
+ * @list:	all instances of this resource
+ * @id:		unique id for this instance
+ * @cpu_mask:	which cpus share this resource
+ * @cbm:	array of cache bit masks (indexed by CLOSID)
+ */
+struct rdt_domain {
+	struct list_head	list;
+	int			id;
+	struct cpumask		cpu_mask;
+	u32			*cbm;
+};
+
+/**
+ * struct msr_param - set a range of MSRs from a domain
+ * @res:       The resource to use
+ * @low:       Beginning index from base MSR
+ * @high:      End index
+ */
+struct msr_param {
+	struct rdt_resource	*res;
+	int			low;
+	int			high;
+};
+
+extern struct mutex rdtgroup_mutex;
+
 extern struct rdt_resource rdt_resources_all[];
 
 enum {
@@ -56,6 +84,11 @@ enum {
 	     r++) 							      \
 		if (r->capable)
 
+#define for_each_enabled_rdt_resource(r)				      \
+	for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
+	     r++)							      \
+		if (r->enabled)
+
 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
 union cpuid_0x10_1_eax {
 	struct {
@@ -71,4 +104,6 @@ union cpuid_0x10_1_edx {
 	} split;
 	unsigned int full;
 };
+
+void rdt_cbm_update(void *arg);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt.c +189 -0

219 lines not on this page · raw message

author
#5 lore raw

PATCH v6 3/10 x86/intel_rdt: Add basic resctrl filesystem support

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

Use kernfs as basis for our user interface filesystem. This patch supports mount/umount, and one mount parameter "cdp" to enable code/data prioritization (though all we do at this point is ensure that the system can support CDP). The file system is not populated yet in this patch.

---
 arch/x86/include/asm/intel_rdt.h         |  24 +++
 arch/x86/kernel/cpu/Makefile             |   2 +-
 arch/x86/kernel/cpu/intel_rdt.c          |   8 +-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 268 +++++++++++++++++++++++++++++++
 include/uapi/linux/magic.h               |   1 +
 5 files changed, 301 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
arch/x86/include/asm/intel_rdt.h +24 -0
index c0d0a6e..8e1d002 100644
@@ -1,10 +1,30 @@
 #ifndef _ASM_X86_INTEL_RDT_H
 #define _ASM_X86_INTEL_RDT_H
 
+#include <linux/jump_label.h>
+
+#define IA32_L3_QOS_CFG		0xc81
 #define IA32_L3_CBM_BASE	0xc90
 #define IA32_L2_CBM_BASE	0xd10
 
 /**
+ * struct rdtgroup - store rdtgroup's data in resctrl file system.
+ * @kn:				kernfs node
+ * @rdtgroup_list:		linked list for all rdtgroups
+ * @closid:			closid for this rdtgroup
+ */
+struct rdtgroup {
+	struct kernfs_node	*kn;
+	struct list_head	rdtgroup_list;
+	int			closid;
+};
+
+/* List of all resource groups */
+extern struct list_head rdt_all_groups;
+
+int __init rdtgroup_init(void);
+
+/**
  * struct rdt_resource - attributes of an RDT resource
  * @enabled:			Is this feature enabled on this machine
  * @capable:			Is this feature available on this machine
@@ -68,6 +88,10 @@ struct msr_param {
 extern struct mutex rdtgroup_mutex;
 
 extern struct rdt_resource rdt_resources_all[];
+extern struct rdtgroup rdtgroup_default;
+DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
+
+int __init rdtgroup_init(void);
 
 enum {
 	RDT_RESOURCE_L3,
arch/x86/kernel/cpu/Makefile +1 -1
index cf4bfd0..b4334e8 100644
@@ -34,7 +34,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o
+obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
arch/x86/kernel/cpu/intel_rdt.c +7 -1
index 6b3fd78..63a0045 100644
@@ -361,7 +361,7 @@ static int intel_rdt_offline_cpu(unsigned int cpu)
 static int __init intel_rdt_late_init(void)
 {
 	struct rdt_resource *r;
-	int state;
+	int state, ret;
 
 	if (!get_rdt_resources())
 		return -ENODEV;
@@ -372,6 +372,12 @@ static int __init intel_rdt_late_init(void)
 	if (state < 0)
 		return state;
 
+	ret = rdtgroup_init();
+	if (ret) {
+		cpuhp_remove_state(state);
+		return ret;
+	}
+
 	for_each_capable_rdt_resource(r)
 		pr_info("Intel RDT %s allocation detected\n", r->name);
 
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +268 -0

268 lines not on this page · raw message

include/uapi/linux/magic.h +1 -0
index 9bd5594..e230af2 100644
@@ -57,6 +57,7 @@
 #define CGROUP_SUPER_MAGIC	0x27e0eb
 #define CGROUP2_SUPER_MAGIC	0x63677270
 
+#define RDTGROUP_SUPER_MAGIC	0x7655821
 
 #define STACK_END_MAGIC		0x57AC6E9D
 
Signature · 1 line
2.5.0
#6 lore raw

Re: [PATCH v6 03/10] x86/intel_rdt: Add basic resctrl filesystem support

Quoted 14 lines · Fenghua Yu
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +14 -0
+static void l3_qos_cfg_update(void *arg)
+{
+	bool *enable = arg;
+
+	wrmsrl(IA32_L3_QOS_CFG, *enable);
+}
+
+static int set_l3_qos_cfg(struct rdt_resource *r, bool enable)
+{
+	cpumask_var_t cpu_mask;
+	struct rdt_domain *d;
+	int cpu;
+
+	if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))

arch/x86/kernel/cpu/intel_rdt_rdtgroup.c line 60

Quoted 10 lines
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +10 -0
+		return -ENOMEM;
+
+	list_for_each_entry(d, &r->domains, list) {
+		/* Pick one CPU from each domain instance to update MSR */
+		cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
+	}
+	cpu = get_cpu();
+	/* Update QOS_CFG MSR on this cpu if it's in cpu_mask. */
+	if (cpumask_test_cpu(cpu, cpu_mask))
+		l3_qos_cfg_update(r);

I made this &enable .....

Quoted 6 lines
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +6 -0
+	/* Update QOS_CFG MSR on all other cpus in cpu_mask. */
+	smp_call_function_many(cpu_mask, l3_qos_cfg_update, &enable, 1);
+	put_cpu();
+	if (rdt_resources_all[RDT_RESOURCE_L3DATA].enabled &&
+	    rdt_resources_all[RDT_RESOURCE_L3CODE].enabled) {
+		ret = set_l3_qos_cfg(&rdt_resources_all[RDT_RESOURCE_L3], true);

arch/x86/kernel/cpu/intel_rdt_rdtgroup.c line 136

Quoted 10 lines
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +10 -0
+		if (ret) {
+			dentry = ERR_PTR(ret);
+			goto out;
+		}
+	}
+
+	dentry = kernfs_mount(fs_type, flags, rdt_root,
+			      RDTGROUP_SUPER_MAGIC, NULL);
+	if (IS_ERR(dentry))
+		goto out;

This leaks a potentially enabled cdp. So if you mount again later w/o cdp the machine will still be in cdp enabled mode. I fixed that up with proper error handling. Please verify the changes carefuly.

Thanks,

tglx

#7 lore raw

[tip:x86/cache] x86/intel_rdt: Add basic resctrl filesystem support

In reply to Fenghua Yu
x86/intel_rdt: Add basic resctrl filesystem support
Commit-ID:  5ff193fbde20df5d80fec367cea3e7856c057320
Gitweb:     http://git.kernel.org/tip/5ff193fbde20df5d80fec367cea3e7856c057320
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:42 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:14 -0600

x86/intel_rdt: Add basic resctrl filesystem support

Use kernfs as basis for our user interface filesystem. This patch supports mount/umount, and one mount parameter "cdp" to enable code/data prioritization (though all we do at this point is ensure that the system can support CDP). The file system is not populated yet in this patch.

[ tglx: Fixed up a few nits and added cdp handling in case of error ]

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         |  26 +++
 arch/x86/kernel/cpu/Makefile             |   2 +-
 arch/x86/kernel/cpu/intel_rdt.c          |   8 +-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 271 +++++++++++++++++++++++++++++++
 include/uapi/linux/magic.h               |   1 +
 5 files changed, 306 insertions(+), 2 deletions(-)
arch/x86/include/asm/intel_rdt.h +26 -0
index c0d0a6e..09d00e6 100644
@@ -1,9 +1,31 @@
 #ifndef _ASM_X86_INTEL_RDT_H
 #define _ASM_X86_INTEL_RDT_H
 
+#include <linux/jump_label.h>
+
+#define IA32_L3_QOS_CFG		0xc81
 #define IA32_L3_CBM_BASE	0xc90
 #define IA32_L2_CBM_BASE	0xd10
 
+#define L3_QOS_CDP_ENABLE	0x01ULL
+
+/**
+ * struct rdtgroup - store rdtgroup's data in resctrl file system.
+ * @kn:				kernfs node
+ * @rdtgroup_list:		linked list for all rdtgroups
+ * @closid:			closid for this rdtgroup
+ */
+struct rdtgroup {
+	struct kernfs_node	*kn;
+	struct list_head	rdtgroup_list;
+	int			closid;
+};
+
+/* List of all resource groups */
+extern struct list_head rdt_all_groups;
+
+int __init rdtgroup_init(void);
+
 /**
  * struct rdt_resource - attributes of an RDT resource
  * @enabled:			Is this feature enabled on this machine
@@ -68,6 +90,10 @@ struct msr_param {
 extern struct mutex rdtgroup_mutex;
 
 extern struct rdt_resource rdt_resources_all[];
+extern struct rdtgroup rdtgroup_default;
+DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
+
+int __init rdtgroup_init(void);
 
 enum {
 	RDT_RESOURCE_L3,
arch/x86/kernel/cpu/Makefile +1 -1
index cf4bfd0..b4334e8 100644
@@ -34,7 +34,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o
+obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
arch/x86/kernel/cpu/intel_rdt.c +7 -1
index 3d4b397..9d95414 100644
@@ -361,7 +361,7 @@ static int intel_rdt_offline_cpu(unsigned int cpu)
 static int __init intel_rdt_late_init(void)
 {
 	struct rdt_resource *r;
-	int state;
+	int state, ret;
 
 	if (!get_rdt_resources())
 		return -ENODEV;
@@ -372,6 +372,12 @@ static int __init intel_rdt_late_init(void)
 	if (state < 0)
 		return state;
 
+	ret = rdtgroup_init();
+	if (ret) {
+		cpuhp_remove_state(state);
+		return ret;
+	}
+
 	for_each_capable_rdt_resource(r)
 		pr_info("Intel RDT %s allocation detected\n", r->name);
 
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file +271 -0

271 lines not on this page · raw message

include/uapi/linux/magic.h +1 -0
index 9bd5594..e230af2 100644
@@ -57,6 +57,7 @@
 #define CGROUP_SUPER_MAGIC	0x27e0eb
 #define CGROUP2_SUPER_MAGIC	0x63677270
 
+#define RDTGROUP_SUPER_MAGIC	0x7655821
 
 #define STACK_END_MAGIC		0x57AC6E9D
 
author
#8 lore raw

PATCH v6 4/10 x86/intel_rdt: Add "info" files to resctrl file system

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

For the convenience of applications we make the decoded values of some of the CPUID values available in read-only (0444) files.

---
 arch/x86/include/asm/intel_rdt.h         |  24 ++++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 185 +++++++++++++++++++++++++++++++
 2 files changed, 209 insertions(+)
arch/x86/include/asm/intel_rdt.h +24 -0
index 8e1d002..39ed561 100644
@@ -25,6 +25,30 @@ extern struct list_head rdt_all_groups;
 int __init rdtgroup_init(void);
 
 /**
+ * struct rftype - describe each file in the resctrl file system
+ * @name: file name
+ * @mode: access mode
+ * @kf_ops: operations
+ * @seq_show: show content of the file
+ * @write: write to the file
+ */
+struct rftype {
+	char			*name;
+	umode_t			mode;
+	struct kernfs_ops	*kf_ops;
+
+	int (*seq_show)(struct kernfs_open_file *of,
+			struct seq_file *sf, void *v);
+	/*
+	 * write() is the generic write callback which maps directly to
+	 * kernfs write operation and overrides all other operations.
+	 * Maximum write size is determined by ->max_write_len.
+	 */
+	ssize_t (*write)(struct kernfs_open_file *of,
+			 char *buf, size_t nbytes, loff_t off);
+};
+
+/**
  * struct rdt_resource - attributes of an RDT resource
  * @enabled:			Is this feature enabled on this machine
  * @capable:			Is this feature available on this machine
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +185 -0

215 lines not on this page · raw message

Signature · 1 line
2.5.0
#9 lore raw

[tip:x86/cache] x86/intel_rdt: Add "info" files to resctrl file system

x86/intel_rdt: Add "info" files to resctrl file system
Commit-ID:  4e978d06dedb8207b298a5a8a49fce4b2ab80d12
Gitweb:     http://git.kernel.org/tip/4e978d06dedb8207b298a5a8a49fce4b2ab80d12
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:43 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:14 -0600

x86/intel_rdt: Add "info" files to resctrl file system

For the convenience of applications we make the decoded values of some of the CPUID values available in read-only (0444) files.

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         |  24 ++++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 185 +++++++++++++++++++++++++++++++
 2 files changed, 209 insertions(+)
arch/x86/include/asm/intel_rdt.h +24 -0
index 09d00e6..5b7b3f6 100644
@@ -27,6 +27,30 @@ extern struct list_head rdt_all_groups;
 int __init rdtgroup_init(void);
 
 /**
+ * struct rftype - describe each file in the resctrl file system
+ * @name: file name
+ * @mode: access mode
+ * @kf_ops: operations
+ * @seq_show: show content of the file
+ * @write: write to the file
+ */
+struct rftype {
+	char			*name;
+	umode_t			mode;
+	struct kernfs_ops	*kf_ops;
+
+	int (*seq_show)(struct kernfs_open_file *of,
+			struct seq_file *sf, void *v);
+	/*
+	 * write() is the generic write callback which maps directly to
+	 * kernfs write operation and overrides all other operations.
+	 * Maximum write size is determined by ->max_write_len.
+	 */
+	ssize_t (*write)(struct kernfs_open_file *of,
+			 char *buf, size_t nbytes, loff_t off);
+};
+
+/**
  * struct rdt_resource - attributes of an RDT resource
  * @enabled:			Is this feature enabled on this machine
  * @capable:			Is this feature available on this machine
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +185 -0

215 lines not on this page · raw message

author
#10 lore raw

PATCH v6 5/10 x86/intel_rdt: Add mkdir to resctrl file system

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

Resource control groups are represented as directories in the resctrl file system. The root directory describes the default resources available to tasks that have not been assigned specific resources. Other directories can be created at the root level to make new resource groups. It is not permitted to make directories within other directories.

Hardware uses a CLOSID (Class of service ID) to determine which resource limits are currently in effect. The exact number available is enumerated by CPUID leaf 0x10, but on current implementations it is a small number. We implement a simple bitmask allocator for CLOSIDs.

Each resource control group uses one CLOSID, which limits the total number of directories that can be created.

Resource groups can be removed using rmdir.

---
 arch/x86/include/asm/intel_rdt.h         |   9 ++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 231 +++++++++++++++++++++++++++++++
 2 files changed, 240 insertions(+)
arch/x86/include/asm/intel_rdt.h +9 -0
index 39ed561..a6c7d94 100644
@@ -12,13 +12,20 @@
  * @kn:				kernfs node
  * @rdtgroup_list:		linked list for all rdtgroups
  * @closid:			closid for this rdtgroup
+ * @flags:			status bits
+ * @waitcount:			how many cpus expect to find this
  */
 struct rdtgroup {
 	struct kernfs_node	*kn;
 	struct list_head	rdtgroup_list;
 	int			closid;
+	int			flags;
+	atomic_t		waitcount;
 };
 
+/* rdtgroup.flags */
+#define	RDT_DELETED		1
+
 /* List of all resource groups */
 extern struct list_head rdt_all_groups;
 
@@ -154,4 +161,6 @@ union cpuid_0x10_1_edx {
 };
 
 void rdt_cbm_update(void *arg);
+struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
+void rdtgroup_kn_unlock(struct kernfs_node *kn);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +231 -0

276 lines not on this page · raw message

Signature · 1 line
2.5.0
#11 lore raw

[tip:x86/cache] x86/intel_rdt: Add mkdir to resctrl file system

x86/intel_rdt: Add mkdir to resctrl file system
Commit-ID:  60cf5e101fd4441ab112a81e88726efb6fd7542c
Gitweb:     http://git.kernel.org/tip/60cf5e101fd4441ab112a81e88726efb6fd7542c
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:44 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:14 -0600

x86/intel_rdt: Add mkdir to resctrl file system

Resource control groups are represented as directories in the resctrl file system. The root directory describes the default resources available to tasks that have not been assigned specific resources. Other directories can be created at the root level to make new resource groups. It is not permitted to make directories within other directories.

Hardware uses a CLOSID (Class of service ID) to determine which resource limits are currently in effect. The exact number available is enumerated by CPUID leaf 0x10, but on current implementations it is a small number. We implement a simple bitmask allocator for CLOSIDs.

Each resource control group uses one CLOSID, which limits the total number of directories that can be created.

Resource groups can be removed using rmdir.

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         |   9 ++
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 231 +++++++++++++++++++++++++++++++
 2 files changed, 240 insertions(+)
arch/x86/include/asm/intel_rdt.h +9 -0
index 5b7b3f6..8032ace 100644
@@ -14,13 +14,20 @@
  * @kn:				kernfs node
  * @rdtgroup_list:		linked list for all rdtgroups
  * @closid:			closid for this rdtgroup
+ * @flags:			status bits
+ * @waitcount:			how many cpus expect to find this
  */
 struct rdtgroup {
 	struct kernfs_node	*kn;
 	struct list_head	rdtgroup_list;
 	int			closid;
+	int			flags;
+	atomic_t		waitcount;
 };
 
+/* rdtgroup.flags */
+#define	RDT_DELETED		1
+
 /* List of all resource groups */
 extern struct list_head rdt_all_groups;
 
@@ -156,4 +163,6 @@ union cpuid_0x10_1_edx {
 };
 
 void rdt_cbm_update(void *arg);
+struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
+void rdtgroup_kn_unlock(struct kernfs_node *kn);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +231 -0

276 lines not on this page · raw message

author
#12 lore raw

PATCH v6 6/10 x86/intel_rdt: Add cpus file

In reply to Fenghua Yu

From: Tony Luck <[email protected]>

Now we populate each directory with a read/write (mode 0644) file named "cpus". This is used to over-ride the resources available to processes in the default resource group when running on specific CPUs. Each "cpus" file reads as a cpumask showing which CPUs belong to this resource group. Initially all online CPUs are assigned to the default group. They can be added to other groups by writing a cpumask to the "cpus" file in the directory for the resource group (which will remove them from the previous group to which they were assigned). CPU online/offline operations will delete CPUs that go offline from whatever group they are in and add new CPUs to the default group.

If there are CPUs assigned to a group when the directory is removed, they are returned to the default group.

---
 arch/x86/include/asm/intel_rdt.h         |   5 ++
 arch/x86/kernel/cpu/intel_rdt.c          |  23 +++++-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 131 ++++++++++++++++++++++++++++++-
 3 files changed, 154 insertions(+), 5 deletions(-)
arch/x86/include/asm/intel_rdt.h +5 -0
index a6c7d94..3e8450f 100644
@@ -12,13 +12,16 @@
  * @kn:				kernfs node
  * @rdtgroup_list:		linked list for all rdtgroups
  * @closid:			closid for this rdtgroup
+ * @cpu_mask:			CPUs assigned to this rdtgroup
  * @flags:			status bits
  * @waitcount:			how many cpus expect to find this
+ *				group when they acquire rdtgroup_mutex
  */
 struct rdtgroup {
 	struct kernfs_node	*kn;
 	struct list_head	rdtgroup_list;
 	int			closid;
+	struct cpumask		cpu_mask;
 	int			flags;
 	atomic_t		waitcount;
 };
@@ -160,6 +163,8 @@ union cpuid_0x10_1_edx {
 	unsigned int full;
 };
 
+DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
+
 void rdt_cbm_update(void *arg);
 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
 void rdtgroup_kn_unlock(struct kernfs_node *kn);
arch/x86/kernel/cpu/intel_rdt.c +20 -3
index 63a0045..9e1f901 100644
@@ -36,6 +36,8 @@
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
 
+DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid);
+
 #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].domains)
 
 struct rdt_resource rdt_resources_all[] = {
@@ -331,16 +333,25 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
 	}
 }
 
-static int intel_rdt_online_cpu(unsigned int cpu)
+static void clear_closid(int cpu)
 {
 	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+
+	per_cpu(cpu_closid, cpu) = 0;
+	state->closid = 0;
+	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0);
+}
+
+static int intel_rdt_online_cpu(unsigned int cpu)
+{
 	struct rdt_resource *r;
 
 	mutex_lock(&rdtgroup_mutex);
 	for_each_capable_rdt_resource(r)
 		domain_add_cpu(cpu, r);
-	state->closid = 0;
-	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0);
+	/* The cpu is set in default rdtgroup after online. */
+	cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+	clear_closid(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 
 	return 0;
@@ -348,11 +359,17 @@ static int intel_rdt_online_cpu(unsigned int cpu)
 
 static int intel_rdt_offline_cpu(unsigned int cpu)
 {
+	struct rdtgroup *rdtgrp;
 	struct rdt_resource *r;
 
 	mutex_lock(&rdtgroup_mutex);
 	for_each_capable_rdt_resource(r)
 		domain_remove_cpu(cpu, r);
+	list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) {
+		if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask))
+			break;
+	}
+	clear_closid(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 
 	return 0;
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +129 -2

178 lines not on this page · raw message

Signature · 1 line
2.5.0
#13 lore raw

[tip:x86/cache] x86/intel_rdt: Add cpus file

x86/intel_rdt: Add cpus file
Commit-ID:  12e0110c11a460b890ed7e1071198ced732152c9
Gitweb:     http://git.kernel.org/tip/12e0110c11a460b890ed7e1071198ced732152c9
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:45 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:15 -0600

x86/intel_rdt: Add cpus file

Now we populate each directory with a read/write (mode 0644) file named "cpus". This is used to over-ride the resources available to processes in the default resource group when running on specific CPUs. Each "cpus" file reads as a cpumask showing which CPUs belong to this resource group. Initially all online CPUs are assigned to the default group. They can be added to other groups by writing a cpumask to the "cpus" file in the directory for the resource group (which will remove them from the previous group to which they were assigned). CPU online/offline operations will delete CPUs that go offline from whatever group they are in and add new CPUs to the default group.

If there are CPUs assigned to a group when the directory is removed, they are returned to the default group.

Cc "Ravi V Shankar" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         |   5 ++
 arch/x86/kernel/cpu/intel_rdt.c          |  23 +++++-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 131 ++++++++++++++++++++++++++++++-
 3 files changed, 154 insertions(+), 5 deletions(-)
arch/x86/include/asm/intel_rdt.h +5 -0
index 8032ace..a0dd3e9 100644
@@ -14,13 +14,16 @@
  * @kn:				kernfs node
  * @rdtgroup_list:		linked list for all rdtgroups
  * @closid:			closid for this rdtgroup
+ * @cpu_mask:			CPUs assigned to this rdtgroup
  * @flags:			status bits
  * @waitcount:			how many cpus expect to find this
+ *				group when they acquire rdtgroup_mutex
  */
 struct rdtgroup {
 	struct kernfs_node	*kn;
 	struct list_head	rdtgroup_list;
 	int			closid;
+	struct cpumask		cpu_mask;
 	int			flags;
 	atomic_t		waitcount;
 };
@@ -162,6 +165,8 @@ union cpuid_0x10_1_edx {
 	unsigned int full;
 };
 
+DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
+
 void rdt_cbm_update(void *arg);
 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
 void rdtgroup_kn_unlock(struct kernfs_node *kn);
arch/x86/kernel/cpu/intel_rdt.c +20 -3
index 9d95414..40094ae 100644
@@ -36,6 +36,8 @@
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
 
+DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid);
+
 #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].domains)
 
 struct rdt_resource rdt_resources_all[] = {
@@ -331,16 +333,25 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
 	}
 }
 
-static int intel_rdt_online_cpu(unsigned int cpu)
+static void clear_closid(int cpu)
 {
 	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+
+	per_cpu(cpu_closid, cpu) = 0;
+	state->closid = 0;
+	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0);
+}
+
+static int intel_rdt_online_cpu(unsigned int cpu)
+{
 	struct rdt_resource *r;
 
 	mutex_lock(&rdtgroup_mutex);
 	for_each_capable_rdt_resource(r)
 		domain_add_cpu(cpu, r);
-	state->closid = 0;
-	wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0);
+	/* The cpu is set in default rdtgroup after online. */
+	cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+	clear_closid(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 
 	return 0;
@@ -348,11 +359,17 @@ static int intel_rdt_online_cpu(unsigned int cpu)
 
 static int intel_rdt_offline_cpu(unsigned int cpu)
 {
+	struct rdtgroup *rdtgrp;
 	struct rdt_resource *r;
 
 	mutex_lock(&rdtgroup_mutex);
 	for_each_capable_rdt_resource(r)
 		domain_remove_cpu(cpu, r);
+	list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) {
+		if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask))
+			break;
+	}
+	clear_closid(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 
 	return 0;
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +129 -2

178 lines not on this page · raw message

author
#14 lore raw

PATCH v6 7/10 x86/intel_rdt: Add tasks files

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

The root directory all subdirectories are automatically populated with a read/write (mode 0644) file named "tasks". When read it will show all the task IDs assigned to the resource group. Tasks can be added (one at a time) to a group by writing the task ID to the file. E.g.

Membership in a resource group is indicated by a new field in the task_struct "int closid" which holds the CLOSID for each task. The default resource group uses CLOSID=0 which means that all existing tasks when the resctrl file system is mounted belong to the default group.

A resource group cannot be removed while there are tasks assigned to it.

---
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 180 +++++++++++++++++++++++++++++++
 include/linux/sched.h                    |   3 +
 2 files changed, 183 insertions(+)
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +180 -0
index 931b406..50fa946 100644
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
+#include <linux/task_work.h>
 
 #include <uapi/linux/magic.h>
 
@@ -267,6 +268,162 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of,
 	return ret ?: nbytes;
 }
 
+struct task_move_callback {
+	struct callback_head	work;
+	struct rdtgroup		*rdtgrp;
+};
+
+static void move_myself(struct callback_head *head)
+{
+	struct task_move_callback *callback;
+	struct rdtgroup *rdtgrp;
+
+	callback = container_of(head, struct task_move_callback, work);
+	rdtgrp = callback->rdtgrp;
+
+	/*
+	 * If resource group was deleted before this task work callback
+	 * was invoked, then assign the task to root group and free the
+	 * resource group.
+	 */
+	if (atomic_dec_and_test(&rdtgrp->waitcount) &&
+	    (rdtgrp->flags & RDT_DELETED)) {
+		current->closid = 0;
+		kfree(rdtgrp);
+	}
+
+	kfree(callback);
+}
+
+static int __rdtgroup_move_task(struct task_struct *tsk,
+				struct rdtgroup *rdtgrp)
+{
+	struct task_move_callback *callback;
+	int ret;
+
+	callback = kzalloc(sizeof(*callback), GFP_KERNEL);
+	if (!callback)
+		return -ENOMEM;
+	callback->work.func = move_myself;
+	callback->rdtgrp = rdtgrp;
+
+	/*
+	 * Take a refcount, so rdtgrp cannot be freed before the
+	 * callback has been invoked.
+	 */
+	atomic_inc(&rdtgrp->waitcount);
+	ret = task_work_add(tsk, &callback->work, true);
+	if (ret) {
+		/*
+		 * Task is exiting. Drop the refcount and free the callback.
+		 * No need to check the refcount as the group cannot be
+		 * deleted before the write function unlocks rdtgroup_mutex.
+		 */
+		atomic_dec(&rdtgrp->waitcount);
+		kfree(callback);
+	} else {
+		tsk->closid = rdtgrp->closid;
+	}
+	return ret;
+}
+
+static int rdtgroup_task_write_permission(struct task_struct *task,
+					  struct kernfs_open_file *of)
+{
+	const struct cred *tcred = get_task_cred(task);
+	const struct cred *cred = current_cred();
+	int ret = 0;
+
+	/*
+	 * Even if we're attaching all tasks in the thread group, we only
+	 * need to check permissions on one of them.
+	 */
+	if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) &&
+	    !uid_eq(cred->euid, tcred->uid) &&
+	    !uid_eq(cred->euid, tcred->suid))
+		ret = -EPERM;
+
+	put_cred(tcred);
+	return ret;
+}
+
+static int rdtgroup_move_task(pid_t pid, struct rdtgroup *rdtgrp,
+			      struct kernfs_open_file *of)
+{
+	struct task_struct *tsk;
+	int ret;
+
+	rcu_read_lock();
+	if (pid) {
+		tsk = find_task_by_vpid(pid);
+		if (!tsk) {
+			rcu_read_unlock();
+			return -ESRCH;
+		}
+	} else {
+		tsk = current;
+	}
+
+	get_task_struct(tsk);
+	rcu_read_unlock();
+
+	ret = rdtgroup_task_write_permission(tsk, of);
+	if (!ret)
+		ret = __rdtgroup_move_task(tsk, rdtgrp);
+
+	put_task_struct(tsk);
+	return ret;
+}
+
+static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
+				    char *buf, size_t nbytes, loff_t off)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+	pid_t pid;
+
+	if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0)
+		return -EINVAL;
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+
+	if (rdtgrp)
+		ret = rdtgroup_move_task(pid, rdtgrp, of);
+	else
+		ret = -ENOENT;
+
+	rdtgroup_kn_unlock(of->kn);
+
+	return ret ?: nbytes;
+}
+
+static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
+{
+	struct task_struct *p, *t;
+
+	rcu_read_lock();
+	for_each_process_thread(p, t) {
+		if (t->closid == r->closid)
+			seq_printf(s, "%d\n", t->pid);
+	}
+	rcu_read_unlock();
+}
+
+static int rdtgroup_tasks_show(struct kernfs_open_file *of,
+			       struct seq_file *s, void *v)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+	if (rdtgrp)
+		show_rdt_tasks(rdtgrp, s);
+	else
+		ret = -ENOENT;
+	rdtgroup_kn_unlock(of->kn);
+
+	return ret;
+}
+
 /* Files in each rdtgroup */
 static struct rftype rdtgroup_base_files[] = {
 	{
@@ -276,6 +433,13 @@ static struct rftype rdtgroup_base_files[] = {
 		.write		= rdtgroup_cpus_write,
 		.seq_show	= rdtgroup_cpus_show,
 	},
+	{
+		.name		= "tasks",
+		.mode		= 0644,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.write		= rdtgroup_tasks_write,
+		.seq_show	= rdtgroup_tasks_show,
+	},
 };
 
 static int rdt_num_closids_show(struct kernfs_open_file *of,
@@ -582,6 +746,13 @@ static void rdt_reset_pqr_assoc_closid(void *v)
 static void rmdir_all_sub(void)
 {
 	struct rdtgroup *rdtgrp, *tmp;
+	struct task_struct *p, *t;
+
+	/* move all tasks to default resource group */
+	read_lock(&tasklist_lock);
+	for_each_process_thread(p, t)
+		t->closid = 0;
+	read_unlock(&tasklist_lock);
 
 	get_cpu();
 	/* Reset PQR_ASSOC MSR on this cpu. */
@@ -709,6 +880,7 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
 
 static int rdtgroup_rmdir(struct kernfs_node *kn)
 {
+	struct task_struct *p, *t;
 	struct rdtgroup *rdtgrp;
 	int cpu, ret = 0;
 
@@ -718,6 +890,14 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
 		return -ENOENT;
 	}
 
+	/* Give any tasks back to the default group */
+	read_lock(&tasklist_lock);
+	for_each_process_thread(p, t) {
+		if (t->closid == rdtgrp->closid)
+			t->closid = 0;
+	}
+	read_unlock(&tasklist_lock);
+
 	/* Give any CPUs back to the default group */
 	cpumask_or(&rdtgroup_default.cpu_mask,
 		   &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask);
include/linux/sched.h +3 -0
index 348f51b..c8f4152 100644
@@ -1791,6 +1791,9 @@ struct task_struct {
 	/* cg_list protected by css_set_lock and tsk->alloc_lock */
 	struct list_head cg_list;
 #endif
+#ifdef CONFIG_INTEL_RDT_A
+	int closid;
+#endif
 #ifdef CONFIG_FUTEX
 	struct robust_list_head __user *robust_list;
 #ifdef CONFIG_COMPAT
Signature · 1 line
2.5.0
#15 lore raw

[tip:x86/cache] x86/intel_rdt: Add tasks files

x86/intel_rdt: Add tasks files
Commit-ID:  e02737d5b82640497637d18428e2793bb7f02881
Gitweb:     http://git.kernel.org/tip/e02737d5b82640497637d18428e2793bb7f02881
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:46 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:15 -0600

x86/intel_rdt: Add tasks files

The root directory all subdirectories are automatically populated with a read/write (mode 0644) file named "tasks". When read it will show all the task IDs assigned to the resource group. Tasks can be added (one at a time) to a group by writing the task ID to the file. E.g.

Membership in a resource group is indicated by a new field in the task_struct "int closid" which holds the CLOSID for each task. The default resource group uses CLOSID=0 which means that all existing tasks when the resctrl file system is mounted belong to the default group.

If a group is removed, tasks which are members of that group are moved to the default group.

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 180 +++++++++++++++++++++++++++++++
 include/linux/sched.h                    |   3 +
 2 files changed, 183 insertions(+)
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +180 -0
index e05a186..5cc0865 100644
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
+#include <linux/task_work.h>
 
 #include <uapi/linux/magic.h>
 
@@ -267,6 +268,162 @@ unlock:
 	return ret ?: nbytes;
 }
 
+struct task_move_callback {
+	struct callback_head	work;
+	struct rdtgroup		*rdtgrp;
+};
+
+static void move_myself(struct callback_head *head)
+{
+	struct task_move_callback *callback;
+	struct rdtgroup *rdtgrp;
+
+	callback = container_of(head, struct task_move_callback, work);
+	rdtgrp = callback->rdtgrp;
+
+	/*
+	 * If resource group was deleted before this task work callback
+	 * was invoked, then assign the task to root group and free the
+	 * resource group.
+	 */
+	if (atomic_dec_and_test(&rdtgrp->waitcount) &&
+	    (rdtgrp->flags & RDT_DELETED)) {
+		current->closid = 0;
+		kfree(rdtgrp);
+	}
+
+	kfree(callback);
+}
+
+static int __rdtgroup_move_task(struct task_struct *tsk,
+				struct rdtgroup *rdtgrp)
+{
+	struct task_move_callback *callback;
+	int ret;
+
+	callback = kzalloc(sizeof(*callback), GFP_KERNEL);
+	if (!callback)
+		return -ENOMEM;
+	callback->work.func = move_myself;
+	callback->rdtgrp = rdtgrp;
+
+	/*
+	 * Take a refcount, so rdtgrp cannot be freed before the
+	 * callback has been invoked.
+	 */
+	atomic_inc(&rdtgrp->waitcount);
+	ret = task_work_add(tsk, &callback->work, true);
+	if (ret) {
+		/*
+		 * Task is exiting. Drop the refcount and free the callback.
+		 * No need to check the refcount as the group cannot be
+		 * deleted before the write function unlocks rdtgroup_mutex.
+		 */
+		atomic_dec(&rdtgrp->waitcount);
+		kfree(callback);
+	} else {
+		tsk->closid = rdtgrp->closid;
+	}
+	return ret;
+}
+
+static int rdtgroup_task_write_permission(struct task_struct *task,
+					  struct kernfs_open_file *of)
+{
+	const struct cred *tcred = get_task_cred(task);
+	const struct cred *cred = current_cred();
+	int ret = 0;
+
+	/*
+	 * Even if we're attaching all tasks in the thread group, we only
+	 * need to check permissions on one of them.
+	 */
+	if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) &&
+	    !uid_eq(cred->euid, tcred->uid) &&
+	    !uid_eq(cred->euid, tcred->suid))
+		ret = -EPERM;
+
+	put_cred(tcred);
+	return ret;
+}
+
+static int rdtgroup_move_task(pid_t pid, struct rdtgroup *rdtgrp,
+			      struct kernfs_open_file *of)
+{
+	struct task_struct *tsk;
+	int ret;
+
+	rcu_read_lock();
+	if (pid) {
+		tsk = find_task_by_vpid(pid);
+		if (!tsk) {
+			rcu_read_unlock();
+			return -ESRCH;
+		}
+	} else {
+		tsk = current;
+	}
+
+	get_task_struct(tsk);
+	rcu_read_unlock();
+
+	ret = rdtgroup_task_write_permission(tsk, of);
+	if (!ret)
+		ret = __rdtgroup_move_task(tsk, rdtgrp);
+
+	put_task_struct(tsk);
+	return ret;
+}
+
+static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
+				    char *buf, size_t nbytes, loff_t off)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+	pid_t pid;
+
+	if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0)
+		return -EINVAL;
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+
+	if (rdtgrp)
+		ret = rdtgroup_move_task(pid, rdtgrp, of);
+	else
+		ret = -ENOENT;
+
+	rdtgroup_kn_unlock(of->kn);
+
+	return ret ?: nbytes;
+}
+
+static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
+{
+	struct task_struct *p, *t;
+
+	rcu_read_lock();
+	for_each_process_thread(p, t) {
+		if (t->closid == r->closid)
+			seq_printf(s, "%d\n", t->pid);
+	}
+	rcu_read_unlock();
+}
+
+static int rdtgroup_tasks_show(struct kernfs_open_file *of,
+			       struct seq_file *s, void *v)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+	if (rdtgrp)
+		show_rdt_tasks(rdtgrp, s);
+	else
+		ret = -ENOENT;
+	rdtgroup_kn_unlock(of->kn);
+
+	return ret;
+}
+
 /* Files in each rdtgroup */
 static struct rftype rdtgroup_base_files[] = {
 	{
@@ -276,6 +433,13 @@ static struct rftype rdtgroup_base_files[] = {
 		.write		= rdtgroup_cpus_write,
 		.seq_show	= rdtgroup_cpus_show,
 	},
+	{
+		.name		= "tasks",
+		.mode		= 0644,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.write		= rdtgroup_tasks_write,
+		.seq_show	= rdtgroup_tasks_show,
+	},
 };
 
 static int rdt_num_closids_show(struct kernfs_open_file *of,
@@ -592,6 +756,13 @@ static void rdt_reset_pqr_assoc_closid(void *v)
 static void rmdir_all_sub(void)
 {
 	struct rdtgroup *rdtgrp, *tmp;
+	struct task_struct *p, *t;
+
+	/* move all tasks to default resource group */
+	read_lock(&tasklist_lock);
+	for_each_process_thread(p, t)
+		t->closid = 0;
+	read_unlock(&tasklist_lock);
 
 	get_cpu();
 	/* Reset PQR_ASSOC MSR on this cpu. */
@@ -712,6 +883,7 @@ out_unlock:
 
 static int rdtgroup_rmdir(struct kernfs_node *kn)
 {
+	struct task_struct *p, *t;
 	struct rdtgroup *rdtgrp;
 	int cpu, ret = 0;
 
@@ -721,6 +893,14 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
 		return -ENOENT;
 	}
 
+	/* Give any tasks back to the default group */
+	read_lock(&tasklist_lock);
+	for_each_process_thread(p, t) {
+		if (t->closid == rdtgrp->closid)
+			t->closid = 0;
+	}
+	read_unlock(&tasklist_lock);
+
 	/* Give any CPUs back to the default group */
 	cpumask_or(&rdtgroup_default.cpu_mask,
 		   &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask);
include/linux/sched.h +3 -0
index 348f51b..c8f4152 100644
@@ -1791,6 +1791,9 @@ struct task_struct {
 	/* cg_list protected by css_set_lock and tsk->alloc_lock */
 	struct list_head cg_list;
 #endif
+#ifdef CONFIG_INTEL_RDT_A
+	int closid;
+#endif
 #ifdef CONFIG_FUTEX
 	struct robust_list_head __user *robust_list;
 #ifdef CONFIG_COMPAT
author
#16 lore raw

PATCH v6 8/10 x86/intel_rdt: Add schemata file

In reply to Fenghua Yu

From: Tony Luck <[email protected]>

Last of the per resource group files. Also mode 0644. This one shows the resources available to the group. Syntax depends on whether the "cdp" mount option was given. With code/data prioritization disabled it is simply a list of masks for each cache domain. Initial value allows access to all of the L3 cache on all domains. E.g. on a 2 socket Broadwell:

        L3:0=fffff;1=fffff
With CDP enabled, separate masks for data and instructions are provided:
        L3DATA:0=fffff;1=fffff
        L3CODE:0=fffff;1=fffff
---
 arch/x86/include/asm/intel_rdt.h         |   6 +
 arch/x86/kernel/cpu/Makefile             |   2 +-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |   7 +
 arch/x86/kernel/cpu/intel_rdt_schemata.c | 245 +++++++++++++++++++++++++++++++
 4 files changed, 259 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/kernel/cpu/intel_rdt_schemata.c
arch/x86/include/asm/intel_rdt.h +6 -0
index 3e8450f..f847189 100644
@@ -71,6 +71,7 @@ struct rftype {
  * @num_domains:		Number of domains active
  * @msr_base:			Base MSR address for CBMs
  * @tmp_cbms:			Scratch space when updating schemata
+ * @num_tmp_cbms:		Number of CBMs in tmp_cbms
  * @cache_level:		Which cache level defines scope of this domain
  * @cbm_idx_multi:		Multiplier of CBM index
  * @cbm_idx_offset:		Offset of CBM index. CBM index is computed by:
@@ -88,6 +89,7 @@ struct rdt_resource {
 	int			num_domains;
 	int			msr_base;
 	u32			*tmp_cbms;
+	int			num_tmp_cbms;
 	int			cache_level;
 	int			cbm_idx_multi;
 	int			cbm_idx_offset;
@@ -168,4 +170,8 @@ DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
 void rdt_cbm_update(void *arg);
 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
 void rdtgroup_kn_unlock(struct kernfs_node *kn);
+ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
+				char *buf, size_t nbytes, loff_t off);
+int rdtgroup_schemata_show(struct kernfs_open_file *of,
+			   struct seq_file *s, void *v);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/Makefile +1 -1
index b4334e8..c9f8c81 100644
@@ -34,7 +34,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o
+obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_schemata.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +7 -0
index 50fa946..d20be87 100644
@@ -440,6 +440,13 @@ static struct rftype rdtgroup_base_files[] = {
 		.write		= rdtgroup_tasks_write,
 		.seq_show	= rdtgroup_tasks_show,
 	},
+	{
+		.name		= "schemata",
+		.mode		= 0644,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.write		= rdtgroup_schemata_write,
+		.seq_show	= rdtgroup_schemata_show,
+	},
 };
 
 static int rdt_num_closids_show(struct kernfs_open_file *of,
arch/x86/kernel/cpu/intel_rdt_schemata.c new file +245 -0

245 lines not on this page · raw message

Signature · 1 line
2.5.0
#17 lore raw

[tip:x86/cache] x86/intel_rdt: Add schemata file

x86/intel_rdt: Add schemata file
Commit-ID:  60ec2440c63dea88a5ef13e2b2549730a0d75a37
Gitweb:     http://git.kernel.org/tip/60ec2440c63dea88a5ef13e2b2549730a0d75a37
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:47 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:16 -0600

x86/intel_rdt: Add schemata file

Last of the per resource group files. Also mode 0644. This one shows the resources available to the group. Syntax depends on whether the "cdp" mount option was given. With code/data prioritization disabled it is simply a list of masks for each cache domain. Initial value allows access to all of the L3 cache on all domains. E.g. on a 2 socket Broadwell:

        L3:0=fffff;1=fffff
With CDP enabled, separate masks for data and instructions are provided:
        L3DATA:0=fffff;1=fffff
        L3CODE:0=fffff;1=fffff
Cc "Ravi V Shankar" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         |   6 +
 arch/x86/kernel/cpu/Makefile             |   2 +-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |   7 +
 arch/x86/kernel/cpu/intel_rdt_schemata.c | 245 +++++++++++++++++++++++++++++++
 4 files changed, 259 insertions(+), 1 deletion(-)
arch/x86/include/asm/intel_rdt.h +6 -0
index a0dd3e9..2e5eab0 100644
@@ -73,6 +73,7 @@ struct rftype {
  * @num_domains:		Number of domains active
  * @msr_base:			Base MSR address for CBMs
  * @tmp_cbms:			Scratch space when updating schemata
+ * @num_tmp_cbms:		Number of CBMs in tmp_cbms
  * @cache_level:		Which cache level defines scope of this domain
  * @cbm_idx_multi:		Multiplier of CBM index
  * @cbm_idx_offset:		Offset of CBM index. CBM index is computed by:
@@ -90,6 +91,7 @@ struct rdt_resource {
 	int			num_domains;
 	int			msr_base;
 	u32			*tmp_cbms;
+	int			num_tmp_cbms;
 	int			cache_level;
 	int			cbm_idx_multi;
 	int			cbm_idx_offset;
@@ -170,4 +172,8 @@ DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
 void rdt_cbm_update(void *arg);
 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
 void rdtgroup_kn_unlock(struct kernfs_node *kn);
+ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
+				char *buf, size_t nbytes, loff_t off);
+int rdtgroup_schemata_show(struct kernfs_open_file *of,
+			   struct seq_file *s, void *v);
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/Makefile +1 -1
index b4334e8..c9f8c81 100644
@@ -34,7 +34,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o
+obj-$(CONFIG_INTEL_RDT_A)	+= intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_schemata.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +7 -0
index 5cc0865..5c4bab9 100644
@@ -440,6 +440,13 @@ static struct rftype rdtgroup_base_files[] = {
 		.write		= rdtgroup_tasks_write,
 		.seq_show	= rdtgroup_tasks_show,
 	},
+	{
+		.name		= "schemata",
+		.mode		= 0644,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.write		= rdtgroup_schemata_write,
+		.seq_show	= rdtgroup_schemata_show,
+	},
 };
 
 static int rdt_num_closids_show(struct kernfs_open_file *of,
arch/x86/kernel/cpu/intel_rdt_schemata.c new file +245 -0

245 lines not on this page · raw message

author
#18 lore raw

PATCH v6 9/10 x86/intel_rdt: Add scheduler hook

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

Hook the x86 scheduler code to update closid based on whether the current task is assigned to a specific closid or running on a CPU assigned to a specific closid.

---
 arch/x86/include/asm/intel_rdt.h         | 42 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel_rdt.c          |  1 -
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 arch/x86/kernel/process_32.c             |  4 +++
 arch/x86/kernel/process_64.c             |  4 +++
 5 files changed, 53 insertions(+), 1 deletion(-)
arch/x86/include/asm/intel_rdt.h +42 -0
index f847189..100e53c 100644
@@ -1,8 +1,12 @@
 #ifndef _ASM_X86_INTEL_RDT_H
 #define _ASM_X86_INTEL_RDT_H
 
+#ifdef CONFIG_INTEL_RDT_A
+
 #include <linux/jump_label.h>
 
+#include <asm/intel_rdt_common.h>
+
 #define IA32_L3_QOS_CFG		0xc81
 #define IA32_L3_CBM_BASE	0xc90
 #define IA32_L2_CBM_BASE	0xd10
@@ -174,4 +178,42 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 				char *buf, size_t nbytes, loff_t off);
 int rdtgroup_schemata_show(struct kernfs_open_file *of,
 			   struct seq_file *s, void *v);
+
+/*
+ * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR
+ *
+ * Following considerations are made so that this has minimal impact
+ * on scheduler hot path:
+ * - This will stay as no-op unless we are running on an Intel SKU
+ *   which supports resource control and we enable by mounting the
+ *   resctrl file system.
+ * - Caches the per cpu CLOSid values and does the MSR write only
+ *   when a task with a different CLOSid is scheduled in.
+ */
+static inline void intel_rdt_sched_in(void)
+{
+	if (static_branch_likely(&rdt_enable_key)) {
+		struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+		int closid;
+
+		/*
+		 * If this task has a closid assigned, use it.
+		 * Else use the closid assigned to this cpu.
+		 */
+		closid = current->closid;
+		if (closid == 0)
+			closid = this_cpu_read(cpu_closid);
+
+		if (closid != state->closid) {
+			state->closid = closid;
+			wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, closid);
+		}
+	}
+}
+
+#else
+
+static inline void intel_rdt_sched_in(void) {}
+
+#endif /* CONFIG_INTEL_RDT_A */
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt.c +0 -1
index 9e1f901..3232efd 100644
@@ -29,7 +29,6 @@
 #include <linux/cacheinfo.h>
 #include <linux/cpuhotplug.h>
 
-#include <asm/intel_rdt_common.h>
 #include <asm/intel-family.h>
 #include <asm/intel_rdt.h>
 
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +3 -0
index d20be87..1c9bd29 100644
@@ -292,6 +292,9 @@ static void move_myself(struct callback_head *head)
 		kfree(rdtgrp);
 	}
 
+	/* update PQR_ASSOC MSR to make resource group go into effect */
+	intel_rdt_sched_in();
+
 	kfree(callback);
 }
 
arch/x86/kernel/process_32.c +4 -0
index bd7be8e..efe7f9f 100644
@@ -54,6 +54,7 @@
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
 #include <asm/vm86.h>
+#include <asm/intel_rdt.h>
 
 void __show_regs(struct pt_regs *regs, int all)
 {
@@ -299,5 +300,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	this_cpu_write(current_task, next_p);
 
+	/* Load the Intel cache allocation PQR MSR. */
+	intel_rdt_sched_in();
+
 	return prev_p;
 }
arch/x86/kernel/process_64.c +4 -0
index b3760b3..acd7d6f 100644
@@ -50,6 +50,7 @@
 #include <asm/switch_to.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/vdso.h>
+#include <asm/intel_rdt.h>
 
 __visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
 
@@ -473,6 +474,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 			loadsegment(ss, __KERNEL_DS);
 	}
 
+	/* Load the Intel cache allocation PQR MSR. */
+	intel_rdt_sched_in();
+
 	return prev_p;
 }
 
Signature · 1 line
2.5.0
#19 lore raw

[tip:x86/cache] x86/intel_rdt: Add scheduler hook

x86/intel_rdt: Add scheduler hook
Commit-ID:  4f341a5e48443fcc2e2d935ca990e462c02bb1a6
Gitweb:     http://git.kernel.org/tip/4f341a5e48443fcc2e2d935ca990e462c02bb1a6
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:48 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:16 -0600

x86/intel_rdt: Add scheduler hook

Hook the x86 scheduler code to update closid based on whether the current task is assigned to a specific closid or running on a CPU assigned to a specific closid.

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/include/asm/intel_rdt.h         | 42 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel_rdt.c          |  1 -
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |  3 +++
 arch/x86/kernel/process_32.c             |  4 +++
 arch/x86/kernel/process_64.c             |  4 +++
 5 files changed, 53 insertions(+), 1 deletion(-)
arch/x86/include/asm/intel_rdt.h +42 -0
index 2e5eab0..5bc72a4 100644
@@ -1,8 +1,12 @@
 #ifndef _ASM_X86_INTEL_RDT_H
 #define _ASM_X86_INTEL_RDT_H
 
+#ifdef CONFIG_INTEL_RDT_A
+
 #include <linux/jump_label.h>
 
+#include <asm/intel_rdt_common.h>
+
 #define IA32_L3_QOS_CFG		0xc81
 #define IA32_L3_CBM_BASE	0xc90
 #define IA32_L2_CBM_BASE	0xd10
@@ -176,4 +180,42 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 				char *buf, size_t nbytes, loff_t off);
 int rdtgroup_schemata_show(struct kernfs_open_file *of,
 			   struct seq_file *s, void *v);
+
+/*
+ * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR
+ *
+ * Following considerations are made so that this has minimal impact
+ * on scheduler hot path:
+ * - This will stay as no-op unless we are running on an Intel SKU
+ *   which supports resource control and we enable by mounting the
+ *   resctrl file system.
+ * - Caches the per cpu CLOSid values and does the MSR write only
+ *   when a task with a different CLOSid is scheduled in.
+ */
+static inline void intel_rdt_sched_in(void)
+{
+	if (static_branch_likely(&rdt_enable_key)) {
+		struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+		int closid;
+
+		/*
+		 * If this task has a closid assigned, use it.
+		 * Else use the closid assigned to this cpu.
+		 */
+		closid = current->closid;
+		if (closid == 0)
+			closid = this_cpu_read(cpu_closid);
+
+		if (closid != state->closid) {
+			state->closid = closid;
+			wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, closid);
+		}
+	}
+}
+
+#else
+
+static inline void intel_rdt_sched_in(void) {}
+
+#endif /* CONFIG_INTEL_RDT_A */
 #endif /* _ASM_X86_INTEL_RDT_H */
arch/x86/kernel/cpu/intel_rdt.c +0 -1
index 40094ae..5a533fe 100644
@@ -29,7 +29,6 @@
 #include <linux/cacheinfo.h>
 #include <linux/cpuhotplug.h>
 
-#include <asm/intel_rdt_common.h>
 #include <asm/intel-family.h>
 #include <asm/intel_rdt.h>
 
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +3 -0
index 5c4bab9..a90ad22 100644
@@ -292,6 +292,9 @@ static void move_myself(struct callback_head *head)
 		kfree(rdtgrp);
 	}
 
+	/* update PQR_ASSOC MSR to make resource group go into effect */
+	intel_rdt_sched_in();
+
 	kfree(callback);
 }
 
arch/x86/kernel/process_32.c +4 -0
index bd7be8e..efe7f9f 100644
@@ -54,6 +54,7 @@
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
 #include <asm/vm86.h>
+#include <asm/intel_rdt.h>
 
 void __show_regs(struct pt_regs *regs, int all)
 {
@@ -299,5 +300,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	this_cpu_write(current_task, next_p);
 
+	/* Load the Intel cache allocation PQR MSR. */
+	intel_rdt_sched_in();
+
 	return prev_p;
 }
arch/x86/kernel/process_64.c +4 -0
index b3760b3..acd7d6f 100644
@@ -50,6 +50,7 @@
 #include <asm/switch_to.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/vdso.h>
+#include <asm/intel_rdt.h>
 
 __visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
 
@@ -473,6 +474,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 			loadsegment(ss, __KERNEL_DS);
 	}
 
+	/* Load the Intel cache allocation PQR MSR. */
+	intel_rdt_sched_in();
+
 	return prev_p;
 }
 
author
#20 lore raw

PATCH v6 10/10 MAINTAINERS: Add maintainer for Intel RDT resource allocation

In reply to Fenghua Yu

From: Fenghua Yu <[email protected]>

We create five new files for Intel RDT resource allocation:
arch/x86/kernel/cpu/intel_rdt.c arch/x86/kernel/cpu/intel_rdt_rdtgroup.c arch/x86/kernel/cpu/intel_rdt_schemata.c arch/x86/include/asm/intel_rdt.h Documentation/x86/intel_rdt_ui.txt

Fenghua Yu will maintain this code.

---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
index c447953..4e6a044 100644
@@ -10107,6 +10107,14 @@ L:	[email protected]
 S:	Supported
 F:	drivers/infiniband/sw/rdmavt
 
+RDT - RESOURCE ALLOCATION
+M:	Fenghua Yu <[email protected]>
+L:	[email protected]
+S:	Supported
+F:	arch/x86/kernel/cpu/intel_rdt*
+F:	arch/x86/include/asm/intel_rdt*
+F:	Documentation/x86/intel_rdt*
+
 READ-COPY UPDATE (RCU)
 M:	"Paul E. McKenney" <[email protected]>
 M:	Josh Triplett <[email protected]>
Signature · 1 line
2.5.0
#21 lore raw

[tip:x86/cache] MAINTAINERS: Add maintainer for Intel RDT resource allocation

MAINTAINERS: Add maintainer for Intel RDT resource allocation
Commit-ID:  48553d103d0b63991a08980889c6a35b3e05b5e3
Gitweb:     http://git.kernel.org/tip/48553d103d0b63991a08980889c6a35b3e05b5e3
Author:     Fenghua Yu <[email protected]>
AuthorDate: Fri, 28 Oct 2016 15:04:49 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 30 Oct 2016 19:10:17 -0600

MAINTAINERS: Add maintainer for Intel RDT resource allocation

We create five new files for Intel RDT resource allocation:
arch/x86/kernel/cpu/intel_rdt.c arch/x86/kernel/cpu/intel_rdt_rdtgroup.c arch/x86/kernel/cpu/intel_rdt_schemata.c arch/x86/include/asm/intel_rdt.h Documentation/x86/intel_rdt_ui.txt

Fenghua Yu will maintain this code.

Cc "Ravi V Shankar" <[email protected]>
Cc "Tony Luck" <[email protected]>
Cc "Shaohua Li" <[email protected]>
Cc "Sai Prakhya" <[email protected]>
Cc "Peter Zijlstra" <[email protected]>
Cc "Stephane Eranian" <[email protected]>
Cc "Dave Hansen" <[email protected]>
Cc "David Carrillo-Cisneros" <[email protected]>
Cc "Nilay Vaish" <[email protected]>
Cc "Vikas Shivappa" <[email protected]>
Cc "Ingo Molnar" <[email protected]>
Cc "Borislav Petkov" <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
index c447953..4e6a044 100644
@@ -10107,6 +10107,14 @@ L:	[email protected]
 S:	Supported
 F:	drivers/infiniband/sw/rdmavt
 
+RDT - RESOURCE ALLOCATION
+M:	Fenghua Yu <[email protected]>
+L:	[email protected]
+S:	Supported
+F:	arch/x86/kernel/cpu/intel_rdt*
+F:	arch/x86/include/asm/intel_rdt*
+F:	Documentation/x86/intel_rdt*
+
 READ-COPY UPDATE (RCU)
 M:	"Paul E. McKenney" <[email protected]>
 M:	Josh Triplett <[email protected]>
#22 lore raw
In reply to Fenghua Yu

Gentlemen!

After more than two years of tinkering and real engineering, we finaly have skinned the CAT!

That was the most amazing review journey I ever made as a maintainer. Just a few statistics:

Design variants: 6

6 different approaches for a user space interface. 3 of them have been actually implemented.

Unfortunately the real interface discussion happened way after the first rounds of patches had been sent and reviewed. See below.

Patchsets: 21

21 patch sets were posted. These can be split into two generations.

Gen1 16 Oct 2014 - Dec 2015

Gen2 5 Jul 2016 - Oct 2016

LKML-Mails: 1216

That's the number of mails related to this project sent to LKML, according to my archive. About 1/3 of those mails are the postings of the patchsets alone.

I cannot tell how many offlist mails have been sent around in total on this matter, but at least in my personal mail are close to hundred.

Beers: Uncountable

This applies to both the number of beers consumed and the number of beers owed.

I'm pretty happy with the final outcome of these patches and I want to say thanks to everyone!

I know that I've been a pain in the neck for some of you due to my pedantery about the details, but getting this wrong would have been a major disaster. If I offended someone personally in course of the sometimes heated discussions, then I offer my excuses.

Some lessons can be learned from this endeavour:

1) Chip vendors should give access to the full documentation early

2) Reviewers should never trust patch submitters, that they have read the documentation correctly and came to the right conclusions how to handle such a facility.

3) User space interface discussions should be done upfront with a full explanation of the inner workings of such a facility and full documentation available.

Anything else is just the usual churn of patch submissions, which are handled by the submitters with different effectiveness levels.

That said, all which needs to be done now is proper testing and a massive exposure of the user space interface to fuzzers. I've implemented my share of string parsers in the past and as careful as I was, there was always a hole in them.

If any of the involved folks are at KS/LPC then I suggest we get together at a bar during the week and drown the skinned CAT with the appropriate beverages. The first round of drinks is my shout.

Thanks,

tglx

#23 lore raw
Quoted 4 lines

Gentlemen!

After more than two years of tinkering and real engineering, we finaly have skinned the CAT!

Yeah! We made it!

Quoted 14 lines

That was the most amazing review journey I ever made as a maintainer. Just a few statistics:

Design variants: 6

6 different approaches for a user space interface. 3 of them have been actually implemented.

Unfortunately the real interface discussion happened way after the first rounds of patches had been sent and reviewed. See below.

Patchsets: 21

Quoted 7 lines

21 patch sets were posted. These can be split into two generations.

Gen1 16 Oct 2014 - Dec 2015

Gen2 5 Jul 2016 - Oct 2016

LKML-Mails: 1216

Wow! You have such detailed statistics data!

Quoted 34 lines

That's the number of mails related to this project sent to LKML, according to my archive. About 1/3 of those mails are the postings of the patchsets alone.

I cannot tell how many offlist mails have been sent around in total on this matter, but at least in my personal mail are close to hundred.

Beers: Uncountable

This applies to both the number of beers consumed and the number of
beers
owed.

I'm pretty happy with the final outcome of these patches and I want to say thanks to everyone!

I know that I've been a pain in the neck for some of you due to my pedantery about the details, but getting this wrong would have been a major disaster. If I offended someone personally in course of the sometimes heated discussions, then I offer my excuses.

Some lessons can be learned from this endeavour:

1) Chip vendors should give access to the full documentation early

2) Reviewers should never trust patch submitters, that they have read the documentation correctly and came to the right conclusions how to handle such a facility.

3) User space interface discussions should be done upfront with a full explanation of the inner workings of such a facility and full documentation available.

Quoted 7 lines

Anything else is just the usual churn of patch submissions, which are handled by the submitters with different effectiveness levels.

That said, all which needs to be done now is proper testing and a massive exposure of the user space interface to fuzzers. I've implemented my share of string parsers in the past and as careful as I was, there was always a hole in them.

We have a few internal test cases and we are enhancing them and doing more tests from our side.

Quoted 4 lines

If any of the involved folks are at KS/LPC then I suggest we get together at a bar during the week and drown the skinned CAT with the appropriate beverages. The first round of drinks is my shout.

I won't be in KS/LPC, unfortunately. But I really wish we can meet face to face in the near future.

Is there any plan for you to travel to any Intel site recently? It would be great to have a celebration beer with you and discuss what we are going to do next:)

Thanks.

-Fenghua