Skip to content
  • Andi Kleen's avatar
    x86, mce: switch x86 machine check handler to Monarch election. · 3c079792
    Andi Kleen authored
    
    
    On Intel platforms machine check exceptions are always broadcast to
    all CPUs.  This patch makes the machine check handler synchronize all
    these machine checks, elect a Monarch to handle the event and collect
    the worst event from all CPUs and then process it first.
    
    This has some advantages:
    
    - When there is a truly data corrupting error the system panics as
      quickly as possible. This improves containment of corrupted
      data and makes sure the corrupted data never hits stable storage.
    
    - The panics are synchronized and do not reenter the panic code
      on multiple CPUs (which currently does not handle this well).
    
    - All the errors are reported. Currently it often happens that
      another CPU happens to do the panic first, but reports useless
      information (empty machine check) because the real error
      happened on another CPU which came in later.
      This is a big advantage on Nehalem where the 8 threads per CPU
      lead to often the wrong CPU winning the race and dumping
      useless information on a machine check.  The problem also occurs
      in a less severe form on older CPUs.
    
    - The system can detect when no CPUs detected a machine check
      and shut down the system.  This can happen when one CPU is so
      badly hung that that it cannot process a machine check anymore
      or when some external agent wants to stop the system by
      asserting the machine check pin.  This follows Intel hardware
      recommendations.
    
    - This matches the recommended error model by the CPU designers.
    
    - The events can be output in true severity order
    
    - When a panic happens on another CPU it makes sure to be actually
      be able to process the stop IPI by enabling interrupts.
    
    The code is extremly careful to handle timeouts while waiting
    for other CPUs. It can't rely on the normal timing mechanisms
    (jiffies, ktime_get) because of its asynchronous/lockless nature,
    so it uses own timeouts using ndelay() and a "SPINUNIT"
    
    The timeout is configurable. By default it waits for upto one
    second for the other CPUs.  This can be also disabled.
    
    From some informal testing AMD systems do not see to broadcast
    machine checks, so right now it's always disabled by default on
    non Intel CPUs or also on very old Intel systems.
    
    Includes fixes from Ying Huang
    Fixed a "ecception" in a comment (H.Seto)
    Moved global_nwo reset later based on suggestion from H.Seto
    v2: Avoid duplicate messages
    
    [ Impact: feature, fixes long standing problems. ]
    
    Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
    Signed-off-by: default avatarHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
    Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
    3c079792