* [RFC PATCH] x86/mce: Avoid arming periodic polling timer on isolated CPUs @ 2026-09-01 15:11 Aaron Tomlin 2026-09-01 17:58 ` Luck, Tony 0 siblings, 1 reply; 3+ messages in thread From: Aaron Tomlin @ 2026-09-01 15:11 UTC (permalink / raw) To: tony.luck, bp, tglx, mingo, dave.hansen Cc: x86, hpa, frederic, marco.crivellari, sean, linux-edac, linux-kernel Latency-sensitive workloads rely on CPU isolation (i.e., configured via nohz_full= or isolcpus=nohz) to guarantee deterministic execution without interruption from background kernel activity. On x86 platforms, the Machine Check Architecture (MCA) subsystem arms a per-CPU, pinned standard timer (mce_timer) to periodically poll hardware banks for "silent" corrected machine check errors. Because mce_timer is pinned to the local CPU via TIMER_PINNED, the timer core cannot migrate its expiration to a housekeeping CPU. Consequently, every check_interval (defaulting to five minutes, or as frequently as every 10 ms during error decay), a timer tick interrupts the isolated CPU to execute mce_timer_fn() and machine_check_poll(), introducing unavoidable latency jitter. Presently, the only mechanisms available to suppress this timer (i.e., the mce=ignore_ce boot parameter or setting check_interval=0 via sysfs) are system-wide globals. Setting these attributes disables polling across the entire platform, needlessly blinding non-isolated housekeeping CPUs from monitoring shared memory controllers and uncore error telemetry. Amend should_enable_timer() to query housekeeping_cpu() for HK_TYPE_TIMER (HK_TYPE_KERNEL_NOISE). When a CPU is designated as isolated, the timer is neither armed at CPU online nor re-armed upon timer expiration. Housekeeping CPUs continue to run their polling timers unaltered, preserving routine monitoring of shared package and memory controller banks. On isolated CPUs, critical synchronous exceptions (#MC) remain fully functional for fatal and recoverable uncorrected errors, and CMCI interrupts continue to deliver asynchronous notifications where supported. When CPU isolation is not configured, static branch optimisations ensure zero runtime overhead. Signed-off-by: Aaron Tomlin <atomlin@atomlin.com> --- arch/x86/kernel/cpu/mce/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index ab469605fc89..fd047968ad17 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -25,6 +25,7 @@ #include <linux/delay.h> #include <linux/ctype.h> #include <linux/sched.h> +#include <linux/sched/isolation.h> #include <linux/sysfs.h> #include <linux/types.h> #include <linux/slab.h> @@ -1759,6 +1760,9 @@ void (*mc_poll_banks)(void) = mc_poll_banks_default; static bool should_enable_timer(unsigned long iv) { + if (!housekeeping_cpu(smp_processor_id(), HK_TYPE_TIMER)) + return false; + return !mca_cfg.ignore_ce && iv; } -- 2.55.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [RFC PATCH] x86/mce: Avoid arming periodic polling timer on isolated CPUs 2026-09-01 15:11 [RFC PATCH] x86/mce: Avoid arming periodic polling timer on isolated CPUs Aaron Tomlin @ 2026-09-01 17:58 ` Luck, Tony 2026-09-02 0:34 ` Aaron Tomlin 0 siblings, 1 reply; 3+ messages in thread From: Luck, Tony @ 2026-09-01 17:58 UTC (permalink / raw) To: Aaron Tomlin Cc: bp, tglx, mingo, dave.hansen, x86, hpa, frederic, marco.crivellari, sean, linux-edac, linux-kernel On Tue, Sep 01, 2026 at 11:11:38AM -0400, Aaron Tomlin wrote: > Latency-sensitive workloads rely on CPU isolation (i.e., configured via > nohz_full= or isolcpus=nohz) to guarantee deterministic execution > without interruption from background kernel activity. > > On x86 platforms, the Machine Check Architecture (MCA) subsystem arms a > per-CPU, pinned standard timer (mce_timer) to periodically poll hardware > banks for "silent" corrected machine check errors. Because mce_timer is > pinned to the local CPU via TIMER_PINNED, the timer core cannot migrate > its expiration to a housekeeping CPU. Consequently, every check_interval > (defaulting to five minutes, or as frequently as every 10 ms during > error decay), a timer tick interrupts the isolated CPU to execute > mce_timer_fn() and machine_check_poll(), introducing unavoidable latency > jitter. > > Presently, the only mechanisms available to suppress this timer (i.e., > the mce=ignore_ce boot parameter or setting check_interval=0 via sysfs) > are system-wide globals. Setting these attributes disables polling > across the entire platform, needlessly blinding non-isolated > housekeeping CPUs from monitoring shared memory controllers and uncore > error telemetry. > > Amend should_enable_timer() to query housekeeping_cpu() for > HK_TYPE_TIMER (HK_TYPE_KERNEL_NOISE). When a CPU is designated as > isolated, the timer is neither armed at CPU online nor re-armed upon > timer expiration. Housekeeping CPUs continue to run their polling timers > unaltered, preserving routine monitoring of shared package and memory > controller banks. > > On isolated CPUs, critical synchronous exceptions (#MC) remain fully > functional for fatal and recoverable uncorrected errors, and CMCI > interrupts continue to deliver asynchronous notifications where > supported. When CPU isolation is not configured, static branch > optimisations ensure zero runtime overhead. There's a better approach which hasn't managed to get to the top of my priority queue. If you look at the mce_poll_banks bitmask, you'll likely see that the only bit set in the range of supported banks is for bank 4 or bank 6. That's the "PCU" (Power Control Unit?) bank. All the other bits are zeroed because Linux found that CMCI was supported, so no polling is needed (assuming CMCI hasn't been disabled). There was a misunderstanding about the full meaning of the CMCI_EN bit in the IA32_MCi_CTL2 MSR. Older versions of the Intel Software Developer's Manual left Linux coders with the impression that if CMCI_EN was not supported for a bank, then software would have to poll to see any corrected errors. Newer editions update volume 3B section 18.5 "CORRECTED MACHINE CHECK ERROR INTERRUPT": To detect the existence of thresholding for a given bank, software writes only bits 14:0 with the threshold value. If the bits persist, then thresholding is available (and CMCI is available). If the bits are all 0's, then no thresholding exists. To detect that CMCI signaling exists, software writes a 1 to bit 30 of the MCi_CTL2 register. Upon subsequent read, if bit 30 = 0, no CMCI is available for this bank and no corrected or UCNA errors will be reported on this bank. If bit 30 = 1, then CMCI is available and enabled. The addition being the "and no corrected or UCNA errors will be reported on this bank" The PCU bank behaves this way. It doesn't support CMCI because: *NO CORRECTED ERRORS WILL BE REPORTED IN THE PCU BANK* so a waste of cycles to poll it. So Linux needs: 1) Properly handle systems that support CMCI, but have bank(s) that don't. The bit for such banks should be cleared in mce_poll_banks. 2) Add a check to see if mce_poll_banks is empty, don't start the timer. > > Signed-off-by: Aaron Tomlin <atomlin@atomlin.com> > --- > arch/x86/kernel/cpu/mce/core.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c > index ab469605fc89..fd047968ad17 100644 > --- a/arch/x86/kernel/cpu/mce/core.c > +++ b/arch/x86/kernel/cpu/mce/core.c > @@ -25,6 +25,7 @@ > #include <linux/delay.h> > #include <linux/ctype.h> > #include <linux/sched.h> > +#include <linux/sched/isolation.h> > #include <linux/sysfs.h> > #include <linux/types.h> > #include <linux/slab.h> > @@ -1759,6 +1760,9 @@ void (*mc_poll_banks)(void) = mc_poll_banks_default; > > static bool should_enable_timer(unsigned long iv) > { > + if (!housekeeping_cpu(smp_processor_id(), HK_TYPE_TIMER)) > + return false; > + > return !mca_cfg.ignore_ce && iv; > } > > -- > 2.55.0 > -Tony ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC PATCH] x86/mce: Avoid arming periodic polling timer on isolated CPUs 2026-09-01 17:58 ` Luck, Tony @ 2026-09-02 0:34 ` Aaron Tomlin 0 siblings, 0 replies; 3+ messages in thread From: Aaron Tomlin @ 2026-09-02 0:34 UTC (permalink / raw) To: Luck, Tony Cc: bp, tglx, mingo, dave.hansen, x86, hpa, frederic, marco.crivellari, neelx, chjohnst, sean, linux-edac, linux-kernel On Tue, Sep 01, 2026 at 10:58:52AM -0700, Luck, Tony wrote: > On Tue, Sep 01, 2026 at 11:11:38AM -0400, Aaron Tomlin wrote: > > Latency-sensitive workloads rely on CPU isolation (i.e., configured via > > nohz_full= or isolcpus=nohz) to guarantee deterministic execution > > without interruption from background kernel activity. > > > > On x86 platforms, the Machine Check Architecture (MCA) subsystem arms a > > per-CPU, pinned standard timer (mce_timer) to periodically poll hardware > > banks for "silent" corrected machine check errors. Because mce_timer is > > pinned to the local CPU via TIMER_PINNED, the timer core cannot migrate > > its expiration to a housekeeping CPU. Consequently, every check_interval > > (defaulting to five minutes, or as frequently as every 10 ms during > > error decay), a timer tick interrupts the isolated CPU to execute > > mce_timer_fn() and machine_check_poll(), introducing unavoidable latency > > jitter. > > > > Presently, the only mechanisms available to suppress this timer (i.e., > > the mce=ignore_ce boot parameter or setting check_interval=0 via sysfs) > > are system-wide globals. Setting these attributes disables polling > > across the entire platform, needlessly blinding non-isolated > > housekeeping CPUs from monitoring shared memory controllers and uncore > > error telemetry. > > > > Amend should_enable_timer() to query housekeeping_cpu() for > > HK_TYPE_TIMER (HK_TYPE_KERNEL_NOISE). When a CPU is designated as > > isolated, the timer is neither armed at CPU online nor re-armed upon > > timer expiration. Housekeeping CPUs continue to run their polling timers > > unaltered, preserving routine monitoring of shared package and memory > > controller banks. > > > > On isolated CPUs, critical synchronous exceptions (#MC) remain fully > > functional for fatal and recoverable uncorrected errors, and CMCI > > interrupts continue to deliver asynchronous notifications where > > supported. When CPU isolation is not configured, static branch > > optimisations ensure zero runtime overhead. > > There's a better approach which hasn't managed to get to the top of my > priority queue. > > If you look at the mce_poll_banks bitmask, you'll likely see that the > only bit set in the range of supported banks is for bank 4 or bank 6. > That's the "PCU" (Power Control Unit?) bank. All the other bits are > zeroed because Linux found that CMCI was supported, so no polling is > needed (assuming CMCI hasn't been disabled). > > There was a misunderstanding about the full meaning of the CMCI_EN > bit in the IA32_MCi_CTL2 MSR. Older versions of the Intel Software > Developer's Manual left Linux coders with the impression that if > CMCI_EN was not supported for a bank, then software would have to > poll to see any corrected errors. > > Newer editions update volume 3B section 18.5 "CORRECTED MACHINE CHECK ERROR INTERRUPT": > > To detect the existence of thresholding for a given bank, software writes only > bits 14:0 with the threshold value. If the bits persist, then thresholding > is available (and CMCI is available). If the bits are all 0's, then no > thresholding exists. To detect that CMCI signaling exists, software writes > a 1 to bit 30 of the MCi_CTL2 register. Upon subsequent read, if bit 30 = > 0, no CMCI is available for this bank and no corrected or UCNA errors will > be reported on this bank. If bit 30 = 1, then CMCI is available and enabled. > > The addition being the "and no corrected or UCNA errors will be reported on this bank" > > The PCU bank behaves this way. It doesn't support CMCI because: > > *NO CORRECTED ERRORS WILL BE REPORTED IN THE PCU BANK* > > so a waste of cycles to poll it. > > So Linux needs: > > 1) Properly handle systems that support CMCI, but have bank(s) that don't. > The bit for such banks should be cleared in mce_poll_banks. > 2) Add a check to see if mce_poll_banks is empty, don't start the timer. Hi Tony, Thank you for your feedback. I see. Addressing the root cause by not polling banks that will never log corrected/Uncorrected No Action Required (UCNA) errors, and subsequently eliding mce_timer whenever mce_poll_banks is empty, is indeed a far cleaner and more elegant solution. It eliminates the polling overhead across the entire system rather than merely masking it on isolated cores. Based on your suggestions, the implementation would look like: 1. When CMCI is supported on the CPU but a given bank does not support setting MCI_CTL2_CMCI_EN (i.e., the PCU bank), clear that bank's bit from mce_poll_banks instead of leaving it set and flagging it as poll_only. 2. Add a check (e.g., bitmap_empty(this_cpu_ptr(mce_poll_banks), MAX_NR_BANKS)) so that the timer is never armed or re-armed when no banks require polling. This also integrates cleanly with the existing storm tracking logic. When a storm begins, cmci_storm_begin() sets the bank's bit in mce_poll_banks and kicks the timer; once the storm concludes, cmci_storm_end() clears the bit and the timer ceases re-arming. Legacy systems lacking CMCI (or systems booted with mce=no_cmci) will continue to retain bits in mce_poll_banks and poll as expected. I will prepare a v2 patch implementing this approach and post it shortly for review. Kind regards, -- Aaron Tomlin ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-02 0:34 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-01 15:11 [RFC PATCH] x86/mce: Avoid arming periodic polling timer on isolated CPUs Aaron Tomlin 2026-09-01 17:58 ` Luck, Tony 2026-09-02 0:34 ` Aaron Tomlin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox