From nobody Mon May 25 08:12:38 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B25783D6CB9 for ; Fri, 15 May 2026 16:31:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778862677; cv=none; b=A267ZY7hVNfiZsmQ/Wq2e/vsaNCACOY7HGvfjSPMnoz4AyqLEq+1HKLI13agv6YX5Npo38DY+jaGmSww+BetgttWAMIsncN3fcLp2KsjCxDm94B4Lxj2+CiQJny7q4PcspNYfRtjx87XV3jJrLOiLby/ewxZ9gnEdVbtnOnq1hA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778862677; c=relaxed/simple; bh=KNR0O4yT804vNnna7721gdTD+kRDZ6wZRm4PB8VyROg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=SX0YcNa4s0obb5fgmtYUc9ARuvcaaYnabcqK/6yjucCmY9E2OUQ3ZktK4ESAfPBpevkF1ubs9CYk8EQXfwm9uMASXCb8LEeLYaTpEgG5zCUrJkMYZIvIiEvUOGSDJawyKLaz22E7of2rh9cs+mc6eXsjzT9gUby8Byo7N3/4rIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GdK2AGCX; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GdK2AGCX" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-48d102471a4so92214325e9.2 for ; Fri, 15 May 2026 09:31:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778862674; x=1779467474; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=o6G9ueckfWCoDGV4axLh/GWpHoVQw0VPdfoo27FG+js=; b=GdK2AGCXd3jym/3GKejybuExGjPffEXpXBG3A3OUB0vEMI2NI9Xncbcs9k15bwMoRm DiMzR1NlRxN9xLyV7I1c8GbvcR0XaxmIMvMy59SLOGvav/nGRL6ZZIRmlLW8WDeRZdH3 pd9tSDiRBD9mCzjkSJzL037EJ278HgOhcI2UzyOOrnb+YeLqAsUqCV+n5GvEXU8FRIVh lmWre04E31qc/Q8dgyUzHFh7KItCemwZzqw5MNYgm9GPTzI4wj13Yz3EJPOWXjOYhKXI 8RKO2nnNf77dM1hB2mV+2hMcXY9KlWTr3nLRfBbR4D0mvqp6WulL3jM01cnDVHTH/Aju C1WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778862674; x=1779467474; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=o6G9ueckfWCoDGV4axLh/GWpHoVQw0VPdfoo27FG+js=; b=ZjOQwoD3+7FlccwW0QwKyZ6+Y/cfMuvE7srWH84RMwBlR3TAP8rb6j6lxguKw1XBva x3RkRPV3qC4Bz9ScPf9GDAF9qk6aocg7LvmC2tB5+uRAKXbAb6IGX3/+gDmmxsY+awzi Vl4si9VE4T2gsfNavyMKhYs3pCBYTjM1KYlB839A6DQL53nAgeTwY/LG+UEWGoRcaJDy wWLf4c3Sq3wugd13hHqfOVSV/quQ1akA6b4ZvFgKcl42kcCJuJ+4FtEpj/uCjPFbJYgL SK9fQhIf2Zltg6uZQntfpGDuDuNMGHffMf5mkq+sisw5pF31+wQ1mQybtyxnrKkxbwLx 6f8A== X-Gm-Message-State: AOJu0Ywv1UkhaIiUVaVDDmVj2eqGmh+eRHy2XH8GW7H37zoBo/NTt6GU 7GARHYXqF1+qSMbfaKAzYJrbBS6KDG3fP1GFMv+eJl/ga083N4F4gSVw X-Gm-Gg: Acq92OE4h/8naRAEWbL04Z9FZaVFSA67hPCmbi4gHEYALHp0jR8kd0r0bY/8dd2CXkW TTV5Fhaw88CRK9LNhYcKsC3Q1e/ceRiGxAr8D/bMj/7dQjLHLZSYMM6YNYLpwdlsP2CPvrtexVw TAsQbgVuX51JE4uxKY0Pec9VGeGTKSu/C/8IVhxw9QCsUnwKZ+JPVheBRmE4xYOCPZEKzIsTuLM 8n7iXnfNtNsTChMY9pk92fOmdo8fYKppshvSfF1RIM/pWfgUGK8ErxyUXy8yzbE/LevLxcjk7GO 9lq1EaqzpOjloR36xA22LmLC6UXW6+dznNc3XvTxMHKSB0kkJPQ6G1ZrriO2/XRlpSGjZi/1vvV 7kWnc5Yvi7D+0IoNz9KnJjkbivcaaF3SZCxjj1ASUl2wqEh7pCqM6+rt84Qop1smV13kraVBjzz 5UMFyp1EYO/U7ZQIvTBxc= X-Received: by 2002:a05:600c:34ce:b0:48a:592c:e63d with SMTP id 5b1f17b1804b1-48fe60d7832mr74084615e9.14.1778862673725; Fri, 15 May 2026 09:31:13 -0700 (PDT) Received: from fedora-dev ([46.10.223.24]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48fe5694f2csm71015515e9.4.2026.05.15.09.31.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 May 2026 09:31:13 -0700 (PDT) From: "Nikola Z. Ivanov" To: kprateek.nayak@amd.com, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, puwen@hygon.cn, mario.limonciello@amd.com, yazen.ghannam@amd.com, andrew.cooper3@citrix.com, me@mixaill.net, kai.huang@intel.com, i@rong.moe, sohil.mehta@intel.com, peterz@infradead.org, xin@zytor.com, seanjc@google.com, pawan.kumar.gupta@linux.intel.com, nikunj@amd.com, ptesarik@suse.com, nik.borisov@suse.com, darwi@linutronix.de, suchitkarunakaran@gmail.com, x86@kernel.org Cc: linux-kernel@vger.kernel.org, "Nikola Z. Ivanov" Subject: [PATCH v2] x86/topology: Unify srat_detect_node among amd and hygon Date: Fri, 15 May 2026 19:31:05 +0300 Message-ID: <20260515163105.414436-1-zlatistiv@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since the amd and hygon srat_detect_node implementation is practically identical the code can be shared. Move the implementation to common.c and expose it in arch/x86/kernel/cpu/cpu.h for code in arch/x86/kernel/cpu/ to use. For intel the separate implementation is kept to stay consistent with its behavior. Signed-off-by: Nikola Z. Ivanov --- Changes since v1: - Abandon the idea for using the same function for intel, also move the function to another file and limit its scope to x86 https://lore.kernel.org/all/dcfd7282-f722-46ea-b35c-2ab1333ca0d8@gmail.co= m/ arch/x86/kernel/cpu/amd.c | 74 ------------------------------------ arch/x86/kernel/cpu/common.c | 73 +++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/cpu.h | 1 + arch/x86/kernel/cpu/hygon.c | 73 ----------------------------------- arch/x86/kernel/cpu/intel.c | 4 +- 5 files changed, 76 insertions(+), 149 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 2f8e8ff2d000..f317c6bdcf5d 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -277,80 +277,6 @@ static void init_amd_k7(struct cpuinfo_x86 *c) #endif } =20 -#ifdef CONFIG_NUMA -/* - * To workaround broken NUMA config. Read the comment in - * srat_detect_node(). - */ -static int nearby_node(int apicid) -{ - int i, node; - - for (i =3D apicid - 1; i >=3D 0; i--) { - node =3D __apicid_to_node[i]; - if (node !=3D NUMA_NO_NODE && node_online(node)) - return node; - } - for (i =3D apicid + 1; i < MAX_LOCAL_APIC; i++) { - node =3D __apicid_to_node[i]; - if (node !=3D NUMA_NO_NODE && node_online(node)) - return node; - } - return first_node(node_online_map); /* Shouldn't happen */ -} -#endif - -static void srat_detect_node(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_NUMA - int cpu =3D smp_processor_id(); - int node; - unsigned apicid =3D c->topo.apicid; - - node =3D numa_cpu_node(cpu); - if (node =3D=3D NUMA_NO_NODE) - node =3D per_cpu_llc_id(cpu); - - /* - * On multi-fabric platform (e.g. Numascale NumaChip) a - * platform-specific handler needs to be called to fixup some - * IDs of the CPU. - */ - if (x86_cpuinit.fixup_cpu_id) - x86_cpuinit.fixup_cpu_id(c, node); - - if (!node_online(node)) { - /* - * Two possibilities here: - * - * - The CPU is missing memory and no node was created. In - * that case try picking one from a nearby CPU. - * - * - The APIC IDs differ from the HyperTransport node IDs - * which the K8 northbridge parsing fills in. Assume - * they are all increased by a constant offset, but in - * the same order as the HT nodeids. If that doesn't - * result in a usable node fall back to the path for the - * previous case. - * - * This workaround operates directly on the mapping between - * APIC ID and NUMA node, assuming certain relationship - * between APIC ID, HT node ID and NUMA topology. As going - * through CPU mapping may alter the outcome, directly - * access __apicid_to_node[]. - */ - int ht_nodeid =3D c->topo.initial_apicid; - - if (__apicid_to_node[ht_nodeid] !=3D NUMA_NO_NODE) - node =3D __apicid_to_node[ht_nodeid]; - /* Pick a nearby node */ - if (!node_online(node)) - node =3D nearby_node(apicid); - } - numa_set_node(cpu, node); -#endif -} - static void bsp_determine_snp(struct cpuinfo_x86 *c) { #ifdef CONFIG_ARCH_HAS_CC_PLATFORM diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a4268c47f2bc..a0d7c7c47153 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2518,6 +2518,79 @@ void cpu_init(void) load_fixmap_gdt(cpu); } =20 +#ifdef CONFIG_NUMA +/* + * To workaround broken NUMA config. Read the comment in + * srat_detect_node(). + */ +static int nearby_node(int apicid) +{ + int i, node; + + for (i =3D apicid - 1; i >=3D 0; i--) { + node =3D __apicid_to_node[i]; + if (node !=3D NUMA_NO_NODE && node_online(node)) + return node; + } + for (i =3D apicid + 1; i < MAX_LOCAL_APIC; i++) { + node =3D __apicid_to_node[i]; + if (node !=3D NUMA_NO_NODE && node_online(node)) + return node; + } + return first_node(node_online_map); /* Shouldn't happen */ +} +#endif + +void srat_detect_node(struct cpuinfo_x86 *c) +{ +#ifdef CONFIG_NUMA + int cpu =3D smp_processor_id(); + int node; + unsigned int apicid =3D c->topo.apicid; + + node =3D numa_cpu_node(cpu); + if (node =3D=3D NUMA_NO_NODE) + node =3D c->topo.llc_id; + + /* + * On multi-fabric platform (e.g. Numascale NumaChip) a + * platform-specific handler needs to be called to fixup some + * IDs of the CPU. + */ + if (x86_cpuinit.fixup_cpu_id) + x86_cpuinit.fixup_cpu_id(c, node); + + if (!node_online(node)) { + /* + * Two possibilities here: + * + * - The CPU is missing memory and no node was created. In + * that case try picking one from a nearby CPU. + * + * - The APIC IDs differ from the HyperTransport node IDs. + * Assume they are all increased by a constant offset, but + * in the same order as the HT nodeids. If that doesn't + * result in a usable node fall back to the path for the + * previous case. + * + * This workaround operates directly on the mapping between + * APIC ID and NUMA node, assuming certain relationship + * between APIC ID, HT node ID and NUMA topology. As going + * through CPU mapping may alter the outcome, directly + * access __apicid_to_node[]. + */ + int ht_nodeid =3D c->topo.initial_apicid; + + if (__apicid_to_node[ht_nodeid] !=3D NUMA_NO_NODE) + node =3D __apicid_to_node[ht_nodeid]; + /* Pick a nearby node */ + if (!node_online(node)) + node =3D nearby_node(apicid); + } + numa_set_node(cpu, node); +#endif +} + #ifdef CONFIG_MICROCODE_LATE_LOADING /** * store_cpu_caps() - Store a snapshot of CPU capabilities diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 5c7a3a71191a..04e73ff9a153 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -65,6 +65,7 @@ extern void check_null_seg_clears_base(struct cpuinfo_x86= *c); =20 void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c); +void srat_detect_node(struct cpuinfo_x86 *c); =20 #if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS) struct amd_northbridge *amd_init_l3_cache(int index); diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c index 7f95a74e4c65..a33735094843 100644 --- a/arch/x86/kernel/cpu/hygon.c +++ b/arch/x86/kernel/cpu/hygon.c @@ -20,79 +20,6 @@ =20 #include "cpu.h" =20 -#ifdef CONFIG_NUMA -/* - * To workaround broken NUMA config. Read the comment in - * srat_detect_node(). - */ -static int nearby_node(int apicid) -{ - int i, node; - - for (i =3D apicid - 1; i >=3D 0; i--) { - node =3D __apicid_to_node[i]; - if (node !=3D NUMA_NO_NODE && node_online(node)) - return node; - } - for (i =3D apicid + 1; i < MAX_LOCAL_APIC; i++) { - node =3D __apicid_to_node[i]; - if (node !=3D NUMA_NO_NODE && node_online(node)) - return node; - } - return first_node(node_online_map); /* Shouldn't happen */ -} -#endif - -static void srat_detect_node(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_NUMA - int cpu =3D smp_processor_id(); - int node; - unsigned int apicid =3D c->topo.apicid; - - node =3D numa_cpu_node(cpu); - if (node =3D=3D NUMA_NO_NODE) - node =3D c->topo.llc_id; - - /* - * On multi-fabric platform (e.g. Numascale NumaChip) a - * platform-specific handler needs to be called to fixup some - * IDs of the CPU. - */ - if (x86_cpuinit.fixup_cpu_id) - x86_cpuinit.fixup_cpu_id(c, node); - - if (!node_online(node)) { - /* - * Two possibilities here: - * - * - The CPU is missing memory and no node was created. In - * that case try picking one from a nearby CPU. - * - * - The APIC IDs differ from the HyperTransport node IDs. - * Assume they are all increased by a constant offset, but - * in the same order as the HT nodeids. If that doesn't - * result in a usable node fall back to the path for the - * previous case. - * - * This workaround operates directly on the mapping between - * APIC ID and NUMA node, assuming certain relationship - * between APIC ID, HT node ID and NUMA topology. As going - * through CPU mapping may alter the outcome, directly - * access __apicid_to_node[]. - */ - int ht_nodeid =3D c->topo.initial_apicid; - - if (__apicid_to_node[ht_nodeid] !=3D NUMA_NO_NODE) - node =3D __apicid_to_node[ht_nodeid]; - /* Pick a nearby node */ - if (!node_online(node)) - node =3D nearby_node(apicid); - } - numa_set_node(cpu, node); -#endif -} - static void bsp_init_hygon(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index f28c0efb7c8f..0c34ec32baec 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -468,7 +468,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) } #endif =20 -static void srat_detect_node(struct cpuinfo_x86 *c) +static void srat_detect_node_intel(struct cpuinfo_x86 *c) { #ifdef CONFIG_NUMA unsigned node; @@ -614,7 +614,7 @@ static void init_intel(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_PREFER_YMM); =20 /* Work around errata */ - srat_detect_node(c); + srat_detect_node_intel(c); =20 init_ia32_feat_ctl(c); =20 --=20 2.53.0