Commit c5abe803 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Greg Kroah-Hartman

x86: MCE: Add raw_lock conversion again

commit ed5c41d3 upstream.

Commit ea431643 ("x86/mce: Fix CMCI preemption bugs") breaks RT by
the completely unrelated conversion of the cmci_discover_lock to a
regular (non raw) spinlock.  This lock was annotated in commit
59d958d2 ("locking, x86: mce: Annotate cmci_discover_lock as raw")
with a proper explanation why.

The argument for converting the lock back to a regular spinlock was:

 - it does percpu ops without disabling preemption. Preemption is not
   disabled due to the mistaken use of a raw spinlock.

Which is complete nonsense.  The raw_spinlock is disabling preemption in
the same way as a regular spinlock.  In mainline spinlock maps to
raw_spinlock, in RT spinlock becomes a "sleeping" lock.

raw_spinlock has on RT exactly the same semantics as in mainline.  And
because this lock is taken in non preemptible context it must be raw on
RT.

Undo the locking brainfart.
Reported-by: default avatarClark Williams <williams@redhat.com>
Reported-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e6ff6f13
...@@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned); ...@@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
* cmci_discover_lock protects against parallel discovery attempts * cmci_discover_lock protects against parallel discovery attempts
* which could race against each other. * which could race against each other.
*/ */
static DEFINE_SPINLOCK(cmci_discover_lock); static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
#define CMCI_THRESHOLD 1 #define CMCI_THRESHOLD 1
#define CMCI_POLL_INTERVAL (30 * HZ) #define CMCI_POLL_INTERVAL (30 * HZ)
...@@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void) ...@@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void)
int bank; int bank;
u64 val; u64 val;
spin_lock_irqsave(&cmci_discover_lock, flags); raw_spin_lock_irqsave(&cmci_discover_lock, flags);
owned = __get_cpu_var(mce_banks_owned); owned = __get_cpu_var(mce_banks_owned);
for_each_set_bit(bank, owned, MAX_NR_BANKS) { for_each_set_bit(bank, owned, MAX_NR_BANKS) {
rdmsrl(MSR_IA32_MCx_CTL2(bank), val); rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
val &= ~MCI_CTL2_CMCI_EN; val &= ~MCI_CTL2_CMCI_EN;
wrmsrl(MSR_IA32_MCx_CTL2(bank), val); wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
} }
spin_unlock_irqrestore(&cmci_discover_lock, flags); raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
} }
static bool cmci_storm_detect(void) static bool cmci_storm_detect(void)
...@@ -211,7 +211,7 @@ static void cmci_discover(int banks) ...@@ -211,7 +211,7 @@ static void cmci_discover(int banks)
int i; int i;
int bios_wrong_thresh = 0; int bios_wrong_thresh = 0;
spin_lock_irqsave(&cmci_discover_lock, flags); raw_spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) { for (i = 0; i < banks; i++) {
u64 val; u64 val;
int bios_zero_thresh = 0; int bios_zero_thresh = 0;
...@@ -266,7 +266,7 @@ static void cmci_discover(int banks) ...@@ -266,7 +266,7 @@ static void cmci_discover(int banks)
WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
} }
} }
spin_unlock_irqrestore(&cmci_discover_lock, flags); raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) { if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
pr_info_once( pr_info_once(
"bios_cmci_threshold: Some banks do not have valid thresholds set\n"); "bios_cmci_threshold: Some banks do not have valid thresholds set\n");
...@@ -316,10 +316,10 @@ void cmci_clear(void) ...@@ -316,10 +316,10 @@ void cmci_clear(void)
if (!cmci_supported(&banks)) if (!cmci_supported(&banks))
return; return;
spin_lock_irqsave(&cmci_discover_lock, flags); raw_spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) for (i = 0; i < banks; i++)
__cmci_disable_bank(i); __cmci_disable_bank(i);
spin_unlock_irqrestore(&cmci_discover_lock, flags); raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
} }
static void cmci_rediscover_work_func(void *arg) static void cmci_rediscover_work_func(void *arg)
...@@ -360,9 +360,9 @@ void cmci_disable_bank(int bank) ...@@ -360,9 +360,9 @@ void cmci_disable_bank(int bank)
if (!cmci_supported(&banks)) if (!cmci_supported(&banks))
return; return;
spin_lock_irqsave(&cmci_discover_lock, flags); raw_spin_lock_irqsave(&cmci_discover_lock, flags);
__cmci_disable_bank(bank); __cmci_disable_bank(bank);
spin_unlock_irqrestore(&cmci_discover_lock, flags); raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
} }
static void intel_init_cmci(void) static void intel_init_cmci(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment