x86, mce, cmci: use polled banks bitmap in machine check poller
authorAndi Kleen <andi@firstfloor.org>
Thu, 12 Feb 2009 12:49:34 +0000 (13:49 +0100)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 24 Feb 2009 21:26:05 +0000 (13:26 -0800)
Define a per cpu bitmap that contains the banks polled by the machine
check poller. This is needed for the CMCI code in the next patches
to be able to disable polling on specific banks.

The bank by default contains all banks, so there is no behaviour
change. Only future code will remove some banks from the polling
set.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
arch/x86/include/asm/mce.h
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/cpu/mcheck/mce_amd_64.c

index 125cd871462284e92b1857983b2daa492a913429..9b9523699dbcc4773222689887f2443da6f1ad0d 100644 (file)
@@ -119,11 +119,14 @@ extern atomic_t mce_entry;
 
 extern void do_machine_check(struct pt_regs *, long);
 
+typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
+DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
+
 enum mcp_flags {
        MCP_TIMESTAMP = (1 << 0),       /* log time stamp */
        MCP_UC = (1 << 1),              /* log uncorrected errors */
 };
-extern void machine_check_poll(enum mcp_flags flags);
+extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 
 extern int mce_notify_user(void);
 
index 9017609cadd961e0f1dae802f187f78dcdd06ecb..a8ff38bfa6ede72ef6679738e8b138945d993bef 100644 (file)
@@ -62,6 +62,11 @@ static char *trigger_argv[2] = { trigger, NULL };
 
 static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
 
+/* MCA banks polled by the period polling timer for corrected events */
+DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
+       [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
+};
+
 /* Do initial initialization of a struct mce */
 void mce_setup(struct mce *m)
 {
@@ -191,7 +196,7 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
  *
  * This is executed in standard interrupt context.
  */
-void machine_check_poll(enum mcp_flags flags)
+void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 {
        struct mce m;
        int i;
@@ -200,7 +205,7 @@ void machine_check_poll(enum mcp_flags flags)
 
        rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
        for (i = 0; i < banks; i++) {
-               if (!bank[i])
+               if (!bank[i] || !test_bit(i, *b))
                        continue;
 
                m.misc = 0;
@@ -458,7 +463,8 @@ static void mcheck_timer(unsigned long data)
        WARN_ON(smp_processor_id() != data);
 
        if (mce_available(&current_cpu_data))
-               machine_check_poll(MCP_TIMESTAMP);
+               machine_check_poll(MCP_TIMESTAMP,
+                               &__get_cpu_var(mce_poll_banks));
 
        /*
         * Alert userspace if needed.  If we logged an MCE, reduce the
@@ -572,11 +578,13 @@ static void mce_init(void *dummy)
 {
        u64 cap;
        int i;
+       mce_banks_t all_banks;
 
        /*
         * Log the machine checks left over from the previous reset.
         */
-       machine_check_poll(MCP_UC);
+       bitmap_fill(all_banks, MAX_NR_BANKS);
+       machine_check_poll(MCP_UC, &all_banks);
 
        set_in_cr4(X86_CR4_MCE);
 
index 49705be982096a6f38f3478cd3b57ea3e210727e..ee8bfcd3aa327d83417192f2975cf2de54743d99 100644 (file)
@@ -231,7 +231,8 @@ static void amd_threshold_interrupt(void)
 
                        /* Log the machine check that caused the threshold
                           event. */
-                       machine_check_poll(MCP_TIMESTAMP);
+                       machine_check_poll(MCP_TIMESTAMP,
+                                       &__get_cpu_var(mce_poll_banks));
 
                        if (high & MASK_OVERFLOW_HI) {
                                rdmsrl(address, m.misc);