summaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-10-05 09:40:09 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 11:49:31 -0300
commit6e103be1c7c4adb50f25aaf1f1e8f828833c1719 (patch)
tree77d1ada687f996be4f7cce07b47d46e13fe09413 /drivers/edac
parent4f87fad1d32fcdda448f9eb430c9c234a1939ece (diff)
downloadlinux-6e103be1c7c4adb50f25aaf1f1e8f828833c1719.tar.bz2
i7core_edac: First store, then increment
Fix ringbuffer store logic. While here, add a few comments to the code and remove the undesired printk that could otherwise be called during NMI time. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7core_edac.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 477b62a74dbf..59ec44175560 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1678,6 +1678,8 @@ static void i7core_check_error(struct mem_ctl_info *mci)
* This routine simply queues mcelog errors, and
* return. The error itself should be handled later
* by i7core_check_error.
+ * WARNING: As this routine should be called at NMI time, extra care should
+ * be taken to avoid deadlocks, and to be as fast as possible.
*/
static int i7core_mce_check_error(void *priv, struct mce *mce)
{
@@ -1696,13 +1698,8 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
return 0;
/* Only handle if it is the right mc controller */
- if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) {
- debugf0("mc%d: ignoring mce log for socket %d. "
- "Another mc should get it.\n",
- pvt->i7core_dev->socket,
- cpu_data(mce->cpu).phys_proc_id);
+ if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket)
return 0;
- }
smp_rmb();
if ((pvt->mce_out + 1) % sizeof(mce_entry) == pvt->mce_in) {
@@ -1710,9 +1707,11 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
pvt->mce_overrun++;
return 0;
}
+
+ /* Copy memory error at the ringbuffer */
+ memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce));
smp_wmb();
pvt->mce_out = (pvt->mce_out + 1) % sizeof(mce_entry);
- memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce));
/* Handle fatal errors immediately */
if (mce->mcgstatus & 1)