Patch "x86/mce: Reenable CMCI banks when swiching back to interrupt mode" has been added to the 4.1-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
x86/mce: Reenable CMCI banks when swiching back to interrupt mode
to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-mce-reenable-cmci-banks-when-swiching-back-to-interrupt-mode.patch
and it can be found in the queue-4.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
1b48465500611a2dc5e75800c61ac352e22d41c3Mon Sep 17 00:00:00 2001
From: Xie XiuQi <[email protected]>
Date: Wed, 12 Aug 2015 18:29:41 +0200
Subject: x86/mce: Reenable CMCI banks when swiching back to interrupt mode
From: Xie XiuQi <[email protected]>
commit 1b48465500611a2dc5e75800c61ac352e22d41c3 upstream.
Zhang Liguang reported the following issue:
1) System detects a CMCI storm on the current CPU.
2) Kernel disables the CMCI interrupt on banks owned by the current CPU and switches to poll mode
3) After the CMCI storm subsides, kernel switches back to interrupt mode
4) We expect the system to reenable the CMCI interrupt on banks owned by the current CPU
mce_intel_adjust_timer
|-> cmci_reenable
|-> cmci_discover # owned banks are ignored here
static void cmci_discover(int banks)
...
for (i = 0; i < banks; i++) {
...
if (test_bit(i, owned)) # ownd banks is ignore here
continue;So convert cmci_storm_disable_banks() to cmci_toggle_interrupt_mode() which controls whether to enable or disable CMCI interrupts with its argument.
NB: We cannot clear the owned bit because the banks won't be polled, otherwise. See:
27f6c573e0f7 ("x86, CMCI: Add proper detection of end of CMCI storms")
for more info.
--- arch/x86/kernel/cpu/mcheck/mce_intel.c | 41 ++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-)
arch/x86/kernel/cpu/mcheck/mce_intel.c +23 -18
@@ -116,6 +116,27 @@ void mce_intel_hcpu_update(unsigned longper_cpu (cmci_storm_state, cpu) =CMCI_STORM_NONE ; } +static void cmci_toggle_interrupt_mode (bool on) +{ +unsigned long flags, *owned; +int bank; +u64 val; + +raw_spin_lock_irqsave (&cmci_discover_lock, flags); + owned =this_cpu_ptr (mce_banks_owned); +for_each_set_bit (bank, owned,MAX_NR_BANKS ) { +rdmsrl (MSR_IA32_MCx_CTL2 (bank), val); + +if (on) + val |=MCI_CTL2_CMCI_EN ; +else + val &= ~MCI_CTL2_CMCI_EN ; + +wrmsrl (MSR_IA32_MCx_CTL2 (bank), val); + } +raw_spin_unlock_irqrestore (&cmci_discover_lock, flags); +} +unsigned long cmci_intel_adjust_timer (unsigned long interval) { if ((this_cpu_read(cmci_backoff_cnt) > 0) &&
@@ -145,7 +166,7 @@ unsigned long cmci_intel_adjust_timer(un*/ if (!atomic_read (&cmci_storm_on_cpus)) {__this_cpu_write (cmci_storm_state,CMCI_STORM_NONE ); -cmci_reenable (); +cmci_toggle_interrupt_mode (true);cmci_recheck (); }return CMCI_POLL_INTERVAL ;
@@ -156,22 +177,6 @@ unsigned long cmci_intel_adjust_timer(un } } -static void cmci_storm_disable_banks (void ) -{ -unsigned long flags, *owned; -int bank; -u64 val; - -raw_spin_lock_irqsave (&cmci_discover_lock, flags); - owned =this_cpu_ptr (mce_banks_owned); -for_each_set_bit (bank, owned,MAX_NR_BANKS ) { -rdmsrl (MSR_IA32_MCx_CTL2 (bank), val); - val &= ~MCI_CTL2_CMCI_EN ; -wrmsrl (MSR_IA32_MCx_CTL2 (bank), val); - } -raw_spin_unlock_irqrestore (&cmci_discover_lock, flags); -} -static bool cmci_storm_detect (void ) {unsigned int cnt =__this_cpu_read (cmci_storm_cnt);
@@ -193,7 +198,7 @@ static bool cmci_storm_detect(void)if (cnt <=CMCI_STORM_THRESHOLD )return false; -cmci_storm_disable_banks (); +cmci_toggle_interrupt_mode (false);__this_cpu_write (cmci_storm_state,CMCI_STORM_ACTIVE ); r =atomic_add_return (1 , &cmci_storm_on_cpus);mce_timer_kick (CMCI_STORM_INTERVAL );
Patches currently in stable-queue which might be from [email protected] are
queue-4.1/x86-mce-reenable-cmci-banks-when-swiching-back-to-interrupt-mode.patch