2007-07-19 08:49:33 +00:00
|
|
|
/*
|
2016-10-29 17:16:34 +00:00
|
|
|
* Defines, structures, APIs for edac_mc module
|
2007-07-19 08:49:33 +00:00
|
|
|
*
|
|
|
|
* (C) 2007 Linux Networx (http://lnxi.com)
|
|
|
|
* This file may be distributed under the terms of the
|
|
|
|
* GNU General Public License.
|
|
|
|
*
|
|
|
|
* Written by Thayne Harbaugh
|
|
|
|
* Based on work by Dan Hollis <goemon at anime dot net> and others.
|
|
|
|
* http://www.anime.net/~goemon/linux-ecc/
|
|
|
|
*
|
|
|
|
* NMI handling support added by
|
|
|
|
* Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>
|
|
|
|
*
|
|
|
|
* Refactored for multi-source files:
|
|
|
|
* Doug Thompson <norsk5@xmission.com>
|
|
|
|
*
|
2016-10-29 12:35:23 +00:00
|
|
|
* Please look at Documentation/driver-api/edac.rst for more info about
|
|
|
|
* EDAC core structs and functions.
|
2007-07-19 08:49:33 +00:00
|
|
|
*/
|
|
|
|
|
2016-10-29 17:16:34 +00:00
|
|
|
#ifndef _EDAC_MC_H_
|
|
|
|
#define _EDAC_MC_H_
|
2007-07-19 08:49:33 +00:00
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/smp.h>
|
|
|
|
#include <linux/pci.h>
|
|
|
|
#include <linux/time.h>
|
|
|
|
#include <linux/nmi.h>
|
|
|
|
#include <linux/rcupdate.h>
|
|
|
|
#include <linux/completion.h>
|
|
|
|
#include <linux/kobject.h>
|
|
|
|
#include <linux/platform_device.h>
|
2007-07-19 08:49:36 +00:00
|
|
|
#include <linux/workqueue.h>
|
2011-03-04 18:11:29 +00:00
|
|
|
#include <linux/edac.h>
|
2007-07-19 08:49:33 +00:00
|
|
|
|
|
|
|
#if PAGE_SHIFT < 20
|
2010-12-07 12:48:00 +00:00
|
|
|
#define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT))
|
|
|
|
#define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
|
2007-07-19 08:49:33 +00:00
|
|
|
#else /* PAGE_SHIFT > 20 */
|
2010-12-07 12:48:00 +00:00
|
|
|
#define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20))
|
2010-08-10 23:26:35 +00:00
|
|
|
#define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20))
|
2007-07-19 08:49:33 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define edac_printk(level, prefix, fmt, arg...) \
|
|
|
|
printk(level "EDAC " prefix ": " fmt, ##arg)
|
|
|
|
|
|
|
|
#define edac_mc_printk(mci, level, fmt, arg...) \
|
|
|
|
printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
|
|
|
|
|
|
|
|
#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \
|
|
|
|
printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg)
|
|
|
|
|
2007-07-19 08:49:36 +00:00
|
|
|
#define edac_device_printk(ctl, level, fmt, arg...) \
|
|
|
|
printk(level "EDAC DEVICE%d: " fmt, ctl->dev_idx, ##arg)
|
|
|
|
|
2007-07-19 08:49:52 +00:00
|
|
|
#define edac_pci_printk(ctl, level, fmt, arg...) \
|
|
|
|
printk(level "EDAC PCI%d: " fmt, ctl->pci_idx, ##arg)
|
|
|
|
|
2007-07-19 08:49:33 +00:00
|
|
|
/* prefixes for edac_printk() and edac_mc_printk() */
|
|
|
|
#define EDAC_MC "MC"
|
|
|
|
#define EDAC_PCI "PCI"
|
|
|
|
#define EDAC_DEBUG "DEBUG"
|
|
|
|
|
2014-08-13 21:27:55 +00:00
|
|
|
extern const char * const edac_mem_types[];
|
2010-10-07 16:29:15 +00:00
|
|
|
|
2007-07-19 08:49:33 +00:00
|
|
|
#ifdef CONFIG_EDAC_DEBUG
|
|
|
|
extern int edac_debug_level;
|
|
|
|
|
2012-04-29 20:08:39 +00:00
|
|
|
#define edac_dbg(level, fmt, ...) \
|
2012-04-28 19:41:46 +00:00
|
|
|
do { \
|
|
|
|
if (level <= edac_debug_level) \
|
|
|
|
edac_printk(KERN_DEBUG, EDAC_DEBUG, \
|
|
|
|
"%s: " fmt, __func__, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2007-07-19 08:49:58 +00:00
|
|
|
#else /* !CONFIG_EDAC_DEBUG */
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2012-04-29 20:08:39 +00:00
|
|
|
#define edac_dbg(level, fmt, ...) \
|
2012-04-28 19:41:46 +00:00
|
|
|
do { \
|
|
|
|
if (0) \
|
|
|
|
edac_printk(KERN_DEBUG, EDAC_DEBUG, \
|
|
|
|
"%s: " fmt, __func__, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2007-07-19 08:49:58 +00:00
|
|
|
#endif /* !CONFIG_EDAC_DEBUG */
|
2007-07-19 08:49:33 +00:00
|
|
|
|
|
|
|
#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
|
|
|
|
PCI_DEVICE_ID_ ## vend ## _ ## dev
|
|
|
|
|
2008-05-05 03:54:19 +00:00
|
|
|
#define edac_dev_name(dev) (dev)->dev_name
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2015-09-22 09:56:04 +00:00
|
|
|
#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
|
|
|
|
|
2016-10-26 17:47:55 +00:00
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_alloc() - Allocate and partially fill a struct &mem_ctl_info.
|
|
|
|
*
|
2016-10-26 17:47:55 +00:00
|
|
|
* @mc_num: Memory controller number
|
|
|
|
* @n_layers: Number of MC hierarchy layers
|
|
|
|
* @layers: Describes each layer as seen by the Memory Controller
|
|
|
|
* @sz_pvt: size of private storage needed
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Everything is kmalloc'ed as one big chunk - more efficient.
|
|
|
|
* Only can be used if all structures have the same lifetime - otherwise
|
|
|
|
* you have to allocate and initialize your own structures.
|
|
|
|
*
|
|
|
|
* Use edac_mc_free() to free mc structures allocated by this function.
|
|
|
|
*
|
|
|
|
* .. note::
|
|
|
|
*
|
|
|
|
* drivers handle multi-rank memories in different ways: in some
|
|
|
|
* drivers, one multi-rank memory stick is mapped as one entry, while, in
|
|
|
|
* others, a single multi-rank memory stick would be mapped into several
|
|
|
|
* entries. Currently, this function will allocate multiple struct dimm_info
|
|
|
|
* on such scenarios, as grouping the multiple ranks require drivers change.
|
|
|
|
*
|
|
|
|
* Returns:
|
2016-10-29 12:35:23 +00:00
|
|
|
* On success, return a pointer to struct mem_ctl_info pointer;
|
|
|
|
* %NULL otherwise
|
2016-10-26 17:47:55 +00:00
|
|
|
*/
|
2012-05-02 17:37:00 +00:00
|
|
|
struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
|
edac: Change internal representation to work with layers
Change the EDAC internal representation to work with non-csrow
based memory controllers.
There are lots of those memory controllers nowadays, and more
are coming. So, the EDAC internal representation needs to be
changed, in order to work with those memory controllers, while
preserving backward compatibility with the old ones.
The edac core was written with the idea that memory controllers
are able to directly access csrows.
This is not true for FB-DIMM and RAMBUS memory controllers.
Also, some recent advanced memory controllers don't present a per-csrows
view. Instead, they view memories as DIMMs, instead of ranks.
So, change the allocation and error report routines to allow
them to work with all types of architectures.
This will allow the removal of several hacks with FB-DIMM and RAMBUS
memory controllers.
Also, several tests were done on different platforms using different
x86 drivers.
TODO: a multi-rank DIMMs are currently represented by multiple DIMM
entries in struct dimm_info. That means that changing a label for one
rank won't change the same label for the other ranks at the same DIMM.
This bug is present since the beginning of the EDAC, so it is not a big
deal. However, on several drivers, it is possible to fix this issue, but
it should be a per-driver fix, as the csrow => DIMM arrangement may not
be equal for all. So, don't try to fix it here yet.
I tried to make this patch as short as possible, preceding it with
several other patches that simplified the logic here. Yet, as the
internal API changes, all drivers need changes. The changes are
generally bigger in the drivers for FB-DIMMs.
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Joe Perches <joe@perches.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2012-04-18 18:20:50 +00:00
|
|
|
unsigned n_layers,
|
|
|
|
struct edac_mc_layer *layers,
|
|
|
|
unsigned sz_pvt);
|
2016-10-26 17:47:55 +00:00
|
|
|
|
|
|
|
/**
|
2017-08-23 22:54:46 +00:00
|
|
|
* edac_get_owner - Return the owner's mod_name of EDAC MC
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Pointer to mod_name string when EDAC MC is owned. NULL otherwise.
|
|
|
|
*/
|
|
|
|
extern const char *edac_get_owner(void);
|
|
|
|
|
|
|
|
/*
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_add_mc_with_groups() - Insert the @mci structure into the mci
|
|
|
|
* global list and create sysfs entries associated with @mci structure.
|
|
|
|
*
|
2016-10-26 17:47:55 +00:00
|
|
|
* @mci: pointer to the mci structure to be added to the list
|
|
|
|
* @groups: optional attribute groups for the driver-specific sysfs entries
|
|
|
|
*
|
2016-10-29 12:35:23 +00:00
|
|
|
* Returns:
|
|
|
|
* 0 on Success, or an error code on failure
|
2016-10-26 17:47:55 +00:00
|
|
|
*/
|
2015-02-04 10:48:52 +00:00
|
|
|
extern int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
#define edac_mc_add_mc(mci) edac_mc_add_mc_with_groups(mci, NULL)
|
2016-10-26 17:47:55 +00:00
|
|
|
|
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_free() - Frees a previously allocated @mci structure
|
|
|
|
*
|
2016-10-26 17:47:55 +00:00
|
|
|
* @mci: pointer to a struct mem_ctl_info structure
|
|
|
|
*/
|
2007-07-19 08:50:26 +00:00
|
|
|
extern void edac_mc_free(struct mem_ctl_info *mci);
|
2016-10-26 17:47:55 +00:00
|
|
|
|
2017-01-27 17:24:21 +00:00
|
|
|
/**
|
|
|
|
* edac_has_mcs() - Check if any MCs have been allocated.
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* True if MC instances have been registered successfully.
|
|
|
|
* False otherwise.
|
|
|
|
*/
|
|
|
|
extern bool edac_has_mcs(void);
|
|
|
|
|
2016-10-26 17:47:55 +00:00
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_find() - Search for a mem_ctl_info structure whose index is @idx.
|
2016-10-26 17:47:55 +00:00
|
|
|
*
|
|
|
|
* @idx: index to be seek
|
|
|
|
*
|
|
|
|
* If found, return a pointer to the structure.
|
|
|
|
* Else return NULL.
|
|
|
|
*/
|
2007-07-19 08:49:58 +00:00
|
|
|
extern struct mem_ctl_info *edac_mc_find(int idx);
|
2016-10-26 17:47:55 +00:00
|
|
|
|
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* find_mci_by_dev() - Scan list of controllers looking for the one that
|
|
|
|
* manages the @dev device.
|
2016-10-26 17:47:55 +00:00
|
|
|
*
|
|
|
|
* @dev: pointer to a struct device related with the MCI
|
2016-10-29 12:35:23 +00:00
|
|
|
*
|
|
|
|
* Returns: on success, returns a pointer to struct &mem_ctl_info;
|
|
|
|
* %NULL otherwise.
|
2016-10-26 17:47:55 +00:00
|
|
|
*/
|
2010-08-10 14:22:01 +00:00
|
|
|
extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
|
2016-10-26 17:47:55 +00:00
|
|
|
|
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_del_mc() - Remove sysfs entries for mci structure associated with
|
|
|
|
* @dev and remove mci structure from global list.
|
2016-10-26 17:47:55 +00:00
|
|
|
*
|
|
|
|
* @dev: Pointer to struct &device representing mci structure to remove.
|
|
|
|
*
|
2016-10-29 12:35:23 +00:00
|
|
|
* Returns: pointer to removed mci structure, or %NULL if device not found.
|
2016-10-26 17:47:55 +00:00
|
|
|
*/
|
2007-07-19 08:49:58 +00:00
|
|
|
extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
|
2016-10-29 12:35:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* edac_mc_find_csrow_by_page() - Ancillary routine to identify what csrow
|
|
|
|
* contains a memory page.
|
|
|
|
*
|
|
|
|
* @mci: pointer to a struct mem_ctl_info structure
|
|
|
|
* @page: memory page to find
|
|
|
|
*
|
|
|
|
* Returns: on success, returns the csrow. -1 if not found.
|
|
|
|
*/
|
2007-07-19 08:49:33 +00:00
|
|
|
extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
|
2007-07-19 08:49:58 +00:00
|
|
|
unsigned long page);
|
2012-10-31 16:46:11 +00:00
|
|
|
|
2016-10-26 17:47:55 +00:00
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_raw_mc_handle_error() - Reports a memory event to userspace without
|
|
|
|
* doing anything to discover the error location.
|
2016-10-26 17:47:55 +00:00
|
|
|
*
|
|
|
|
* @type: severity of the error (CE/UE/Fatal)
|
|
|
|
* @mci: a struct mem_ctl_info pointer
|
|
|
|
* @e: error description
|
|
|
|
*
|
|
|
|
* This raw function is used internally by edac_mc_handle_error(). It should
|
|
|
|
* only be called directly when the hardware error come directly from BIOS,
|
|
|
|
* like in the case of APEI GHES driver.
|
|
|
|
*/
|
2012-10-31 16:46:11 +00:00
|
|
|
void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
|
|
|
|
struct mem_ctl_info *mci,
|
|
|
|
struct edac_raw_error_desc *e);
|
|
|
|
|
2016-10-26 17:47:55 +00:00
|
|
|
/**
|
2016-10-29 12:35:23 +00:00
|
|
|
* edac_mc_handle_error() - Reports a memory event to userspace.
|
2016-10-26 17:47:55 +00:00
|
|
|
*
|
|
|
|
* @type: severity of the error (CE/UE/Fatal)
|
|
|
|
* @mci: a struct mem_ctl_info pointer
|
|
|
|
* @error_count: Number of errors of the same type
|
|
|
|
* @page_frame_number: mem page where the error occurred
|
|
|
|
* @offset_in_page: offset of the error inside the page
|
|
|
|
* @syndrome: ECC syndrome
|
|
|
|
* @top_layer: Memory layer[0] position
|
|
|
|
* @mid_layer: Memory layer[1] position
|
|
|
|
* @low_layer: Memory layer[2] position
|
|
|
|
* @msg: Message meaningful to the end users that
|
|
|
|
* explains the event
|
|
|
|
* @other_detail: Technical details about the event that
|
|
|
|
* may help hardware manufacturers and
|
|
|
|
* EDAC developers to analyse the event
|
|
|
|
*/
|
edac: Change internal representation to work with layers
Change the EDAC internal representation to work with non-csrow
based memory controllers.
There are lots of those memory controllers nowadays, and more
are coming. So, the EDAC internal representation needs to be
changed, in order to work with those memory controllers, while
preserving backward compatibility with the old ones.
The edac core was written with the idea that memory controllers
are able to directly access csrows.
This is not true for FB-DIMM and RAMBUS memory controllers.
Also, some recent advanced memory controllers don't present a per-csrows
view. Instead, they view memories as DIMMs, instead of ranks.
So, change the allocation and error report routines to allow
them to work with all types of architectures.
This will allow the removal of several hacks with FB-DIMM and RAMBUS
memory controllers.
Also, several tests were done on different platforms using different
x86 drivers.
TODO: a multi-rank DIMMs are currently represented by multiple DIMM
entries in struct dimm_info. That means that changing a label for one
rank won't change the same label for the other ranks at the same DIMM.
This bug is present since the beginning of the EDAC, so it is not a big
deal. However, on several drivers, it is possible to fix this issue, but
it should be a per-driver fix, as the csrow => DIMM arrangement may not
be equal for all. So, don't try to fix it here yet.
I tried to make this patch as short as possible, preceding it with
several other patches that simplified the logic here. Yet, as the
internal API changes, all drivers need changes. The changes are
generally bigger in the drivers for FB-DIMMs.
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Joe Perches <joe@perches.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2012-04-18 18:20:50 +00:00
|
|
|
void edac_mc_handle_error(const enum hw_event_mc_err_type type,
|
|
|
|
struct mem_ctl_info *mci,
|
2012-06-04 16:27:43 +00:00
|
|
|
const u16 error_count,
|
edac: Change internal representation to work with layers
Change the EDAC internal representation to work with non-csrow
based memory controllers.
There are lots of those memory controllers nowadays, and more
are coming. So, the EDAC internal representation needs to be
changed, in order to work with those memory controllers, while
preserving backward compatibility with the old ones.
The edac core was written with the idea that memory controllers
are able to directly access csrows.
This is not true for FB-DIMM and RAMBUS memory controllers.
Also, some recent advanced memory controllers don't present a per-csrows
view. Instead, they view memories as DIMMs, instead of ranks.
So, change the allocation and error report routines to allow
them to work with all types of architectures.
This will allow the removal of several hacks with FB-DIMM and RAMBUS
memory controllers.
Also, several tests were done on different platforms using different
x86 drivers.
TODO: a multi-rank DIMMs are currently represented by multiple DIMM
entries in struct dimm_info. That means that changing a label for one
rank won't change the same label for the other ranks at the same DIMM.
This bug is present since the beginning of the EDAC, so it is not a big
deal. However, on several drivers, it is possible to fix this issue, but
it should be a per-driver fix, as the csrow => DIMM arrangement may not
be equal for all. So, don't try to fix it here yet.
I tried to make this patch as short as possible, preceding it with
several other patches that simplified the logic here. Yet, as the
internal API changes, all drivers need changes. The changes are
generally bigger in the drivers for FB-DIMMs.
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Joe Perches <joe@perches.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2012-04-18 18:20:50 +00:00
|
|
|
const unsigned long page_frame_number,
|
|
|
|
const unsigned long offset_in_page,
|
|
|
|
const unsigned long syndrome,
|
RAS: Add a tracepoint for reporting memory controller events
Add a new tracepoint-based hardware events report method for
reporting Memory Controller events.
Part of the description bellow is shamelessly copied from Tony
Luck's notes about the Hardware Error BoF during LPC 2010 [1].
Tony, thanks for your notes and discussions to generate the
h/w error reporting requirements.
[1] http://lwn.net/Articles/416669/
We have several subsystems & methods for reporting hardware errors:
1) EDAC ("Error Detection and Correction"). In its original form
this consisted of a platform specific driver that read topology
information and error counts from chipset registers and reported
the results via a sysfs interface.
2) mcelog - x86 specific decoding of machine check bank registers
reporting in binary form via /dev/mcelog. Recent additions make use
of the APEI extensions that were documented in version 4.0a of the
ACPI specification to acquire more information about errors without
having to rely reading chipset registers directly. A user level
programs decodes into somewhat human readable format.
3) drivers/edac/mce_amd.c - this driver hooks into the mcelog path and
decodes errors reported via machine check bank registers in AMD
processors to the console log using printk();
Each of these mechanisms has a band of followers ... and none
of them appear to meet all the needs of all users.
As part of a RAS subsystem, let's encapsulate the memory error hardware
events into a trace facility.
The tracepoint printk will be displayed like:
mc_event: [quant] (Corrected|Uncorrected|Fatal) error:[error msg] on [label] ([location] [edac_mc detail] [driver_detail]
Where:
[quant] is the quantity of errors
[error msg] is the driver-specific error message
(e. g. "memory read", "bus error", ...);
[location] is the location in terms of memory controller and
branch/channel/slot, channel/slot or csrow/channel;
[label] is the memory stick label;
[edac_mc detail] describes the address location of the error
and the syndrome;
[driver detail] is driver-specifig error message details,
when needed/provided (e. g. "area:DMA", ...)
For example:
mc_event: 1 Corrected error:memory read on memory stick DIMM_1A (mc:0 location:0:0:0 page:0x586b6e offset:0xa66 grain:32 syndrome:0x0 area:DMA)
Of course, any userspace tools meant to handle errors should not parse
the above data. They should, instead, use the binary fields provided by
the tracepoint, mapping them directly into their Management Information
Base.
NOTE: The original patch was providing an additional mechanism for
MCA-based trace events that also contained MCA error register data.
However, as no agreement was reached so far for the MCA-based trace
events, for now, let's add events only for memory errors.
A latter patch is planned to change the tracepoint, for those types
of event.
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2012-02-23 11:10:34 +00:00
|
|
|
const int top_layer,
|
|
|
|
const int mid_layer,
|
|
|
|
const int low_layer,
|
edac: Change internal representation to work with layers
Change the EDAC internal representation to work with non-csrow
based memory controllers.
There are lots of those memory controllers nowadays, and more
are coming. So, the EDAC internal representation needs to be
changed, in order to work with those memory controllers, while
preserving backward compatibility with the old ones.
The edac core was written with the idea that memory controllers
are able to directly access csrows.
This is not true for FB-DIMM and RAMBUS memory controllers.
Also, some recent advanced memory controllers don't present a per-csrows
view. Instead, they view memories as DIMMs, instead of ranks.
So, change the allocation and error report routines to allow
them to work with all types of architectures.
This will allow the removal of several hacks with FB-DIMM and RAMBUS
memory controllers.
Also, several tests were done on different platforms using different
x86 drivers.
TODO: a multi-rank DIMMs are currently represented by multiple DIMM
entries in struct dimm_info. That means that changing a label for one
rank won't change the same label for the other ranks at the same DIMM.
This bug is present since the beginning of the EDAC, so it is not a big
deal. However, on several drivers, it is possible to fix this issue, but
it should be a per-driver fix, as the csrow => DIMM arrangement may not
be equal for all. So, don't try to fix it here yet.
I tried to make this patch as short as possible, preceding it with
several other patches that simplified the logic here. Yet, as the
internal API changes, all drivers need changes. The changes are
generally bigger in the drivers for FB-DIMMs.
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Joe Perches <joe@perches.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2012-04-18 18:20:50 +00:00
|
|
|
const char *msg,
|
2012-06-04 14:29:25 +00:00
|
|
|
const char *other_detail);
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2007-07-19 08:49:52 +00:00
|
|
|
/*
|
|
|
|
* edac misc APIs
|
|
|
|
*/
|
2007-07-19 08:50:21 +00:00
|
|
|
extern char *edac_op_state_to_string(int op_state);
|
2007-07-19 08:49:33 +00:00
|
|
|
|
2016-10-29 17:16:34 +00:00
|
|
|
#endif /* _EDAC_MC_H_ */
|