Intel Cache Allocation Technology
Subsystems (3)
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
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
@@ -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
tip-bot for Fenghua Yu
merge bot[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 ]
--- Documentation/x86/intel_rdt_ui.txt | 195 +++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+)
Documentation/x86/intel_rdt_ui.txt new file +195 -0
@@ -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
PATCH v6 2/10 x86/intel_rdt: Build structures for each resource based on cache topology
In reply to Fenghua YuFrom: 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
@@ -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
tip-bot for Tony Luck
merge bot[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.
--- 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
@@ -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
PATCH v6 3/10 x86/intel_rdt: Add basic resctrl filesystem support
In reply to Fenghua YuFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
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
tip-bot for Fenghua Yu
merge bot[tip:x86/cache] x86/intel_rdt: Add basic resctrl filesystem support
In reply to Fenghua Yux86/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 ]
--- 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
@@ -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
@@ -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
@@ -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
@@ -57,6 +57,7 @@#define CGROUP_SUPER_MAGIC 0x27e0eb#define CGROUP2_SUPER_MAGIC 0x63677270 +#define RDTGROUP_SUPER_MAGIC 0x7655821#define STACK_END_MAGIC 0x57AC6E9D
PATCH v6 4/10 x86/intel_rdt: Add "info" files to resctrl file system
In reply to Fenghua YuFrom: 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
@@ -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
tip-bot for Fenghua Yu
merge bot[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.
--- 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
@@ -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
PATCH v6 5/10 x86/intel_rdt: Add mkdir to resctrl file system
In reply to Fenghua YuFrom: 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
@@ -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
tip-bot for Fenghua Yu
merge bot[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.
--- 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
@@ -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
PATCH v6 6/10 x86/intel_rdt: Add cpus file
In reply to Fenghua YuFrom: 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
@@ -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
@@ -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
tip-bot for Tony Luck
merge bot[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.
--- 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
@@ -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
@@ -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
PATCH v6 7/10 x86/intel_rdt: Add tasks files
In reply to Fenghua YuFrom: 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
@@ -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
@@ -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
tip-bot for Fenghua Yu
merge bot[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.
--- 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
@@ -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
@@ -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
PATCH v6 8/10 x86/intel_rdt: Add schemata file
In reply to Fenghua YuFrom: 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
@@ -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
@@ -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
@@ -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
tip-bot for Tony Luck
merge bot[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--- 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
@@ -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
@@ -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
@@ -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
PATCH v6 9/10 x86/intel_rdt: Add scheduler hook
In reply to Fenghua YuFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
tip-bot for Fenghua Yu
merge bot[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.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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; }
PATCH v6 10/10 MAINTAINERS: Add maintainer for Intel RDT resource allocation
In reply to Fenghua YuFrom: 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
@@ -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
tip-bot for Fenghua Yu
merge bot[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.
--- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
@@ -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]>
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
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