From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932514AbcJNXLb (ORCPT ); Fri, 14 Oct 2016 19:11:31 -0400 Received: from mga07.intel.com ([134.134.136.100]:23561 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754857AbcJNXKI (ORCPT ); Fri, 14 Oct 2016 19:10:08 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,495,1473145200"; d="scan'208";a="19747832" From: "Fenghua Yu" To: "Thomas Gleixner" Cc: "H. Peter Anvin" , "Ingo Molnar" , "Tony Luck" , "Peter Zijlstra" , "Stephane Eranian" , "Borislav Petkov" , "Dave Hansen" , "Nilay Vaish" , "Shaohua Li" , "David Carrillo-Cisneros" , "Ravi V Shankar" , "Sai Prakhya" , "Vikas Shivappa" , "linux-kernel" , "x86" , "Fenghua Yu" Subject: [PATCH v4 11/18] x86/intel_rdt: Add basic resctrl filesystem support Date: Fri, 14 Oct 2016 19:12:21 -0700 Message-Id: <1476497548-11169-12-git-send-email-fenghua.yu@intel.com> X-Mailer: git-send-email 1.8.0.1 In-Reply-To: <1476497548-11169-1-git-send-email-fenghua.yu@intel.com> References: <1476497548-11169-1-git-send-email-fenghua.yu@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fenghua Yu 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. Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck --- arch/x86/include/asm/intel_rdt.h | 22 +++ arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/intel_rdt.c | 8 +- arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 235 +++++++++++++++++++++++++++++++ include/uapi/linux/magic.h | 1 + 5 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h index b3df691..f7acae2 100644 --- a/arch/x86/include/asm/intel_rdt.h +++ b/arch/x86/include/asm/intel_rdt.h @@ -5,6 +5,23 @@ #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 * @name: Name to use in "schemata" file @@ -42,6 +59,7 @@ struct rdt_resource { for (r = rdt_resources_all; r->name; r++) \ if (r->enabled) +#define IA32_L3_QOS_CFG 0xc81 #define IA32_L3_CBM_BASE 0xc90 /** @@ -73,6 +91,10 @@ struct msr_param { extern struct mutex rdtgroup_mutex; extern struct rdt_resource rdt_resources_all[]; +extern struct rdtgroup rdtgroup_default; +extern struct static_key_false rdt_enable_key; + +int __init rdtgroup_init(void); enum { RDT_RESOURCE_L3, diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index cf4bfd0..b4334e8 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -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/ diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 0b47ea9..3d4a125 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -266,7 +266,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; @@ -277,6 +277,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_rdt_resource(r) pr_info("Intel RDT %s allocation %s detected\n", r->name, r->cdp_capable ? " (with CDP)" : ""); diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c new file mode 100644 index 0000000..b2bbd04 --- /dev/null +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -0,0 +1,235 @@ +/* + * User interface for Resource Alloction in Resource Director Technology(RDT) + * + * Copyright (C) 2016 Intel Corporation + * + * Author: Fenghua Yu + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * More information about RDT be found in the Intel (R) x86 Architecture + * Software Developer Manual. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include + +#include + +#include + +DEFINE_STATIC_KEY_FALSE(rdt_enable_key); +struct kernfs_root *rdt_root; +struct rdtgroup rdtgroup_default; +LIST_HEAD(rdt_all_groups); + +static void l3_qos_cfg_update(void *arg) +{ + struct rdt_resource *r = arg; + + wrmsrl(IA32_L3_QOS_CFG, r->cdp_enabled); +} + +static void set_l3_qos_cfg(struct rdt_resource *r) +{ + struct list_head *l; + struct rdt_domain *d; + struct cpumask cpu_mask; + int cpu; + + cpumask_clear(&cpu_mask); + list_for_each(l, &r->domains) { + d = list_entry(l, struct rdt_domain, list); + 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); + /* Update QOS_CFG MSR on all other cpus in cpu_mask. */ + smp_call_function_many(&cpu_mask, l3_qos_cfg_update, r, 1); + put_cpu(); +} + +static int parse_rdtgroupfs_options(char *data) +{ + char *token, *o = data; + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; + + r->cdp_enabled = false; + while ((token = strsep(&o, ",")) != NULL) { + if (!*token) + return -EINVAL; + + if (!strcmp(token, "cdp")) + if (r->enabled && r->cdp_capable) + r->cdp_enabled = true; + } + + return 0; +} + +static struct dentry *rdt_mount(struct file_system_type *fs_type, + int flags, const char *unused_dev_name, + void *data) +{ + struct dentry *dentry; + int ret; + bool new_sb; + + mutex_lock(&rdtgroup_mutex); + /* + * resctrl file system can only be mounted once. + */ + if (static_branch_unlikely(&rdt_enable_key)) { + dentry = ERR_PTR(-EBUSY); + goto out; + } + + ret = parse_rdtgroupfs_options(data); + if (ret) { + dentry = ERR_PTR(ret); + goto out; + } + + dentry = kernfs_mount(fs_type, flags, rdt_root, + RDTGROUP_SUPER_MAGIC, &new_sb); + if (IS_ERR(dentry)) + goto out; + if (!new_sb) { + dentry = ERR_PTR(-EINVAL); + goto out; + } + if (rdt_resources_all[RDT_RESOURCE_L3].cdp_capable) + set_l3_qos_cfg(&rdt_resources_all[RDT_RESOURCE_L3]); + static_branch_enable(&rdt_enable_key); + +out: + mutex_unlock(&rdtgroup_mutex); + + return dentry; +} + +static void reset_all_cbms(struct rdt_resource *r) +{ + struct list_head *l; + struct rdt_domain *d; + struct msr_param msr_param; + struct cpumask cpu_mask; + int i, cpu; + + cpumask_clear(&cpu_mask); + msr_param.res = r; + msr_param.low = 0; + msr_param.high = r->max_closid; + + list_for_each(l, &r->domains) { + d = list_entry(l, struct rdt_domain, list); + cpumask_set_cpu(cpumask_any(&d->cpu_mask), &cpu_mask); + + for (i = 0; i < r->max_closid; i++) + d->cbm[i] = r->max_cbm; + } + cpu = get_cpu(); + /* Update CBM on this cpu if it's in cpu_mask. */ + if (cpumask_test_cpu(cpu, &cpu_mask)) + rdt_cbm_update(&msr_param); + /* Updte CBM on all other cpus in cpu_mask. */ + smp_call_function_many(&cpu_mask, rdt_cbm_update, &msr_param, 1); + put_cpu(); +} + +static void rdt_kill_sb(struct super_block *sb) +{ + struct rdt_resource *r; + + mutex_lock(&rdtgroup_mutex); + + /*Put everything back to default values. */ + for_each_rdt_resource(r) + reset_all_cbms(r); + r = &rdt_resources_all[RDT_RESOURCE_L3]; + if (r->cdp_capable) { + r->cdp_enabled = 0; + set_l3_qos_cfg(r); + } + + static_branch_disable(&rdt_enable_key); + kernfs_kill_sb(sb); + mutex_unlock(&rdtgroup_mutex); +} + +static struct file_system_type rdt_fs_type = { + .name = "resctrl", + .mount = rdt_mount, + .kill_sb = rdt_kill_sb, +}; + +static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = { +}; + +static int __init rdtgroup_setup_root(void) +{ + rdt_root = kernfs_create_root(&rdtgroup_kf_syscall_ops, + KERNFS_ROOT_CREATE_DEACTIVATED, + &rdtgroup_default); + if (IS_ERR(rdt_root)) + return PTR_ERR(rdt_root); + + mutex_lock(&rdtgroup_mutex); + + rdtgroup_default.closid = 0; + list_add(&rdtgroup_default.rdtgroup_list, &rdt_all_groups); + + rdtgroup_default.kn = rdt_root->kn; + kernfs_activate(rdtgroup_default.kn); + + mutex_unlock(&rdtgroup_mutex); + + return 0; +} + +/* + * rdtgroup_init - rdtgroup initialization + * + * Setup resctrl file system including set up root, create mount point, + * register rdtgroup filesystem, and initialize files under root directory. + * + * Return: 0 on success or -errno + */ +int __init rdtgroup_init(void) +{ + int ret = 0; + + ret = rdtgroup_setup_root(); + if (ret) + return ret; + + ret = sysfs_create_mount_point(fs_kobj, "resctrl"); + if (ret) + goto cleanup_root; + + ret = register_filesystem(&rdt_fs_type); + if (ret) + goto cleanup_mountpoint; + + return 0; + +cleanup_mountpoint: + sysfs_remove_mount_point(fs_kobj, "resctrl"); +cleanup_root: + kernfs_destroy_root(rdt_root); + + return ret; +} diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index e398bea..27ef03d 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -57,6 +57,7 @@ #define CGROUP_SUPER_MAGIC 0x27e0eb #define CGROUP2_SUPER_MAGIC 0x63677270 +#define RDTGROUP_SUPER_MAGIC 0x7655821 #define STACK_END_MAGIC 0x57AC6E9D -- 2.5.0