diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-10-05 09:40:09 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 11:49:31 -0300 |
commit | 6e103be1c7c4adb50f25aaf1f1e8f828833c1719 (patch) | |
tree | 77d1ada687f996be4f7cce07b47d46e13fe09413 /drivers/edac | |
parent | 4f87fad1d32fcdda448f9eb430c9c234a1939ece (diff) | |
download | blackbird-op-linux-6e103be1c7c4adb50f25aaf1f1e8f828833c1719.tar.gz blackbird-op-linux-6e103be1c7c4adb50f25aaf1f1e8f828833c1719.zip |
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.c | 13 |
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) |