]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 Feb 2017 20:47:44 +0000 (12:47 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 Feb 2017 20:47:44 +0000 (12:47 -0800)
Pull RAS updates from Ingo Molnar:
 "The main changes in this cycle were:

  - Assign notifier chain priorities for all RAS related handlers to
    make the ordering explicit (Borislav Petkov)

  - Improve the AMD MCA banks sysfs output (Yazen Ghannam)

  - Various cleanups and restructuring of the x86 RAS code (Borislav
    Petkov)"

* 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/ras, EDAC, acpi: Assign MCE notifier handlers a priority
  x86/ras: Get rid of mce_process_work()
  EDAC/mce/amd: Dump TSC value
  EDAC/mce/amd: Unexport amd_decode_mce()
  x86/ras/amd/inj: Change dependency
  x86/ras: Flip the TSC-adding logic
  x86/ras/amd: Make sysfs names of banks more user-friendly
  x86/ras/therm_throt: Do not log a fake MCE for thermal events
  x86/ras/inject: Make it depend on X86_LOCAL_APIC=y

1  2 
arch/x86/kernel/cpu/mcheck/mce.c
drivers/edac/mce_amd.c
drivers/edac/sb_edac.c

index 537c6647d84ca3e7cca771feb6c98bda94ef8c70,e39bbc0e7c8bbe51dfae0f07b02df2e9c726323a..8e9725c607ea6acb7a91deed9b72b2c9a873803e
@@@ -128,7 -128,6 +128,6 @@@ void mce_setup(struct mce *m
  {
        memset(m, 0, sizeof(struct mce));
        m->cpu = m->extcpu = smp_processor_id();
-       m->tsc = rdtsc();
        /* We hope get_seconds stays lockless */
        m->time = get_seconds();
        m->cpuvendor = boot_cpu_data.x86_vendor;
@@@ -217,9 -216,7 +216,7 @@@ void mce_register_decode_chain(struct n
  {
        atomic_inc(&num_notifiers);
  
-       /* Ensure SRAO notifier has the highest priority in the decode chain. */
-       if (nb != &mce_srao_nb && nb->priority == INT_MAX)
-               nb->priority -= 1;
+       WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC);
  
        atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
  }
@@@ -583,7 -580,7 +580,7 @@@ static int srao_decode_notifier(struct 
  }
  static struct notifier_block mce_srao_nb = {
        .notifier_call  = srao_decode_notifier,
-       .priority = INT_MAX,
+       .priority       = MCE_PRIO_SRAO,
  };
  
  static int mce_default_notifier(struct notifier_block *nb, unsigned long val,
  static struct notifier_block mce_default_nb = {
        .notifier_call  = mce_default_notifier,
        /* lowest prio, we want it to run last. */
-       .priority       = 0,
+       .priority       = MCE_PRIO_LOWEST,
  };
  
  /*
@@@ -710,14 -707,8 +707,8 @@@ bool machine_check_poll(enum mcp_flags 
  
        mce_gather_info(&m, NULL);
  
-       /*
-        * m.tsc was set in mce_setup(). Clear it if not requested.
-        *
-        * FIXME: Propagate @flags to mce_gather_info/mce_setup() to avoid
-        *        that dance.
-        */
-       if (!(flags & MCP_TIMESTAMP))
-               m.tsc = 0;
+       if (flags & MCP_TIMESTAMP)
+               m.tsc = rdtsc();
  
        for (i = 0; i < mca_cfg.banks; i++) {
                if (!mce_banks[i].ctl || !test_bit(i, *b))
@@@ -1156,6 -1147,7 +1147,7 @@@ void do_machine_check(struct pt_regs *r
                goto out;
  
        mce_gather_info(&m, regs);
+       m.tsc = rdtsc();
  
        final = this_cpu_ptr(&mces_seen);
        *final = m;
@@@ -1321,41 -1313,6 +1313,6 @@@ int memory_failure(unsigned long pfn, i
  }
  #endif
  
- /*
-  * Action optional processing happens here (picking up
-  * from the list of faulting pages that do_machine_check()
-  * placed into the genpool).
-  */
- static void mce_process_work(struct work_struct *dummy)
- {
-       mce_gen_pool_process();
- }
- #ifdef CONFIG_X86_MCE_INTEL
- /***
-  * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
-  * @cpu: The CPU on which the event occurred.
-  * @status: Event status information
-  *
-  * This function should be called by the thermal interrupt after the
-  * event has been processed and the decision was made to log the event
-  * further.
-  *
-  * The status parameter will be saved to the 'status' field of 'struct mce'
-  * and historically has been the register value of the
-  * MSR_IA32_THERMAL_STATUS (Intel) msr.
-  */
- void mce_log_therm_throt_event(__u64 status)
- {
-       struct mce m;
-       mce_setup(&m);
-       m.bank = MCE_THERMAL_BANK;
-       m.status = status;
-       mce_log(&m);
- }
- #endif /* CONFIG_X86_MCE_INTEL */
  /*
   * Periodic polling timer for "silent" machine check errors.  If the
   * poller finds an MCE, poll 2x faster.  When the poller finds no more
@@@ -1373,15 -1330,20 +1330,15 @@@ static unsigned long mce_adjust_timer_d
  
  static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default;
  
 -static void __restart_timer(struct timer_list *t, unsigned long interval)
 +static void __start_timer(struct timer_list *t, unsigned long interval)
  {
        unsigned long when = jiffies + interval;
        unsigned long flags;
  
        local_irq_save(flags);
  
 -      if (timer_pending(t)) {
 -              if (time_before(when, t->expires))
 -                      mod_timer(t, when);
 -      } else {
 -              t->expires = round_jiffies(when);
 -              add_timer_on(t, smp_processor_id());
 -      }
 +      if (!timer_pending(t) || time_before(when, t->expires))
 +              mod_timer(t, round_jiffies(when));
  
        local_irq_restore(flags);
  }
@@@ -1416,7 -1378,7 +1373,7 @@@ static void mce_timer_fn(unsigned long 
  
  done:
        __this_cpu_write(mce_next_interval, iv);
 -      __restart_timer(t, iv);
 +      __start_timer(t, iv);
  }
  
  /*
@@@ -1427,7 -1389,7 +1384,7 @@@ void mce_timer_kick(unsigned long inter
        struct timer_list *t = this_cpu_ptr(&mce_timer);
        unsigned long iv = __this_cpu_read(mce_next_interval);
  
 -      __restart_timer(t, interval);
 +      __start_timer(t, interval);
  
        if (interval < iv)
                __this_cpu_write(mce_next_interval, interval);
@@@ -1774,15 -1736,17 +1731,15 @@@ static void __mcheck_cpu_clear_vendor(s
        }
  }
  
 -static void mce_start_timer(unsigned int cpu, struct timer_list *t)
 +static void mce_start_timer(struct timer_list *t)
  {
        unsigned long iv = check_interval * HZ;
  
        if (mca_cfg.ignore_ce || !iv)
                return;
  
 -      per_cpu(mce_next_interval, cpu) = iv;
 -
 -      t->expires = round_jiffies(jiffies + iv);
 -      add_timer_on(t, cpu);
 +      this_cpu_write(mce_next_interval, iv);
 +      __start_timer(t, iv);
  }
  
  static void __mcheck_cpu_setup_timer(void)
@@@ -1799,7 -1763,7 +1756,7 @@@ static void __mcheck_cpu_init_timer(voi
        unsigned int cpu = smp_processor_id();
  
        setup_pinned_timer(t, mce_timer_fn, cpu);
 -      mce_start_timer(cpu, t);
 +      mce_start_timer(t);
  }
  
  /* Handle unconfigured int18 (should never happen) */
@@@ -2189,7 -2153,7 +2146,7 @@@ int __init mcheck_init(void
        mce_register_decode_chain(&mce_default_nb);
        mcheck_vendor_init_severity();
  
-       INIT_WORK(&mce_work, mce_process_work);
+       INIT_WORK(&mce_work, mce_gen_pool_process);
        init_irq_work(&mce_irq_work, mce_irq_work_cb);
  
        return 0;
@@@ -2559,7 -2523,7 +2516,7 @@@ static int mce_cpu_dead(unsigned int cp
  
  static int mce_cpu_online(unsigned int cpu)
  {
 -      struct timer_list *t = &per_cpu(mce_timer, cpu);
 +      struct timer_list *t = this_cpu_ptr(&mce_timer);
        int ret;
  
        mce_device_create(cpu);
                return ret;
        }
        mce_reenable_cpu();
 -      mce_start_timer(cpu, t);
 +      mce_start_timer(t);
        return 0;
  }
  
  static int mce_cpu_pre_down(unsigned int cpu)
  {
 -      struct timer_list *t = &per_cpu(mce_timer, cpu);
 +      struct timer_list *t = this_cpu_ptr(&mce_timer);
  
        mce_disable_cpu();
        del_timer_sync(t);
diff --combined drivers/edac/mce_amd.c
index 27513dca80092f575082c4b9e16b7e32dee0cae7,0d9bc25543d8234f7676e4d201da97a9ffe8330f..ba35b7ea3686027dd463ce1e893552e02a70106a
@@@ -937,12 -937,13 +937,13 @@@ static const char *decode_error_status(
        }
  
        if (m->status & MCI_STATUS_DEFERRED)
 -              return "Deferred error.";
 +              return "Deferred error, no action required.";
  
        return "Corrected error, no action required.";
  }
  
- int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
+ static int
+ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  {
        struct mce *m = (struct mce *)data;
        struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
        pr_cont("]: 0x%016llx\n", m->status);
  
        if (m->status & MCI_STATUS_ADDRV)
 -              pr_emerg(HW_ERR "Error Addr: 0x%016llx", m->addr);
 +              pr_emerg(HW_ERR "Error Addr: 0x%016llx\n", m->addr);
  
        if (boot_cpu_has(X86_FEATURE_SMCA)) {
 +              pr_emerg(HW_ERR "IPID: 0x%016llx", m->ipid);
 +
                if (m->status & MCI_STATUS_SYNDV)
                        pr_cont(", Syndrome: 0x%016llx", m->synd);
  
 -              pr_cont(", IPID: 0x%016llx", m->ipid);
 -
                pr_cont("\n");
  
                decode_smca_errors(m);
                goto err_code;
 -      } else
 -              pr_cont("\n");
 +      }
  
+       if (m->tsc)
+               pr_emerg(HW_ERR "TSC: %llu\n", m->tsc);
        if (!fam_ops)
                goto err_code;
  
  
        return NOTIFY_STOP;
  }
- EXPORT_SYMBOL_GPL(amd_decode_mce);
  
  static struct notifier_block amd_mce_dec_nb = {
        .notifier_call  = amd_decode_mce,
+       .priority       = MCE_PRIO_EDAC,
  };
  
  static int __init mce_amd_init(void)
diff --combined drivers/edac/sb_edac.c
index 573be9c0ffb8439e6037d6fed70217b344ff5427,c585a014dd3d556a37d9c220391dab1bc65d54fc..a65ea44e3b0bf66294c0c32effb774c9d3c23622
@@@ -304,6 -304,7 +304,6 @@@ struct sbridge_info 
        u64             (*rir_limit)(u32 reg);
        u64             (*sad_limit)(u32 reg);
        u32             (*interleave_mode)(u32 reg);
 -      char*           (*show_interleave_mode)(u32 reg);
        u32             (*dram_attr)(u32 reg);
        const u32       *dram_rule;
        const u32       *interleave_list;
@@@ -810,6 -811,11 +810,6 @@@ static u32 interleave_mode(u32 reg
        return GET_BITFIELD(reg, 1, 1);
  }
  
 -char *show_interleave_mode(u32 reg)
 -{
 -      return interleave_mode(reg) ? "8:6" : "[8:6]XOR[18:16]";
 -}
 -
  static u32 dram_attr(u32 reg)
  {
        return GET_BITFIELD(reg, 2, 3);
@@@ -825,16 -831,29 +825,16 @@@ static u32 knl_interleave_mode(u32 reg
        return GET_BITFIELD(reg, 1, 2);
  }
  
 -static char *knl_show_interleave_mode(u32 reg)
 -{
 -      char *s;
 -
 -      switch (knl_interleave_mode(reg)) {
 -      case 0:
 -              s = "use address bits [8:6]";
 -              break;
 -      case 1:
 -              s = "use address bits [10:8]";
 -              break;
 -      case 2:
 -              s = "use address bits [14:12]";
 -              break;
 -      case 3:
 -              s = "use address bits [32:30]";
 -              break;
 -      default:
 -              WARN_ON(1);
 -              break;
 -      }
 +static const char * const knl_intlv_mode[] = {
 +      "[8:6]", "[10:8]", "[14:12]", "[32:30]"
 +};
  
 -      return s;
 +static const char *get_intlv_mode_str(u32 reg, enum type t)
 +{
 +      if (t == KNIGHTS_LANDING)
 +              return knl_intlv_mode[knl_interleave_mode(reg)];
 +      else
 +              return interleave_mode(reg) ? "[8:6]" : "[8:6]XOR[18:16]";
  }
  
  static u32 dram_attr_knl(u32 reg)
@@@ -1791,7 -1810,7 +1791,7 @@@ static void get_memory_layout(const str
                         show_dram_attr(pvt->info.dram_attr(reg)),
                         gb, (mb*1000)/1024,
                         ((u64)tmp_mb) << 20L,
 -                       pvt->info.show_interleave_mode(reg),
 +                       get_intlv_mode_str(reg, pvt->info.type),
                         reg);
                prv = limit;
  
@@@ -3117,7 -3136,8 +3117,8 @@@ static int sbridge_mce_check_error(stru
  }
  
  static struct notifier_block sbridge_mce_dec = {
-       .notifier_call      = sbridge_mce_check_error,
+       .notifier_call  = sbridge_mce_check_error,
+       .priority       = MCE_PRIO_EDAC,
  };
  
  /****************************************************************************
@@@ -3208,6 -3228,7 +3209,6 @@@ static int sbridge_register_mci(struct 
                pvt->info.rir_limit = rir_limit;
                pvt->info.sad_limit = sad_limit;
                pvt->info.interleave_mode = interleave_mode;
 -              pvt->info.show_interleave_mode = show_interleave_mode;
                pvt->info.dram_attr = dram_attr;
                pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
                pvt->info.interleave_list = ibridge_interleave_list;
                pvt->info.rir_limit = rir_limit;
                pvt->info.sad_limit = sad_limit;
                pvt->info.interleave_mode = interleave_mode;
 -              pvt->info.show_interleave_mode = show_interleave_mode;
                pvt->info.dram_attr = dram_attr;
                pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
                pvt->info.interleave_list = sbridge_interleave_list;
                pvt->info.rir_limit = haswell_rir_limit;
                pvt->info.sad_limit = sad_limit;
                pvt->info.interleave_mode = interleave_mode;
 -              pvt->info.show_interleave_mode = show_interleave_mode;
                pvt->info.dram_attr = dram_attr;
                pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
                pvt->info.interleave_list = ibridge_interleave_list;
                pvt->info.rir_limit = haswell_rir_limit;
                pvt->info.sad_limit = sad_limit;
                pvt->info.interleave_mode = interleave_mode;
 -              pvt->info.show_interleave_mode = show_interleave_mode;
                pvt->info.dram_attr = dram_attr;
                pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
                pvt->info.interleave_list = ibridge_interleave_list;
                pvt->info.rir_limit = NULL;
                pvt->info.sad_limit = knl_sad_limit;
                pvt->info.interleave_mode = knl_interleave_mode;
 -              pvt->info.show_interleave_mode = knl_show_interleave_mode;
                pvt->info.dram_attr = dram_attr_knl;
                pvt->info.max_sad = ARRAY_SIZE(knl_dram_rule);
                pvt->info.interleave_list = knl_interleave_list;