From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 704C33E5ED3 for ; Tue, 3 Mar 2026 11:05:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772535925; cv=none; b=H3nJ4qdKpLqRLsYyqItu5VB8RUKYpRoipv+6heHKPmJWuFmLcgxWxSGhB9KQavFNI54//brFp7bHGtvx1jD+35MKqahmWk86kfIKpG4dQQq7+4lgSZDNRYchKU+BzKYhzCdDp0PzgordIpSmKF3QZWCCHL63Sm1a0oySmE9nYRM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772535925; c=relaxed/simple; bh=Qnv/t+W4ZTEiDjISANsUlcqYS6+xn6PbNkwN213qrh8=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=GjjzAQhvtb/zte/EvwWvDYzM0zRQJ/1RaLdRMKrpn/5C+1odPpexaHwqmqizfZ5Jsr9I6nvQZurRfmmRSGQ/98wa/KgG/QuUIIBz8gbSw8k0iILQcmMPT3DYgP7vuLkpIClTDfX9/+w23OGv1+iddDrfDO13gyBsxueUsMj0q5s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=S+2ibwnF; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="S+2ibwnF" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:References: Subject:Cc:To:From:Date:Message-ID:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:In-Reply-To; bh=ttbCJ8rSOstofOWjXu6KKCoNuH0CTRx+fXGzwHkK+L8=; b=S+2ibwnFF/FNjccUL6TN13inCT oRfR98o1QrTkcDLNmg5nMJe3hadDcpPsGGdkqVhsgxdD8S/3eStgKeI4+1zwDOzGAuQuTOP7oE4hB jM81EVK1Yxs/fu82HIIHvAiSwG77HoiCUbLiASYD2j3Ely73ZQhqgPmSnN1VvOXWiFiRz5G0Z5gBc 01JvRrZN6shtY108UkYLQx8LMaMweheNJdsbJzNPQCZpVyQRAQHE7UiO3Ue7hFicb2oSaU1ncyu5n zpdVqD26EQ3JtHPX0hltYt1gaJJQQh+P2rWcmaaHBvIah6+AXHggb46VgkONxhDhNFMPy1eenQit3 mW+3pejQ==; Received: from 77-249-17-252.cable.dynamic.v4.ziggo.nl ([77.249.17.252] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.98.2 #2 (Red Hat Linux)) id 1vxNYu-0000000BNmf-0W6i; Tue, 03 Mar 2026 11:05:12 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 0) id 2A5A63031CA; Tue, 03 Mar 2026 12:05:09 +0100 (CET) Message-ID: <20260303110100.004091624@infradead.org> User-Agent: quilt/0.68 Date: Tue, 03 Mar 2026 11:55:41 +0100 From: Peter Zijlstra To: x86@kernel.org, tglx@kernel.org Cc: linux-kernel@vger.kernel.org, peterz@infradead.org, tim.c.chen@linux.intel.com, yu.c.chen@intel.com, kyle.meyer@hpe.com, vinicius.gomes@intel.com, brgerst@gmail.com, hpa@zytor.com, kprateek.nayak@amd.com, patryk.wlazlyn@linux.intel.com, rafael.j.wysocki@intel.com, russ.anderson@hpe.com, zhao1.liu@intel.com, tony.luck@intel.com, Zhang Rui Subject: [PATCH v2 2/5] x86/topo: Add topology_num_nodes_per_package() References: <20260303105539.428037056@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Use the MADT and SRAT table data to compute __num_nodes_per_package. Specifically, SRAT has already been parsed in x86_numa_init(), which is called before acpi_boot_init() which parses MADT. So both are available in topology_init_possible_cpus(). This number is useful to divinate the various Intel CoD/SNC and AMD NPS modes, since the platforms are failing to provide this otherwise. Doing it this way is independent of the number of online CPUs and other such shenanigans. Signed-off-by: Peter Zijlstra (Intel) Tested-by: Tony Luck Tested-by: K Prateek Nayak Tested-by: Zhang Rui Tested-by: Chen Yu Tested-by: Kyle Meyer --- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/kernel/cpu/common.c | 3 +++ arch/x86/kernel/cpu/topology.c | 13 +++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -155,6 +155,7 @@ extern unsigned int __max_logical_packag extern unsigned int __max_threads_per_core; extern unsigned int __num_threads_per_package; extern unsigned int __num_cores_per_package; +extern unsigned int __num_nodes_per_package; const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); @@ -179,6 +180,11 @@ static inline unsigned int topology_num_ return __num_threads_per_package; } +static inline unsigned int topology_num_nodes_per_package(void) +{ + return __num_nodes_per_package; +} + #ifdef CONFIG_X86_LOCAL_APIC int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level); #else --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package); unsigned int __max_logical_packages __ro_after_init = 1; EXPORT_SYMBOL(__max_logical_packages); +unsigned int __num_nodes_per_package __ro_after_init = 1; +EXPORT_SYMBOL(__num_nodes_per_package); + unsigned int __num_cores_per_package __ro_after_init = 1; EXPORT_SYMBOL(__num_cores_per_package); --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "cpu.h" @@ -492,11 +493,19 @@ void __init topology_init_possible_cpus( set_nr_cpu_ids(allowed); cnta = domain_weight(TOPO_PKG_DOMAIN); - cntb = domain_weight(TOPO_DIE_DOMAIN); __max_logical_packages = cnta; + + pr_info("Max. logical packages: %3u\n", __max_logical_packages); + + cntb = num_phys_nodes(); + __num_nodes_per_package = DIV_ROUND_UP(cntb, cnta); + + pr_info("Max. logical nodes: %3u\n", cntb); + pr_info("Num. nodes per package:%3u\n", __num_nodes_per_package); + + cntb = domain_weight(TOPO_DIE_DOMAIN); __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta)); - pr_info("Max. logical packages: %3u\n", cnta); pr_info("Max. logical dies: %3u\n", cntb); pr_info("Max. dies per package: %3u\n", __max_dies_per_package);