Received: by 2002:a05:7412:f589:b0:e2:908c:2ebd with SMTP id eh9csp523887rdb; Tue, 31 Oct 2023 14:18:39 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFO0MbZ6DtQtmaqRCTejLsGpl1pkh4wc5Aw7SuA9nGd4jwyaH2zyYP7gxyHPFeVT6ex/GHp X-Received: by 2002:a17:90a:7525:b0:27d:247b:2c3c with SMTP id q34-20020a17090a752500b0027d247b2c3cmr11855223pjk.23.1698787118451; Tue, 31 Oct 2023 14:18:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698787118; cv=none; d=google.com; s=arc-20160816; b=Ow7b3nI24R7xFG87eoWiNiJSlMoFRp22MM1p+jUqn+AgGBduYPcivk+EXVw3xCortW AJFJvD4Ika6mJme0X3TmcpW7kIBGhYOxoEZ3yn0TztoQlVHQJ4ntLpzQzyaZiiDFPB+8 a5Cv7Y8z1icbl+uwbsnJ4onrjttXddsKu5i9GX7j+/5atvSZdujvFtxkjHNYs8+//h14 1jeZEX8Cydu4fQRN4ilsCjOACHgUb6xBBbBXlsgQx2BKs0hKGTIDxph36GWQqLw1FrUC ByDaqvMHUt/w14ErdbZo41jOAFxqqUwUxh2+Z6uuEb1t2L6P199SflDzEgzmRfmQxFD7 eJ6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=xY0S9gJi71xTR/vKflK4Sl9yGqw9bAVlckJoovjy5wc=; fh=EIH9XAmicvPIUSP7TBeBhZ/WaoqG49JQ3xV1i3Gl7Co=; b=HmebltTMyBhmmIW7c+LiZiCMfU7l/vKzp9SvRbhGby5sYOUmmMtLUbVSivxn9tN9Fp o1O3v/A0b1wtP6qj0AlkFPEjUDrAiXWI6TH4Q4j6/oalzlMk11m/mWS5s/5IUblWR6DJ +j/KY2XdKMRXMwJHkEaqVS8LklPe6vI6DRTpY9h121tAVMc235qYcHe1Lkna1k2qNrbW 3PhYqTlSRzJlkoYTQ9VEVWXwyDNwhY+yqlowWmXWs/pNTSLwKDeBPbkDqnLEN1cqbp0Z 0iqROpaqYz8cVmirBMhWEjuTD/j11DBfIzqvyZlkQ60OJcY2aY0jkSYhK1PeEHa/C+MQ OVaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=X+MWzRpf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id na4-20020a17090b4c0400b00271c377a534si1544345pjb.104.2023.10.31.14.18.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Oct 2023 14:18:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=X+MWzRpf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id B0724802EE5F; Tue, 31 Oct 2023 14:18:34 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346154AbjJaVRf (ORCPT + 99 others); Tue, 31 Oct 2023 17:17:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344912AbjJaVRZ (ORCPT ); Tue, 31 Oct 2023 17:17:25 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C040D109; Tue, 31 Oct 2023 14:17:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1698787042; x=1730323042; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=++mkG9B3kMmDCfs7d1/SaaE552BMSHkUeljuri62Pkg=; b=X+MWzRpffXXRslQ2iy+6AKlBkbBRKw2S6sO7dgwq8mPJF9haER1xNsgu SDC3lZh0haizvCUmTYRFN5bmzNYlqVEwvCbTXmHHxoYotQzzv0TbvFa6x zDiKVXJ92QtDCmjbdk0GJL4SD2/bIiKg9bb1XBaT3aqCkm3ReCMMYJma7 zp1gEFiJHfYswxuL14gGuMNtroocdZuQZEzgnbLXVFQnxVIHz32X2H1/x Qn1sotHkxrUAgVO+GamC0JHxLQBoiuSZPG+JGk5MkeLGil8HaqxB+LXwa el9qkLx/OdrJaBVlLBGKhqBq6JRsRVjkDG6aktBlY0Fy9FC5hm8qxlwh+ g==; X-IronPort-AV: E=McAfee;i="6600,9927,10880"; a="388197144" X-IronPort-AV: E=Sophos;i="6.03,266,1694761200"; d="scan'208";a="388197144" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Oct 2023 14:17:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10880"; a="884335012" X-IronPort-AV: E=Sophos;i="6.03,266,1694761200"; d="scan'208";a="884335012" Received: from agluck-desk3.sc.intel.com ([172.25.222.74]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Oct 2023 14:17:20 -0700 From: Tony Luck To: Fenghua Yu , Reinette Chatre , Peter Newman , Jonathan Corbet , Shuah Khan , x86@kernel.org Cc: Shaopeng Tan , James Morse , Jamie Iles , Babu Moger , Randy Dunlap , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, patches@lists.linux.dev, Tony Luck Subject: [PATCH v10 7/8] x86/resctrl: Sub NUMA Cluster detection and enable Date: Tue, 31 Oct 2023 14:17:07 -0700 Message-ID: <20231031211708.37390-8-tony.luck@intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231031211708.37390-1-tony.luck@intel.com> References: <20231020213100.123598-1-tony.luck@intel.com> <20231031211708.37390-1-tony.luck@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.3 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Tue, 31 Oct 2023 14:18:34 -0700 (PDT) There isn't a simple hardware bit that indicates whether a CPU is running in Sub NUMA Cluster (SNC) mode. Infer the state by comparing the ratio of NUMA nodes to L3 cache instances. When SNC mode is detected, reconfigure the RMID counters by updating the MSR_RMID_SNC_CONFIG MSR on each socket as CPUs are seen. Clearing bit zero of the MSR divides the RMIDs and renumbers the ones on the second SNC node to start from zero. Signed-off-by: Tony Luck --- Changes since v9 Expand h/w to hardware (commit and code comments) Remove "earlier commit" reference s/counnter/counter/ Check for offline CPUs and warn user SNC detection may be broken. arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/resctrl/core.c | 100 ++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index e3fa9cecd599..4285a5ee81fe 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1109,6 +1109,7 @@ #define MSR_IA32_QM_CTR 0xc8e #define MSR_IA32_PQR_ASSOC 0xc8f #define MSR_IA32_L3_CBM_BASE 0xc90 +#define MSR_RMID_SNC_CONFIG 0xca0 #define MSR_IA32_L2_CBM_BASE 0xd10 #define MSR_IA32_MBA_THRTL_BASE 0xd50 diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index 97d2a5a7dd41..034f9797e1fb 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -16,11 +16,14 @@ #define pr_fmt(fmt) "resctrl: " fmt +#include #include #include #include #include +#include +#include #include #include #include "internal.h" @@ -184,10 +187,10 @@ bool is_mba_sc(struct rdt_resource *r) /* * rdt_get_mb_table() - get a mapping of bandwidth(b/w) percentage values - * exposed to user interface and the h/w understandable delay values. + * exposed to user interface and the hardware understandable delay values. * * The non-linear delay values have the granularity of power of two - * and also the h/w does not guarantee a curve for configured delay + * and also the hardware does not guarantee a curve for configured delay * values vs. actual b/w enforced. * Hence we need a mapping that is pre calibrated so the user can * express the memory b/w as a percentage value. @@ -738,11 +741,42 @@ static void clear_closid_rmid(int cpu) wrmsr(MSR_IA32_PQR_ASSOC, 0, 0); } +/* + * The power-on reset value of MSR_RMID_SNC_CONFIG is 0x1 + * which indicates that RMIDs are configured in legacy mode. + * This mode is incompatible with Linux resctrl semantics + * as RMIDs are partitioned between SNC nodes, which requires + * a user to know which RMID is allocated to a task. + * Clearing bit 0 reconfigures the RMID counters for use + * in Sub NUMA Cluster mode. This mode is better for Linux. + * The RMID space is divided between all SNC nodes with the + * RMIDs renumbered to start from zero in each node when + * couning operations from tasks. Code to read the counters + * must adjust RMID counter numbers based on SNC node. See + * __rmid_read() for code that does this. + */ +static void snc_remap_rmids(int cpu) +{ + u64 val; + + /* Only need to enable once per package. */ + if (cpumask_first(topology_core_cpumask(cpu)) != cpu) + return; + + rdmsrl(MSR_RMID_SNC_CONFIG, val); + val &= ~BIT_ULL(0); + wrmsrl(MSR_RMID_SNC_CONFIG, val); +} + static int resctrl_online_cpu(unsigned int cpu) { struct rdt_resource *r; mutex_lock(&rdtgroup_mutex); + + if (snc_nodes_per_l3_cache > 1) + snc_remap_rmids(cpu); + for_each_capable_rdt_resource(r) domain_add_cpu(cpu, r); /* The cpu is set in default rdtgroup after online. */ @@ -997,11 +1031,73 @@ static __init bool get_rdt_resources(void) return (rdt_mon_capable || rdt_alloc_capable); } +/* CPU models that support MSR_RMID_SNC_CONFIG */ +static const struct x86_cpu_id snc_cpu_ids[] __initconst = { + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0), + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 0), + X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, 0), + X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X, 0), + {} +}; + +/* + * There isn't a simple hardware bit that indicates whether a CPU is running + * in Sub NUMA Cluster (SNC) mode. Infer the state by comparing the + * ratio of NUMA nodes to L3 cache instances. + * It is not possible to accurately determine SNC state if the system is + * booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes + * to L3 caches. It will be OK if system is booted with hyperthreading + * disabled (since this doesn't affect the ratio). + */ +static __init int snc_get_config(void) +{ + unsigned long *node_caches; + int mem_only_nodes = 0; + int cpu, node, ret; + int num_l3_caches; + + if (!x86_match_cpu(snc_cpu_ids)) + return 1; + + node_caches = bitmap_zalloc(nr_node_ids, GFP_KERNEL); + if (!node_caches) + return 1; + + cpus_read_lock(); + + if (num_online_cpus() != num_present_cpus()) + pr_warn("Some CPUs offline, SNC detection may be incorrect\n"); + + for_each_node(node) { + cpu = cpumask_first(cpumask_of_node(node)); + if (cpu < nr_cpu_ids) + set_bit(get_cpu_cacheinfo_id(cpu, 3), node_caches); + else + mem_only_nodes++; + } + cpus_read_unlock(); + + num_l3_caches = bitmap_weight(node_caches, nr_node_ids); + kfree(node_caches); + + if (!num_l3_caches) + return 1; + + ret = (nr_node_ids - mem_only_nodes) / num_l3_caches; + + if (ret > 1) + rdt_resources_all[RDT_RESOURCE_L3].r_resctrl.mon_scope = RESCTRL_NODE; + + return ret; +} + static __init void rdt_init_res_defs_intel(void) { struct rdt_hw_resource *hw_res; struct rdt_resource *r; + snc_nodes_per_l3_cache = snc_get_config(); + for_each_rdt_resource(r) { hw_res = resctrl_to_arch_res(r); -- 2.41.0