mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
hwmon: (coretemp) Fix handling of isolated SMT siblings
Commit0f8b916bc5("hwmon: (coretemp) avoid RDMSR interrupts to isolated CPUs") prevents create_core_data() from creating temperature data for an isolated CPU. coretemp_cpu_online(), however, still adds that CPU to pdata->cpumask. When an isolated SMT thread is processed before a housekeeping sibling, the mask makes coretemp_cpu_online() believe that the core is already represented. The housekeeping sibling then gets no temperature attributes. Package attributes are similarly not retried when the first CPU processed in a die is isolated. The mask is also used to select a replacement CPU when a sensor target goes offline. Including isolated CPUs permits the driver to retarget a sensor to one, causing subsequent sysfs reads to send an RDMSR IPI to an isolated CPU. Keep isolated CPUs out of pdata->cpumask by moving the housekeeping check to coretemp_cpu_online(). Sensor creation is then deferred to an eligible CPU, and hotplug replacement targets remain on housekeeping CPUs. Tested on an Intel Core i7-10510U running 6.18.50-3-cachyos-lts, with nohz_full=1 on CPU 1 and its housekeeping SMT sibling on CPU 5. The stock driver omitted Core 1 after module load and retained its readable sensor after CPU 5 was offlined. The patched driver exposed Core 1, removed it when CPU 5 went offline, and restored it when CPU 5 returned. Fixes:0f8b916bc5("hwmon: (coretemp) avoid RDMSR interrupts to isolated CPUs") Cc: stable@vger.kernel.org Cc: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Ximing Zhang <xzhangjr@gmail.com> Tested-by: Asaf Nuri Bertizlioğlu <ycistak@gmail.com> Link: https://patch.msgid.link/20261016-codex-coretemp-housekeeping-v1-1-96618c5676b2@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
8e9bd28236
commit
37c1974a0e
|
|
@ -568,9 +568,6 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
|
|||
u64 val;
|
||||
int err;
|
||||
|
||||
if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
|
||||
return 0;
|
||||
|
||||
tdata = init_temp_data(pdata, cpu, pkg_flag);
|
||||
if (!tdata)
|
||||
return -ENOMEM;
|
||||
|
|
@ -690,6 +687,14 @@ static int coretemp_cpu_online(unsigned int cpu)
|
|||
if (!cpu_has(c, X86_FEATURE_DTHERM))
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Keep isolated CPUs out of pdata->cpumask. Besides tracking the CPUs
|
||||
* available to this driver, the mask is used to select the CPU on which
|
||||
* to read the temperature MSRs.
|
||||
*/
|
||||
if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
|
||||
return 0;
|
||||
|
||||
pdata = platform_get_drvdata(pdev);
|
||||
if (!pdata->hwmon_dev) {
|
||||
struct device *hwmon;
|
||||
|
|
@ -719,8 +724,8 @@ static int coretemp_cpu_online(unsigned int cpu)
|
|||
}
|
||||
|
||||
/*
|
||||
* Check whether a thread sibling is already online. If not add the
|
||||
* interface for this CPU core.
|
||||
* Check whether a housekeeping thread sibling is already online. If
|
||||
* not, add the interface for this CPU core.
|
||||
*/
|
||||
if (!cpumask_intersects(&pdata->cpumask, topology_sibling_cpumask(cpu)))
|
||||
coretemp_add_core(pdev, cpu, 0);
|
||||
|
|
@ -750,9 +755,9 @@ static int coretemp_cpu_offline(unsigned int cpu)
|
|||
cpumask_clear_cpu(cpu, &pd->cpumask);
|
||||
|
||||
/*
|
||||
* If this is the last thread sibling, remove the CPU core
|
||||
* interface, If there is still a sibling online, transfer the
|
||||
* target cpu of that core interface to it.
|
||||
* If this is the last housekeeping thread sibling, remove the CPU core
|
||||
* interface. If there is still a housekeeping sibling online, transfer
|
||||
* the target CPU of that core interface to it.
|
||||
*/
|
||||
target = cpumask_any_and(&pd->cpumask, topology_sibling_cpumask(cpu));
|
||||
if (target >= nr_cpu_ids) {
|
||||
|
|
@ -764,7 +769,8 @@ static int coretemp_cpu_offline(unsigned int cpu)
|
|||
}
|
||||
|
||||
/*
|
||||
* If all cores in this pkg are offline, remove the interface.
|
||||
* If all housekeeping cores in this pkg are offline, remove the
|
||||
* interface.
|
||||
*/
|
||||
tdata = get_temp_data(pd, -1);
|
||||
if (cpumask_empty(&pd->cpumask)) {
|
||||
|
|
@ -777,7 +783,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
|
|||
|
||||
/*
|
||||
* Check whether this core is the target for the package
|
||||
* interface. We need to assign it to some other cpu.
|
||||
* interface. We need to assign it to some other housekeeping CPU.
|
||||
*/
|
||||
if (tdata && tdata->cpu == cpu) {
|
||||
target = cpumask_first(&pd->cpumask);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user