Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp3091716imj; Mon, 18 Feb 2019 19:41:10 -0800 (PST) X-Google-Smtp-Source: AHgI3IaSYP1cvhlKZ4/DhDE8DM4axASMlsxDLhFn8nziuy+JrxC+rNFP0yXx0gCovLfl7nSeQ1TC X-Received: by 2002:aa7:8101:: with SMTP id b1mr28012099pfi.148.1550547670439; Mon, 18 Feb 2019 19:41:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550547670; cv=none; d=google.com; s=arc-20160816; b=WDH9lokiDIUaxIT5zx7Y2aqfa/CJCbqa++53/WcrhQg3XqATqtzsSqhVqpMCC99SsN QnH/oWmGL5LQIVYVmKaohvw2P4psX6HGs//QovTlV12cDyyT4JYGqUGtLcz1jfyPIeCR /qQ4mEP6aLTMCerTShsR0FStrh9EdW0gHSD0F8WYfYHM5I5dlt7ozYT+eAvmrMCiSGua X6yhNO4aaKWw+0iVNYmyxs/F7WXegagSY7wrvELBcSevSN0ey5vJjUT3aN29tK+kuw0f SnRudx9xNtPAhsDkWm4w2r3ao0AIyjnEXOEdcrRf7Q8tOmm0S9qvL5dg8ujzxNRNUijN T1Gg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:organization:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=Lu1zx7M7cI9ltexiK09UU1PmGqmAsCf/7vqCm06X1e8=; b=atRwAVXAuP7nOVQ2RjJrnuX2gEojNeF45pSfs0a9HOO3Miw3yTbzqbqRDzYXlMAxEP 9EzX/TqyY5xWEBB5sKlQxuh7yOeVGtie1VJ90Be7csOD5/IIcF+NUgjgStDpFt0BMpmo ZpMuRs4w+kYCfjhRXd92obiK4ElXOf6dUWubHJ2NI/KxjzAiz/VDyl4Y/A7LcSW4f+nw pJ4rLexqWK8ZOQLr7E2bZ3Sb5PL+CmVCbbCxMV7n9cbMuCjC6/zvl59ceTDZLsgaQ58J /exkY/LKYGI9f6c563HTlbkbVRFtpoY9/mPeP7eOci11xUPuZSX4qqz1fT4KIadYlJru w6pg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=VB8tZfbI; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b15si11579150plm.431.2019.02.18.19.40.55; Mon, 18 Feb 2019 19:41:10 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=VB8tZfbI; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726360AbfBSDk3 (ORCPT + 99 others); Mon, 18 Feb 2019 22:40:29 -0500 Received: from mail-qk1-f196.google.com ([209.85.222.196]:38241 "EHLO mail-qk1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726325AbfBSDk0 (ORCPT ); Mon, 18 Feb 2019 22:40:26 -0500 Received: by mail-qk1-f196.google.com with SMTP id p15so11252901qkl.5; Mon, 18 Feb 2019 19:40:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :reply-to:organization; bh=Lu1zx7M7cI9ltexiK09UU1PmGqmAsCf/7vqCm06X1e8=; b=VB8tZfbIcVoZpU6/tpK+1ObRMD/YRDEApGpeOrGQsF8Px/+mkrFyjEPaO4/Zb0iJpA fy9DqQjqsJb2DetlCpDZT2m/5C4ST7ORIfMdGHmimJjEQDx4V9bXBO9Hpg99LFE4+igS FCM7pCdIgP9W/eWiKweaJq6WfqIqVqnCp6ubFmY6Aof88th7M3Sbe3Vs5P7ocbjzgCx0 EVw3ch6lqs4fh0g7wiE/ZCOrkohg9mRWhO69U4twzOrA9gxi1Z4LLPaoIlxVXqsTEbM9 wn6gwZ9PUJ1N2Gggs3z1bzoux2nzaM3Uxl4Q4HJk3y/bSQ9mgX9HopFOrSDvLCZWpNLc Wq1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:reply-to:organization; bh=Lu1zx7M7cI9ltexiK09UU1PmGqmAsCf/7vqCm06X1e8=; b=Fwg1fsK/jdsIMzMrQ/mqiO7zeYHAn4HkaZ9HxKW9sYEBcLyTaob4NjwI2fpesKIoFg mRQ1A4PIXJeBufgh2Ypg5iPFhKkBX/st19uA5tpS5txhmZ6+gpIm1JCbDc7w4vbmm/Hu ugZt8ry3ngadl2G/MtS/P/GsnTA04zvQefrIQpXcYso6uUQnG1mnqgc7xtCl1Hdf/ZWK lQjGol9/JlvTdxDvdFAeZFHy9nUaMhG3JM1Sqdcdn7PTlTSV90csFXjf+9CPb2rUzlhN i0HA5G3Lo8TUCtGekTKynuQwnbNqDacLw5OCgqlIvCH76kq7NuM//26iRQTAvcBZDvss uJlQ== X-Gm-Message-State: AHQUAuZ1kusQ96Zatv3hZ2WrmbkjoVEG1QvoNUK0vHT6P9GGQB3xf6wj /lmq+d9QUlHHFnHadBy/QU4= X-Received: by 2002:a37:7cf:: with SMTP id 198mr19188831qkh.173.1550547625484; Mon, 18 Feb 2019 19:40:25 -0800 (PST) Received: from kbl.fios-router.home (pool-96-233-42-17.bstnma.fios.verizon.net. [96.233.42.17]) by smtp.gmail.com with ESMTPSA id u5sm7327680qtg.37.2019.02.18.19.40.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 19:40:24 -0800 (PST) From: Len Brown To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Len Brown , linux-doc@vger.kernel.org Subject: [PATCH 03/11] x86 topology: Add CPUID.1F multi-die/package support Date: Mon, 18 Feb 2019 22:40:05 -0500 Message-Id: <07d2908dc72bf964b27380999e1c826587d69136.1550545163.git.len.brown@intel.com> X-Mailer: git-send-email 2.18.0-rc0 In-Reply-To: <635b2bf8b1151a191cd9299276b75791a818c0c2.1550545163.git.len.brown@intel.com> References: <635b2bf8b1151a191cd9299276b75791a818c0c2.1550545163.git.len.brown@intel.com> Reply-To: Len Brown Organization: Intel Open Source Technology Center Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Len Brown Some new systems have multiple software-visible die within each package. The new CPUID.1F leaf can enumerate this multi-die/package topology. CPUID.1F a super-set of the CPUID.B "Extended Toplogy Leaf", and a common updated routine can parse either leaf. Legacy systems without CPUID.1F, and systems without multi-die/package hardware, will see no functional change from this patch series. Multi-die/package systems will use CPUID.B before this patch, and CPUID.1F after this patch. In the CPUID.B case, all die appear (incorrectly) to software as individual packages. In the CPUID.1F case, the package id's reflect reality, and die_id's become meaningful. Subsequent patches in this series update the kernel to be multi-die aware. In particular, some software needs to know the difference between a die-scope MSR and a package-scope MSR. Signed-off-by: Len Brown Cc: linux-doc@vger.kernel.org Signed-off-by: Len Brown --- Documentation/x86/topology.txt | 4 ++ arch/x86/include/asm/processor.h | 4 +- arch/x86/kernel/cpu/topology.c | 82 ++++++++++++++++++++++++-------- arch/x86/kernel/smpboot.c | 4 +- 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/Documentation/x86/topology.txt b/Documentation/x86/topology.txt index 06b3cdbc4048..8107b6cfc9ea 100644 --- a/Documentation/x86/topology.txt +++ b/Documentation/x86/topology.txt @@ -46,6 +46,10 @@ The topology of a system is described in the units of: The number of cores in a package. This information is retrieved via CPUID. + - cpuinfo_x86.x86_max_dies: + + The number of dies in a package. This information is retrieved via CPUID. + - cpuinfo_x86.phys_proc_id: The physical ID of the package. This information is retrieved via CPUID diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 33051436c864..f2856fe03715 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -105,7 +105,8 @@ struct cpuinfo_x86 { int x86_power; unsigned long loops_per_jiffy; /* cpuid returned max cores value: */ - u16 x86_max_cores; + u16 x86_max_cores; + u16 x86_max_dies; u16 apicid; u16 initial_apicid; u16 x86_clflush_size; @@ -117,6 +118,7 @@ struct cpuinfo_x86 { u16 logical_proc_id; /* Core id: */ u16 cpu_core_id; + u16 cpu_die_id; /* Index into per_cpu list: */ u16 cpu_index; u32 microcode; diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 8f6c784141d1..6dce6ee77849 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -15,33 +15,61 @@ /* leaf 0xb SMT level */ #define SMT_LEVEL 0 -/* leaf 0xb sub-leaf types */ +/* extended topology sub-leaf types */ #define INVALID_TYPE 0 #define SMT_TYPE 1 #define CORE_TYPE 2 +#define DIE_TYPE 5 #define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff) #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) -int detect_extended_topology_early(struct cpuinfo_x86 *c) -{ #ifdef CONFIG_SMP +/* + * Check if given CPUID extended toplogy "leaf" is implemented + */ +static int check_extended_topology_leaf(int leaf) +{ unsigned int eax, ebx, ecx, edx; - if (c->cpuid_level < 0xb) + cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx); + + if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) return -1; - cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); + return 0; +} +/* + * Return best CPUID Extended Toplogy Leaf supported + */ +static int detect_extended_topology_leaf(struct cpuinfo_x86 *c) +{ + if (c->cpuid_level >= 0x1f) + if (check_extended_topology_leaf(0x1f) == 0) + return 0x1f; - /* - * check if the cpuid leaf 0xb is actually implemented. - */ - if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) + if (c->cpuid_level >= 0xb) + if (check_extended_topology_leaf(0xb) == 0) + return 0xb; + + return -1; +} +#endif + +int detect_extended_topology_early(struct cpuinfo_x86 *c) +{ +#ifdef CONFIG_SMP + unsigned int eax, ebx, ecx, edx; + int leaf; + + leaf = detect_extended_topology_leaf(c); + if (leaf < 0) return -1; set_cpu_cap(c, X86_FEATURE_XTOPOLOGY); + cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx); /* * initial apic id, which also represents 32-bit extended x2apic id. */ @@ -52,7 +80,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c) } /* - * Check for extended topology enumeration cpuid leaf 0xb and if it + * Check for extended topology enumeration cpuid leaf, and if it * exists, use it for populating initial_apicid and cpu topology * detection. */ @@ -60,46 +88,62 @@ int detect_extended_topology(struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP unsigned int eax, ebx, ecx, edx, sub_index; - unsigned int ht_mask_width, core_plus_mask_width; + unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width; unsigned int core_select_mask, core_level_siblings; + unsigned int die_select_mask, die_level_siblings; + int leaf; - if (detect_extended_topology_early(c) < 0) + leaf = detect_extended_topology_leaf(c); + if (leaf < 0) return -1; /* * Populate HT related information from sub-leaf level 0. */ - cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); + cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx); + c->initial_apicid = edx; core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); + die_level_siblings = LEVEL_MAX_SIBLINGS(ebx); + die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); sub_index = 1; do { - cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx); + cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx); /* * Check for the Core type in the implemented sub leaves. */ if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) { core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); + die_level_siblings = core_level_siblings; core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); - break; + } + if (LEAFB_SUBTYPE(ecx) == DIE_TYPE) { + die_level_siblings = LEVEL_MAX_SIBLINGS(ebx); + die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); } sub_index++; } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; - - c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width) - & core_select_mask; - c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width); + die_select_mask = (~(-1 << die_plus_mask_width)) >> + core_plus_mask_width; + + c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, + ht_mask_width) & core_select_mask; + c->cpu_die_id = apic->phys_pkg_id(c->initial_apicid, + core_plus_mask_width) & die_select_mask; + c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, + die_plus_mask_width); /* * Reinit the apicid, now that we have extended initial_apicid. */ c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); c->x86_max_cores = (core_level_siblings / smp_num_siblings); + c->x86_max_dies = (die_level_siblings / core_level_siblings); #endif return 0; } diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index ccd1f2a8e557..4250a87f57db 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -393,6 +393,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) int cpu1 = c->cpu_index, cpu2 = o->cpu_index; if (c->phys_proc_id == o->phys_proc_id && + c->cpu_die_id == o->cpu_die_id && per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) { if (c->cpu_core_id == o->cpu_core_id) return topology_sane(c, o, "smt"); @@ -404,6 +405,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) } } else if (c->phys_proc_id == o->phys_proc_id && + c->cpu_die_id == o->cpu_die_id && c->cpu_core_id == o->cpu_core_id) { return topology_sane(c, o, "smt"); } @@ -461,7 +463,7 @@ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) */ static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) { - if (c->phys_proc_id == o->phys_proc_id) + if (c->cpu_die_id == o->cpu_die_id) return true; return false; } -- 2.18.0-rc0