From nobody Thu Apr 9 09:10:49 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 4382B38E5C6; Mon, 9 Mar 2026 22:20:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094841; cv=none; b=W8qiKw+vke4dgnU5RYjrJuBR8tJ5lFgpIkk1xLiAiTU++zS6L/PJEsjxfyv6z4Yod5wpVxptIUvUy/Vj7WftWGucgTVCn2sVC976EVonatswmLpZNWEMr4LjK2wS5pztApvGoQnIa7YLOF3Oe6qPNHpxCQJErxNYLK5foJ0YH9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094841; c=relaxed/simple; bh=F1AQED94e08k0SWL58HdTlp1BKL2Y2eWIRKWsUfiHsM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A/xK/32SefQ7Zgn4ju0p+m4FpedrKgSbsS8J0p48/jjfZp88Pzmbx/+j+WRneTKUr8qDz4ggbKG6VGSU1lMiZZx+TieOdjZlkTSIPMA+397XwwnoyIMUzSHCaJ40wrGgwvDFPmSsisx7WN5ITrAs5DHch16qPjtLW8R9PM6mGYE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=mJmNNcmj; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="mJmNNcmj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773094839; x=1804630839; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=F1AQED94e08k0SWL58HdTlp1BKL2Y2eWIRKWsUfiHsM=; b=mJmNNcmjn9sOSuEc5j/4uf79fLqqlLdRS0eg+8rjVEIwuRrSUXJXsOy3 DEtc4xlZsNa2uE6wtlfwLS2/vf5zjFNyBwV/Cd0iBbjxgsEqEalrV2wvc xQ3QJ7gdq00+jiPop2eNadypgZioB9FHVZp0ay5esyU21UFFW6A+Qvgdv YCrfXXuSmTxRdJzIdodoQFwMno9fqq4IAw8tk+0o14BXvqi/7iZm+qlzT cyKzFAMDvNwsXwKAOYMGtrq0ZtkyiabJSaTmAvXQh88hixypDdo3dG6GY 5bQap2EHHsXokQfSmhicZhne8vOtB6i9ebAdu2RG7gxGupU0JaMSkOmKd w==; X-CSE-ConnectionGUID: pQQNaFotR4u7U/A3BOJl1g== X-CSE-MsgGUID: 5HGXUJY0RISI7QAEItEiZA== X-IronPort-AV: E=McAfee;i="6800,10657,11724"; a="74050652" X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="74050652" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:37 -0700 X-CSE-ConnectionGUID: oS8gFM29RE+/D9HXkweZuw== X-CSE-MsgGUID: zclN2n5gRMORG4UuEMICdg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="224004285" Received: from unknown (HELO [172.25.112.21]) ([172.25.112.21]) by orviesa003.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:38 -0700 From: Ricardo Neri Date: Mon, 09 Mar 2026 15:19:24 -0700 Subject: [PATCH 1/4] x86/thermal: Add bit definitions for Intel Directed Package Thermal Interrupt 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" Content-Transfer-Encoding: quoted-printable Message-Id: <20260309-rneri-directed-therm-intr-v1-1-2956e3000950@linux.intel.com> References: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> In-Reply-To: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Lukasz Luba Cc: x86@kernel.org, Srinivas Pandruvada , Zhang Rui , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Ricardo Neri , Ricardo Neri X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773094782; l=2125; i=ricardo.neri-calderon@linux.intel.com; s=20250602; h=from:subject:message-id; bh=F1AQED94e08k0SWL58HdTlp1BKL2Y2eWIRKWsUfiHsM=; b=H6Vj51EcgCI5yd90HGMxoxN57Vr7ICr4pOi3BDKA+E39ht382WGajio8ieeYCbR9gBBGahUEh gKwhWzrr/w7Dl3GldYyHlh8jCXfSYdwHjkW0DAhrvACsGoTPDXOFNGt X-Developer-Key: i=ricardo.neri-calderon@linux.intel.com; a=ed25519; pk=NfZw5SyQ2lxVfmNMaMR6KUj3+0OhcwDPyRzFDH9gY2w= Add CPUID and MSR bit definitions required to support Intel Directed Package Thermal Interrupts. A CPU requests directed package-level thermal interrupts by setting bit 25 in IA32_THERM_INTERRUPT. Hardware acknowledges by setting bit 25 in IA32_PACKAGE_THERM_STATUS, indicating that only CPUs that opted in will receive the interrupt. If no CPU in the package requests it, delivery falls back to broadcast. Signed-off-by: Ricardo Neri --- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/msr-index.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpuf= eatures.h index dbe104df339b..487bf9da0cef 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -364,6 +364,7 @@ #define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* "hwp_pkg_req" HWP Package L= evel Request */ #define X86_FEATURE_HWP_HIGHEST_PERF_CHANGE (14*32+15) /* HWP Highest perf= change */ #define X86_FEATURE_HFI (14*32+19) /* "hfi" Hardware Feedback Interface = */ +#define X86_FEATURE_DIRECTED_PKG_THRM_INTR (14*32+24) /* Intel Directed Pa= ckage Thermal Interrupt */ =20 /* AMD SVM Feature Identification, CPUID level 0x8000000a (EDX), word 15 */ #define X86_FEATURE_NPT (15*32+ 0) /* "npt" Nested Page Table support */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index 6673601246b3..aa1c652a9581 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -995,6 +995,7 @@ #define THERM_INT_HIGH_ENABLE (1 << 0) #define THERM_INT_LOW_ENABLE (1 << 1) #define THERM_INT_PLN_ENABLE (1 << 24) +#define THERM_DIRECTED_INTR_ENABLE (1 << 25) =20 #define MSR_IA32_THERM_STATUS 0x0000019c =20 @@ -1024,6 +1025,7 @@ =20 #define PACKAGE_THERM_STATUS_PROCHOT (1 << 0) #define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10) +#define PACKAGE_THERM_STATUS_DIRECTED_INTR_ACK (1 << 25) #define PACKAGE_THERM_STATUS_HFI_UPDATED (1 << 26) =20 #define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2 --=20 2.43.0 From nobody Thu Apr 9 09:10:49 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 03BFF38E5D5; Mon, 9 Mar 2026 22:20:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094843; cv=none; b=XHl2VgKiuXyMCMreioKqXCkeRok5DhoHlOXVRnTpXibRUwMwOuh1vb2R+Dhdz6yGI4v8qLyqing4dR04hAFEK4Kb99zi/xS1jbcEm6tuc0S9iQGAUNJONjImw2QaRWFoVeDvi0GjtFpdHGvWuh2bCb59olfA58RW9a5iWH4DOzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094843; c=relaxed/simple; bh=dGtxAS7nxtT0bG87r2Bb7PJl0WYrAo7+sx542XvvFpA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mIEheZG3gvgy4DV6mCNcJh+nT28Lvuek6zcbFwbgiGgqhiC8ziv43N4emh6NUwWYxxJ+edJf1+YT3Hl9mskjPkP6P612MxsGRMqarmE23NhCLdU11aSgh3mcVKeBCGWl4IB5CDk7PHEsOtbh3P0idXXOR+DJOJqtQMwPnHS4P34= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=auzjWCDg; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="auzjWCDg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773094841; x=1804630841; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=dGtxAS7nxtT0bG87r2Bb7PJl0WYrAo7+sx542XvvFpA=; b=auzjWCDgyuXGK7bNPcY4AlhKOwKI/aWA7yVTP7HWZwTrrWaslwO0iVUF e0rMKpG5o2uPXlffhkr4z8BTIkdOLeFxSP7M3ao4Ho0XdcakHE15INyjL /oy9jozOVJp4ZcIpEOyPpK/SQemGEITYqSOPkncN7UQpqfWmSurSnvkqb 3drprtfuIaeZn3wuudW6YAIN8ouzxRnJond9yMY9AWOIprvUoFHdespuV JDvolRQuxOTwUQlkzD/91CYZ/Bm3gaYHn261Ova8JNlLlzevYFC1cUtIP izIHqC7fcU+9BIKXHJqx2anLOV2FQTCInhSBaO5JLchu7Z/didaVSr43p g==; X-CSE-ConnectionGUID: a0Dg7BWIQzitOxNUf+KZyA== X-CSE-MsgGUID: aREHnR2mTVKerm1z5klyQA== X-IronPort-AV: E=McAfee;i="6800,10657,11724"; a="74050655" X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="74050655" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:38 -0700 X-CSE-ConnectionGUID: QUj/PMltRDCCgv3Hup0zrA== X-CSE-MsgGUID: Vw5EreVaT2anHHjL8bhZ7w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="224004289" Received: from unknown (HELO [172.25.112.21]) ([172.25.112.21]) by orviesa003.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:38 -0700 From: Ricardo Neri Date: Mon, 09 Mar 2026 15:19:25 -0700 Subject: [PATCH 2/4] thermal: intel: Enable Directed Package-level Thermal Interrupts 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" Content-Transfer-Encoding: quoted-printable Message-Id: <20260309-rneri-directed-therm-intr-v1-2-2956e3000950@linux.intel.com> References: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> In-Reply-To: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Lukasz Luba Cc: x86@kernel.org, Srinivas Pandruvada , Zhang Rui , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Ricardo Neri , Ricardo Neri X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773094782; l=8462; i=ricardo.neri-calderon@linux.intel.com; s=20250602; h=from:subject:message-id; bh=dGtxAS7nxtT0bG87r2Bb7PJl0WYrAo7+sx542XvvFpA=; b=DBoNoQ6ndihlFMYo4/VyWW2Z9wCieLl8CtfIBqmybsTEtLJxf7Mip8QVfivWakNZjdq5fer+J iJ1w7vNbev9C3EdP0FSDGjHkldV6/rsIpOVCZWvxVU3XuKk5z+zwGZG X-Developer-Key: i=ricardo.neri-calderon@linux.intel.com; a=ed25519; pk=NfZw5SyQ2lxVfmNMaMR6KUj3+0OhcwDPyRzFDH9gY2w= Package-level thermal interrupts are broadcast to all online CPUs within a package, even though only one CPU needs to service them. This results in unnecessary wakeups, lock contention, and corresponding performance and power-efficiency penalties. When supported by hardware, a CPU requests to receive directed package- level thermal interrupts by setting bit 25 in IA32_THERM_INTERRUPT. The operating system must then verify that hardware has acknowledged this request by checking bit 25 in IA32_PACKAGE_THERM_STATUS. Enable directed package-level thermal interrupts on one CPU per package. Use the CPU hotplug infrastructure. Keep track of the CPUs handling package-level interrupts with an array. If the handling CPU goes offline, select a new CPU. Temporarily enable directed interrupts on both the current and new CPU until hardware acknowledges the new selection, then disable them on the outgoing CPU. Systems without directed-interrupt support retain the current behavior: all online CPUs in a package receive the interrupt and existing handlers manage any resulting contention. Also fall back to this behavior if the directed-interrupt acknowledgment fails during boot. Signed-off-by: Ricardo Neri --- drivers/thermal/intel/therm_throt.c | 178 ++++++++++++++++++++++++++++++++= +++- 1 file changed, 177 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/th= erm_throt.c index 44fa4dd15dd1..456f2ac10e0c 100644 --- a/drivers/thermal/intel/therm_throt.c +++ b/drivers/thermal/intel/therm_throt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -244,7 +245,7 @@ static void thermal_intr_init_pkg_clear_mask(void) * IA32_PACKAGE_THERM_STATUS. */ =20 - /* All bits except BIT 26 depend on CPUID.06H: EAX[6] =3D 1 */ + /* All bits except BITs 25 and 26 depend on CPUID.06H: EAX[6] =3D 1 */ if (boot_cpu_has(X86_FEATURE_PTS)) therm_intr_pkg_clear_mask =3D (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9= ) | BIT(11)); =20 @@ -254,6 +255,13 @@ static void thermal_intr_init_pkg_clear_mask(void) */ if (boot_cpu_has(X86_FEATURE_HFI)) therm_intr_pkg_clear_mask |=3D BIT(26); + + /* + * Intel SDM Volume 2A: Thermal and Power Management Leaf + * Bit 25: CPUID.06H: EAX[24] =3D 1 + */ + if (boot_cpu_has(X86_FEATURE_DIRECTED_PKG_THRM_INTR)) + therm_intr_pkg_clear_mask |=3D BIT(25); } =20 /* @@ -524,6 +532,151 @@ static void thermal_throttle_remove_dev(struct device= *dev) sysfs_remove_group(&dev->kobj, &thermal_attr_group); } =20 +static int check_directed_thermal_pkg_intr_ack(void) +{ + unsigned int count =3D 15000; + u64 msr_val; + + /* + * Hardware is known to acknowledge the setting of the directed + * interrupt in 10ms or less. Wait for 15ms. + */ + do { + rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val); + udelay(1); + } while (!(msr_val & PACKAGE_THERM_STATUS_DIRECTED_INTR_ACK) && --count); + + if (!count) + return -ETIMEDOUT; + + thermal_clear_package_intr_status(PACKAGE_LEVEL, + PACKAGE_THERM_STATUS_DIRECTED_INTR_ACK); + + return 0; +} + +static void config_directed_thermal_pkg_intr(void *info) +{ + bool enable =3D *((bool *)info); + u64 msr_val; + + rdmsrl(MSR_IA32_THERM_INTERRUPT, msr_val); + + if (enable) + msr_val |=3D THERM_DIRECTED_INTR_ENABLE; + else + msr_val &=3D ~THERM_DIRECTED_INTR_ENABLE; + + wrmsrl(MSR_IA32_THERM_INTERRUPT, msr_val); +} + +/* Only accessed from CPU hotplug operations. No extra locking needed. */ +static unsigned int *directed_intr_handler_cpus; + +static bool directed_thermal_pkg_intr_supported(unsigned int cpu) +{ + if (!boot_cpu_has(X86_FEATURE_DIRECTED_PKG_THRM_INTR)) + return false; + + if (!directed_intr_handler_cpus) + return false; + + return true; +} + +static void enable_directed_thermal_pkg_intr(unsigned int cpu) +{ + bool enable =3D true; + u16 pkg_id; + + if (!directed_thermal_pkg_intr_supported(cpu)) + return; + + pkg_id =3D topology_logical_package_id(cpu); + if (pkg_id >=3D topology_max_packages()) + return; + + /* Another CPU in this package already handles the directed interrupt. */ + if (directed_intr_handler_cpus[pkg_id] !=3D nr_cpu_ids) + return; + + thermal_clear_package_intr_status(PACKAGE_LEVEL, + PACKAGE_THERM_STATUS_DIRECTED_INTR_ACK); + + config_directed_thermal_pkg_intr(&enable); + if (!check_directed_thermal_pkg_intr_ack()) { + directed_intr_handler_cpus[pkg_id] =3D cpu; + return; + } + + /* Failed to enable the directed package interrupt. Roll back. */ + enable =3D false; + config_directed_thermal_pkg_intr(&enable); + + /* + * This function is first called from the CPU0 hotplug callback during + * boot. Disable the directed package interrupt. All CPUs in a package + * will receive the package-level interrupt. + */ + if (cpu) + return; + + pr_info_once("CPU0: Failed to enable directed package-level thermal inter= rupt\n"); + kfree(directed_intr_handler_cpus); + directed_intr_handler_cpus =3D NULL; +} + +static void disable_directed_thermal_pkg_intr(unsigned int cpu) +{ + unsigned int new_cpu; + bool enable; + u16 pkg_id; + + if (!directed_thermal_pkg_intr_supported(cpu)) + return; + + pkg_id =3D topology_logical_package_id(cpu); + if (pkg_id >=3D topology_max_packages()) + return; + + /* Not the CPU handling the directed interrupt */ + if (directed_intr_handler_cpus[pkg_id] !=3D cpu) + return; + + /* Redirect the interrupt to another online CPU in the package. */ + new_cpu =3D cpumask_any_but(topology_core_cpumask(cpu), cpu); + if (new_cpu < nr_cpu_ids) { + enable =3D true; + thermal_clear_package_intr_status(PACKAGE_LEVEL, + PACKAGE_THERM_STATUS_DIRECTED_INTR_ACK); + + smp_call_function_single(new_cpu, config_directed_thermal_pkg_intr, + &enable, true); + } + + /* + * If a new CPU was found, check for acknowledgment. If hardware did not + * acknowledge it, disable the redirection of the interrupt on the new CP= U. + * Since no other CPU is configured to receive the package-level interrup= t, + * all CPUs in the package will receive it. + */ + enable =3D false; + if (new_cpu < nr_cpu_ids && check_directed_thermal_pkg_intr_ack()) { + smp_call_function_single(new_cpu, config_directed_thermal_pkg_intr, + &enable, true); + new_cpu =3D nr_cpu_ids; + } + + /* + * Disable the interrupt on this CPU. Hardware may acknowledge the + * request, but we do not care in this case. We do need to clear the + * ack bit when enabling the interrupt in another CPU. + */ + config_directed_thermal_pkg_intr(&enable); + + directed_intr_handler_cpus[pkg_id] =3D new_cpu; +} + /* Get notified when a cpu comes on/off. Be hotplug friendly. */ static int thermal_throttle_online(unsigned int cpu) { @@ -548,6 +701,8 @@ static int thermal_throttle_online(unsigned int cpu) l =3D apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); =20 + enable_directed_thermal_pkg_intr(cpu); + return thermal_throttle_add_dev(dev, cpu); } =20 @@ -557,6 +712,8 @@ static int thermal_throttle_offline(unsigned int cpu) struct device *dev =3D get_cpu_device(cpu); u32 l; =20 + disable_directed_thermal_pkg_intr(cpu); + /* Mask the thermal vector before draining evtl. pending work */ l =3D apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED); @@ -573,6 +730,23 @@ static int thermal_throttle_offline(unsigned int cpu) return 0; } =20 +static __init void init_directed_pkg_intr(void) +{ + int i; + + if (!boot_cpu_has(X86_FEATURE_DIRECTED_PKG_THRM_INTR)) + return; + + directed_intr_handler_cpus =3D kmalloc_array(topology_max_packages(), + sizeof(*directed_intr_handler_cpus), + GFP_KERNEL); + if (!directed_intr_handler_cpus) + return; + + for (i =3D 0; i < topology_max_packages(); i++) + directed_intr_handler_cpus[i] =3D nr_cpu_ids; +} + static __init int thermal_throttle_init_device(void) { int ret; @@ -580,6 +754,8 @@ static __init int thermal_throttle_init_device(void) if (!atomic_read(&therm_throt_en)) return 0; =20 + init_directed_pkg_intr(); + intel_hfi_init(); =20 ret =3D cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/therm:online", --=20 2.43.0 From nobody Thu Apr 9 09:10:49 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 22B7138E5FF; Mon, 9 Mar 2026 22:20:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094842; cv=none; b=VOOYLRB7dM/7Wbbnd6LQ40y94c19cGudqohovM3hjsKGzFcbBxRa4Dt+ozpc2ZVL136k6z75BxKAHGGoFbesUAo69J2mlT797oDix5jHdh80VVjicQ+2Ad6yepMCmyY8TB9gB5C7YkZ7Q+3nljAseyQ3jUs78NJJHkWtWm1Edc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094842; c=relaxed/simple; bh=xkX6/r3jlEdr7Ws/dG9NtH+OFdxbALWEmLOIVpaykP4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=e9C76Imf/9yQu8m7et1RxV1imm4pWzpNL1OMbZbI4LzfS4b0MA64k8mlSJwNEx7WBxUA/qEUilKwpx9nwOdkJkWGU3SYbPBsX/i5jAPo7vSqJt/PyDNikDnPwv+Ryo2gBfbLCwh0yPPJI8lUvzJ9LJgqpyNQsAcMyQD/yWnPRwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FxoMBlcp; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FxoMBlcp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773094841; x=1804630841; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=xkX6/r3jlEdr7Ws/dG9NtH+OFdxbALWEmLOIVpaykP4=; b=FxoMBlcp1nhIrR8iBB9lyOcU+Om2h9p2MIeiQCHbbEhxhC7gDdEqHhJ8 U1foLiksrqrxLY+rw6pq5720Bf+XhQ3nS1jFJ+neYQafqyOL7vjVQxPKm W4fKs51wKuRrRB1Dc8FbcQeX/XOsnusrYbRpRNiaNG01P7EOPSBCfWb2R qByJFw9YNGSOvfsSSIoEBaRGP1D0/Ma7OS9AwL1/h+XA2l7tKnNYTfWOE NoqDwgFfg0r50q4Z8aSygM0W0T0r6vw1Uol/ej2tMFn+pqNi5Hi9Owl2V bEI1IPaKQeQss7ydonRRXBd/caVIKKiY/c10KgLMB8PuIEVmLhDHmIz6S g==; X-CSE-ConnectionGUID: vwYfCHd5TQOEp0unBV/dcA== X-CSE-MsgGUID: kQupOvCHRS68AorsrPIG2Q== X-IronPort-AV: E=McAfee;i="6800,10657,11724"; a="74050658" X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="74050658" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:38 -0700 X-CSE-ConnectionGUID: IgDh7SA2RI+mIDra/ZyvVQ== X-CSE-MsgGUID: aje8LJsSRlWiPiJpaqstlQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="224004293" Received: from unknown (HELO [172.25.112.21]) ([172.25.112.21]) by orviesa003.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:39 -0700 From: Ricardo Neri Date: Mon, 09 Mar 2026 15:19:26 -0700 Subject: [PATCH 3/4] thermal: intel: Add syscore callbacks for suspend and resume 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" Content-Transfer-Encoding: quoted-printable Message-Id: <20260309-rneri-directed-therm-intr-v1-3-2956e3000950@linux.intel.com> References: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> In-Reply-To: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Lukasz Luba Cc: x86@kernel.org, Srinivas Pandruvada , Zhang Rui , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Ricardo Neri , Ricardo Neri X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773094783; l=2660; i=ricardo.neri-calderon@linux.intel.com; s=20250602; h=from:subject:message-id; bh=xkX6/r3jlEdr7Ws/dG9NtH+OFdxbALWEmLOIVpaykP4=; b=RCifaQc3sZs2aCjV+CM02cR5JeAxqgY+1wc6eaOA1skx8ikMnTUrf7IdLzgFHY/5IN4mKhitT iMljg24LwDXAx6eggCAFZ/Oin4GtYHEmmR8WiCVUsSPhRACTihajNiO X-Developer-Key: i=ricardo.neri-calderon@linux.intel.com; a=ed25519; pk=NfZw5SyQ2lxVfmNMaMR6KUj3+0OhcwDPyRzFDH9gY2w= Directed package-level thermal interrupts are serviced by a single CPU per package. These handler CPUs are selected at boot through the CPU hotplug infrastructure. This mechanism is sufficient to restore the directed interrupt configuration when resuming from suspend. For the boot package, CPU0 is chosen during boot because its CPU hotplug online callback runs first. However, this callback is not invoked on resume. The directed package-level interrupt configuration for the boot package is not restored automatically. Add a syscore .resume callback to re-enable directed package-level interrupts for this package. Disabling directed interrupts during suspend is not strictly required, but doing so keeps the handler-tracking array in a consistent state. It allows the correct configuration to be restored on resume. Signed-off-by: Ricardo Neri --- drivers/thermal/intel/therm_throt.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/th= erm_throt.c index 456f2ac10e0c..c89485a8cda0 100644 --- a/drivers/thermal/intel/therm_throt.c +++ b/drivers/thermal/intel/therm_throt.c @@ -14,6 +14,7 @@ * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c. * Inspired by Ross Biro's and Al Borchers' counter code. */ +#include #include #include #include @@ -730,6 +731,32 @@ static int thermal_throttle_offline(unsigned int cpu) return 0; } =20 +static void directed_pkg_intr_syscore_resume(void *data) +{ + /* We resume from the suspend on CPU0. */ + enable_directed_thermal_pkg_intr(0); +} + +static int directed_pkg_intr_syscore_suspend(void *data) +{ + /* + * We suspend from CPU0. The interrupt will not be redirected since all + * CPUs in the package are offline at this point. + */ + disable_directed_thermal_pkg_intr(0); + + return 0; +} + +static struct syscore_ops directed_pkg_intr_pm_ops =3D { + .resume =3D directed_pkg_intr_syscore_resume, + .suspend =3D directed_pkg_intr_syscore_suspend, +}; + +static struct syscore directed_pkg_intr_pm =3D { + .ops =3D &directed_pkg_intr_pm_ops, +}; + static __init void init_directed_pkg_intr(void) { int i; @@ -745,6 +772,8 @@ static __init void init_directed_pkg_intr(void) =20 for (i =3D 0; i < topology_max_packages(); i++) directed_intr_handler_cpus[i] =3D nr_cpu_ids; + + register_syscore(&directed_pkg_intr_pm); } =20 static __init int thermal_throttle_init_device(void) --=20 2.43.0 From nobody Thu Apr 9 09:10:49 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 59D7938F245; Mon, 9 Mar 2026 22:20:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094842; cv=none; b=tZBfykazDVHOlJ15XYc/qoTjrMZkl02MVk2+RzYa5W/JKtIlHKS6TMd2cM0kJzIrSYjgQ52AttVWkspRMjFiE5sM0m1QRWfwkryrqih2HCfx8mb/7y1Tlz0PLnux+lcnEZSyn8TNNkMVLNBQooAuDssdXDtFn3dF263QzLTic/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773094842; c=relaxed/simple; bh=8Zw0uqU/tIweMW1edd8EIH+/9emWZlcM4cagIgjN+qo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G/jw0Pd8/sRhHZEMrgnHwuSWjPjbME7oZLgcE1suztE+7+ZmFeJhEorWVN+lLHLEEbs5C/RuC8h6gnpdFzRSiNFvJWqJFXMelwVReHUxoVcTRAbypM/MnuKkBgOOTJvT1nYnJeUMwW+ZliO8PBcZ1c/j1RPr9mB9dcj1RQGnzmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=bXlY/nyw; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="bXlY/nyw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773094841; x=1804630841; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=8Zw0uqU/tIweMW1edd8EIH+/9emWZlcM4cagIgjN+qo=; b=bXlY/nywE2HpopqB9fdhzIibgWCReEKDriMXjevgsFHo3uKYsEEKXcxO ZwIavsZ3Qz93L3Qi054ym3DytPq7W9WkigZpgg8lJGcE20+PTAoBOEXw1 Aofjee6ibGT8Qn4+wQGM5xfeE2hVSV/ZPcXOUNgboMWkAPc1bLFl1h2lY SxmP2WUaO0pjr6cVGbtRXeG1yI1zmEk7DtkKWIWByULpg3VhNJFf+4XEE AOv8TzBFNmIUGetseHrPhEmPbQabVH2qIREM8pDw1lUjrDKC1ClVHOf7f PcxH5iEXjW09vAO7Pj+tgU48fp+VlxyQ199QnrHF1L1URkvKgcSIHeZmB w==; X-CSE-ConnectionGUID: /kJTXgPDQeaRBuBpec130g== X-CSE-MsgGUID: rD0ikFCoQt26KBkDuGRIww== X-IronPort-AV: E=McAfee;i="6800,10657,11724"; a="74050662" X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="74050662" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:39 -0700 X-CSE-ConnectionGUID: 7NodZ/QXQSWwNs9zDoobpA== X-CSE-MsgGUID: dH8nbJkDR4GQtDi2CkNWQw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,111,1770624000"; d="scan'208";a="224004297" Received: from unknown (HELO [172.25.112.21]) ([172.25.112.21]) by orviesa003.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2026 15:20:39 -0700 From: Ricardo Neri Date: Mon, 09 Mar 2026 15:19:27 -0700 Subject: [PATCH 4/4] thermal: intel: Add a syscore shutdown callback for kexec reboot 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" Content-Transfer-Encoding: quoted-printable Message-Id: <20260309-rneri-directed-therm-intr-v1-4-2956e3000950@linux.intel.com> References: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> In-Reply-To: <20260309-rneri-directed-therm-intr-v1-0-2956e3000950@linux.intel.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Lukasz Luba Cc: x86@kernel.org, Srinivas Pandruvada , Zhang Rui , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Ricardo Neri , Ricardo Neri X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773094783; l=1750; i=ricardo.neri-calderon@linux.intel.com; s=20250602; h=from:subject:message-id; bh=8Zw0uqU/tIweMW1edd8EIH+/9emWZlcM4cagIgjN+qo=; b=sRbJ10ATjqwaVboZbC++6lG1z5fJpS+1qlVyttnONBCT6PhszigFAHsrovMHhiuurA5J5gqpn NzS4FzzYTExAaUMzHHccSG+HpfM+rnrwh7aJySKsBPYSpBcwD4/eh+j X-Developer-Key: i=ricardo.neri-calderon@linux.intel.com; a=ed25519; pk=NfZw5SyQ2lxVfmNMaMR6KUj3+0OhcwDPyRzFDH9gY2w= A kexec reboot may load a kernel that does not support directed package- level thermal interrupts. Without a shutdown callback, the directed interrupt configuration remains enabled across kexec but will not be handled correctly. In particular, if the CPU designated to receive the directed interrupt goes offline, no other CPU in the package will receive it. Add a syscore .shutdown callback to disable directed package-level thermal interrupts on all packages before a kexec reboot. If the post-kexec kernel does not enable directed interrupts, they will fall back to being broadcast to all CPUs in the package. Signed-off-by: Ricardo Neri --- drivers/thermal/intel/therm_throt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/th= erm_throt.c index c89485a8cda0..33b0c90cfe41 100644 --- a/drivers/thermal/intel/therm_throt.c +++ b/drivers/thermal/intel/therm_throt.c @@ -748,9 +748,25 @@ static int directed_pkg_intr_syscore_suspend(void *dat= a) return 0; } =20 +static void directed_pkg_intr_syscore_shutdown(void *data) +{ + bool enable =3D false; + int i; + + for (i =3D 0; i < topology_max_packages(); i++) { + if (directed_intr_handler_cpus[i] =3D=3D nr_cpu_ids) + continue; + + smp_call_function_single(directed_intr_handler_cpus[i], + config_directed_thermal_pkg_intr, + &enable, true); + } +} + static struct syscore_ops directed_pkg_intr_pm_ops =3D { .resume =3D directed_pkg_intr_syscore_resume, .suspend =3D directed_pkg_intr_syscore_suspend, + .shutdown =3D directed_pkg_intr_syscore_shutdown, }; =20 static struct syscore directed_pkg_intr_pm =3D { --=20 2.43.0