From nobody Sat Apr 11 11:10:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1E2EC25B0E for ; Fri, 12 Aug 2022 16:38:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239114AbiHLQiR (ORCPT ); Fri, 12 Aug 2022 12:38:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238656AbiHLQiI (ORCPT ); Fri, 12 Aug 2022 12:38:08 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D551AABF2A; Fri, 12 Aug 2022 09:38:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660322286; x=1691858286; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=NUyQpSQ+bGRYNVMYb0DJKJiMv8VBcicLoCZ/INNs+rE=; b=EH+3kezdI0bVzq4z2chqDwwmF3SzvzgjdxFfqxAXmHHEHAI3lQwoMWIZ 9jdEfz69UnKmXrGLr5aiuf9TdgIMDL9n7zc36IXJhuWAH4KsHJh3Fgny3 1kq3qVawFaJKMkrWesf8e80neR50EYiqqNZQUJx47D3AuoQucWMaTb3G4 qFVXoPCgIbTcv2gqL3dl9FVUgdbVZSfIh0YlR0bOpcc0BLpJ3ecqV30ny XfuXxxUc7qsD9fEvaGugBKCpj9HQ87ufkVoxGs37k4lJXJbK+FH3uZ3OZ onkcLg85FEdmKj50BLpdLv6cZWXtQBrpGJueZmRD7WOpjeZlcFyo3p4Uc w==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="377921603" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="377921603" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 09:38:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="782012297" Received: from power-sh.sh.intel.com ([10.239.183.122]) by orsmga005.jf.intel.com with ESMTP; 12 Aug 2022 09:38:03 -0700 From: Zhang Rui To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-hwmon@vger.kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, corbet@lwn.net, fenghua.yu@intel.com, jdelvare@suse.com, linux@roeck-us.net, len.brown@intel.com, rui.zhang@intel.com Subject: [PATCH 3/7] hwmon/coretemp: Handle large core id value Date: Sat, 13 Aug 2022 00:41:40 +0800 Message-Id: <20220812164144.30829-4-rui.zhang@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220812164144.30829-1-rui.zhang@intel.com> References: <20220812164144.30829-1-rui.zhang@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The coretemp driver supports up to a hard-coded limit of 128 cores. Today, the driver can not support a core with an id above that limit. Yet, the encoding of core_id's is arbitrary (BIOS APIC-id) and so they may be sparse and they may be large. Update the driver to map arbitrary core_id numbers into appropriate array indexes so that 128 cores can be supported, no matter the encoding of core_ids's. Acked-by: Len Brown Signed-off-by: Zhang Rui Acked-by: Guenter Roeck --- drivers/hwmon/coretemp.c | 55 +++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index ccf0af5b988a..3f0f7d7612ae 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -46,9 +46,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) =20 -#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id) -#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) - #ifdef CONFIG_SMP #define for_each_sibling(i, cpu) \ for_each_cpu(i, topology_sibling_cpumask(cpu)) @@ -91,6 +88,8 @@ struct temp_data { struct platform_data { struct device *hwmon_dev; u16 pkg_id; + u16 cpu_map[NUM_REAL_CORES]; + struct ida ida; struct cpumask cpumask; struct temp_data *core_data[MAX_CORE_DATA]; struct device_attribute name_attr; @@ -441,7 +440,7 @@ static struct temp_data *init_temp_data(unsigned int cp= u, int pkg_flag) MSR_IA32_THERM_STATUS; tdata->is_pkg_data =3D pkg_flag; tdata->cpu =3D cpu; - tdata->cpu_core_id =3D TO_CORE_ID(cpu); + tdata->cpu_core_id =3D topology_core_id(cpu); tdata->attr_size =3D MAX_CORE_ATTRS; mutex_init(&tdata->update_lock); return tdata; @@ -454,7 +453,7 @@ static int create_core_data(struct platform_device *pde= v, unsigned int cpu, struct platform_data *pdata =3D platform_get_drvdata(pdev); struct cpuinfo_x86 *c =3D &cpu_data(cpu); u32 eax, edx; - int err, attr_no; + int err, index, attr_no; =20 /* * Find attr number for sysfs: @@ -462,14 +461,26 @@ static int create_core_data(struct platform_device *p= dev, unsigned int cpu, * The attr number is always core id + 2 * The Pkgtemp will always show up as temp1_*, if available */ - attr_no =3D pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu); + if (pkg_flag) + attr_no =3D PKG_SYSFS_ATTR_NO; + else { + index =3D ida_alloc(&pdata->ida, GFP_KERNEL); + if (index < 0) + return index; + pdata->cpu_map[index] =3D topology_core_id(cpu); + attr_no =3D index + BASE_SYSFS_ATTR_NO; + } =20 - if (attr_no > MAX_CORE_DATA - 1) - return -ERANGE; + if (attr_no > MAX_CORE_DATA - 1) { + err =3D -ERANGE; + goto ida_free; + } =20 tdata =3D init_temp_data(cpu, pkg_flag); - if (!tdata) - return -ENOMEM; + if (!tdata) { + err =3D -ENOMEM; + goto ida_free; + } =20 /* Test if we can access the status register */ err =3D rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx); @@ -505,6 +516,9 @@ static int create_core_data(struct platform_device *pde= v, unsigned int cpu, exit_free: pdata->core_data[attr_no] =3D NULL; kfree(tdata); +ida_free: + if (!pkg_flag) + ida_free(&pdata->ida, index); return err; } =20 @@ -524,6 +538,8 @@ static void coretemp_remove_core(struct platform_data *= pdata, int indx) =20 kfree(pdata->core_data[indx]); pdata->core_data[indx] =3D NULL; + + ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); } =20 static int coretemp_probe(struct platform_device *pdev) @@ -537,6 +553,7 @@ static int coretemp_probe(struct platform_device *pdev) return -ENOMEM; =20 pdata->pkg_id =3D pdev->id; + ida_init(&pdata->ida); platform_set_drvdata(pdev, pdata); =20 pdata->hwmon_dev =3D devm_hwmon_device_register_with_groups(dev, DRVNAME, @@ -553,6 +570,7 @@ static int coretemp_remove(struct platform_device *pdev) if (pdata->core_data[i]) coretemp_remove_core(pdata, i); =20 + ida_destroy(&pdata->ida); return 0; } =20 @@ -647,7 +665,7 @@ static int coretemp_cpu_offline(unsigned int cpu) struct platform_device *pdev =3D coretemp_get_pdev(cpu); struct platform_data *pd; struct temp_data *tdata; - int indx, target; + int i, indx =3D -1, target; =20 /* * Don't execute this on suspend as the device remove locks @@ -660,12 +678,19 @@ static int coretemp_cpu_offline(unsigned int cpu) if (!pdev) return 0; =20 - /* The core id is too big, just return */ - indx =3D TO_ATTR_NO(cpu); - if (indx > MAX_CORE_DATA - 1) + pd =3D platform_get_drvdata(pdev); + + for (i =3D 0; i < NUM_REAL_CORES; i++) { + if (pd->cpu_map[i] =3D=3D topology_core_id(cpu)) { + indx =3D i + BASE_SYSFS_ATTR_NO; + break; + } + } + + /* Too many cores and this core is not pupolated, just return */ + if (indx < 0) return 0; =20 - pd =3D platform_get_drvdata(pdev); tdata =3D pd->core_data[indx]; =20 cpumask_clear_cpu(cpu, &pd->cpumask); --=20 2.34.1