Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932964AbcJGXpW (ORCPT ); Fri, 7 Oct 2016 19:45:22 -0400 Received: from mga05.intel.com ([192.55.52.43]:19336 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932886AbcJGXo6 (ORCPT ); Fri, 7 Oct 2016 19:44:58 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,457,1473145200"; d="scan'208";a="17405499" 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 v3 08/18] x86/intel_rdt: Pick up L3 RDT parameters from CPUID Date: Fri, 7 Oct 2016 19:45:53 -0700 Message-Id: <1475894763-64683-9-git-send-email-fenghua.yu@intel.com> X-Mailer: git-send-email 1.8.0.1 In-Reply-To: <1475894763-64683-1-git-send-email-fenghua.yu@intel.com> References: <1475894763-64683-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 Content-Length: 5269 Lines: 192 From: Fenghua Yu Define struct rdt_resource to hold all the parameterized values for an RDT resource. Fill in some of those values from CPUID leaf 0x10 (on Haswell we hard code them). Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck --- arch/x86/include/asm/intel_rdt.h | 67 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/intel_rdt.c | 54 +++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 arch/x86/include/asm/intel_rdt.h diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h new file mode 100644 index 0000000..251ac2a --- /dev/null +++ b/arch/x86/include/asm/intel_rdt.h @@ -0,0 +1,67 @@ +#ifndef _ASM_X86_INTEL_RDT_H +#define _ASM_X86_INTEL_RDT_H + +/** + * struct rdt_resource - attributes of an RDT resource + * @enabled: Is this feature enabled on this machine + * @name: Name to use in "schemata" file + * @max_closid: Maximum number of CLOSIDs supported + * @num_closid: Current number of CLOSIDs available + * @max_cbm: Largest Cache Bit Mask allowed + * @min_cbm_bits: Minimum number of bits to be set in a cache + * bit mask + * @domains: All domains for this resource + * @num_domains: Number of domains active + * @msr_base: Base MSR address for CBMs + * @cdp_capable: Code/Data Prioritization available + * @cdp_enabled: Code/Data Prioritization enabled + * @tmp_cbms: Scratch space when updating schemata + * @cache_level: Which cache level defines scope of this domain + */ +struct rdt_resource { + bool enabled; + char *name; + int max_closid; + int num_closid; + int cbm_len; + int min_cbm_bits; + u32 max_cbm; + struct list_head domains; + int num_domains; + int msr_base; + bool cdp_capable; + bool cdp_enabled; + u32 *tmp_cbms; + int cache_level; +}; + +#define for_each_rdt_resource(r) \ + for (r = rdt_resources_all; r->name; r++) \ + if (r->enabled) + +#define IA32_L3_CBM_BASE 0xc90 +extern struct rdt_resource rdt_resources_all[]; + +enum { + RDT_RESOURCE_L3, +}; + +/* Maximum CLOSID allowed across all enabled resoources */ +extern int rdt_max_closid; + +/* CPUID.(EAX=10H, ECX=ResID=1).EAX */ +union cpuid_0x10_1_eax { + struct { + unsigned int cbm_len:5; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID=1).EDX */ +union cpuid_0x10_1_edx { + struct { + unsigned int cos_max:16; + } split; + unsigned int full; +}; +#endif /* _ASM_X86_INTEL_RDT_H */ diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index bc7f10b..b9b1e9e 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -28,6 +28,24 @@ #include #include #include +#include + +int rdt_max_closid; + +#define domain_init(name) LIST_HEAD_INIT(rdt_resources_all[name].domains) + +struct rdt_resource rdt_resources_all[] = { + { + .name = "L3", + .domains = domain_init(RDT_RESOURCE_L3), + .msr_base = IA32_L3_CBM_BASE, + .min_cbm_bits = 1, + .cache_level = 3 + }, + { + /* NULL terminated */ + } +}; /* * cache_alloc_hsw_probe() - Have to probe for Intel haswell server CPUs @@ -41,6 +59,7 @@ static inline bool cache_alloc_hsw_probe(void) { u32 l, h_old, h_new, h_tmp; + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; if (rdmsr_safe(MSR_IA32_PQR_ASSOC, &l, &h_old)) return false; @@ -58,11 +77,19 @@ static inline bool cache_alloc_hsw_probe(void) wrmsr(MSR_IA32_PQR_ASSOC, l, h_old); + r->max_closid = 4; + r->num_closid = r->max_closid; + r->cbm_len = 20; + r->max_cbm = BIT_MASK(20) - 1; + r->min_cbm_bits = 2; + r->enabled = true; + return true; } static inline bool get_rdt_resources(struct cpuinfo_x86 *c) { + struct rdt_resource *r; bool ret = false; if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 6 && @@ -71,8 +98,23 @@ static inline bool get_rdt_resources(struct cpuinfo_x86 *c) if (!cpu_has(c, X86_FEATURE_RDT_A)) return false; - if (cpu_has(c, X86_FEATURE_CAT_L3)) + if (cpu_has(c, X86_FEATURE_CAT_L3)) { + union cpuid_0x10_1_eax eax; + union cpuid_0x10_1_edx edx; + u32 ebx, ecx; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + cpuid_count(0x00000010, 1, &eax.full, &ebx, &ecx, &edx.full); + r->max_closid = edx.split.cos_max + 1; + r->num_closid = r->max_closid; + r->cbm_len = eax.split.cbm_len + 1; + r->max_cbm = BIT_MASK(eax.split.cbm_len + 1) - 1; + if (cpu_has(c, X86_FEATURE_CDP_L3)) + r->cdp_capable = true; + r->enabled = true; + ret = true; + } return ret; } @@ -80,13 +122,17 @@ static inline bool get_rdt_resources(struct cpuinfo_x86 *c) static int __init intel_rdt_late_init(void) { struct cpuinfo_x86 *c = &boot_cpu_data; + struct rdt_resource *r; if (!get_rdt_resources(c)) return -ENODEV; - pr_info("Intel cache allocation detected\n"); - if (cpu_has(c, X86_FEATURE_CDP_L3)) - pr_info("Intel code data prioritization detected\n"); + for_each_rdt_resource(r) + rdt_max_closid = max(rdt_max_closid, r->max_closid); + + for_each_rdt_resource(r) + pr_info("Intel %s allocation %s detected\n", r->name, + r->cdp_capable ? " (with CDP)" : ""); return 0; } -- 2.5.0