diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-02 22:52:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:44:57 -0400 |
commit | 14d2c08343eecd13f6c6ec232c98b16762b97924 (patch) | |
tree | fa78da74556c7b945814c52643aa64559c0b209a | |
parent | b4e8f0b6eaa1e99f1a64e539466a8ee2fb521d62 (diff) |
i7core: Use registered memories per processor
Instead of assuming that the entire machine has either registered or
unregistered memories, do it at CPU socket based.
While here, fix a bug at i7core_mce_output_error(), where the we're
using m->cpu directly as if it would represent a socket. Instead, the
proper socket_id is given by cpu_data[m->cpu].phys_proc_id.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
-rw-r--r-- | drivers/edac/i7core_edac.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 4758c208f39a..9f4e9d7d4dbf 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mmzone.h> | 29 | #include <linux/mmzone.h> |
30 | #include <linux/edac_mce.h> | 30 | #include <linux/edac_mce.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <asm/processor.h> | ||
32 | 33 | ||
33 | #include "edac_core.h" | 34 | #include "edac_core.h" |
34 | 35 | ||
@@ -206,8 +207,6 @@ struct i7core_pvt { | |||
206 | struct i7core_inject inject; | 207 | struct i7core_inject inject; |
207 | struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; | 208 | struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; |
208 | 209 | ||
209 | unsigned int is_registered:1; /* true if all memories are RDIMMs */ | ||
210 | |||
211 | int sockets; /* Number of sockets */ | 210 | int sockets; /* Number of sockets */ |
212 | int channels; /* Number of active channels */ | 211 | int channels; /* Number of active channels */ |
213 | 212 | ||
@@ -221,6 +220,8 @@ struct i7core_pvt { | |||
221 | unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; | 220 | unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; |
222 | int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; | 221 | int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; |
223 | 222 | ||
223 | unsigned int is_registered[NUM_SOCKETS]; | ||
224 | |||
224 | /* mcelog glue */ | 225 | /* mcelog glue */ |
225 | struct edac_mce edac_mce; | 226 | struct edac_mce edac_mce; |
226 | struct mce mce_entry[MCE_LOG_LEN]; | 227 | struct mce mce_entry[MCE_LOG_LEN]; |
@@ -490,8 +491,6 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) | |||
490 | numrow(pvt->info.max_dod >> 6), | 491 | numrow(pvt->info.max_dod >> 6), |
491 | numcol(pvt->info.max_dod >> 9)); | 492 | numcol(pvt->info.max_dod >> 9)); |
492 | 493 | ||
493 | pvt->is_registered = 1; | ||
494 | |||
495 | for (i = 0; i < NUM_CHANS; i++) { | 494 | for (i = 0; i < NUM_CHANS; i++) { |
496 | u32 data, dimm_dod[3], value[8]; | 495 | u32 data, dimm_dod[3], value[8]; |
497 | 496 | ||
@@ -513,14 +512,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) | |||
513 | 512 | ||
514 | if (data & REGISTERED_DIMM) | 513 | if (data & REGISTERED_DIMM) |
515 | mtype = MEM_RDDR3; | 514 | mtype = MEM_RDDR3; |
516 | else { | 515 | else |
517 | mtype = MEM_DDR3; | 516 | mtype = MEM_DDR3; |
518 | /* | ||
519 | * FIXME: Currently, the driver will use dev 3:2 | ||
520 | * counter registers only if all memories are registered | ||
521 | */ | ||
522 | pvt->is_registered = 0; | ||
523 | } | ||
524 | #if 0 | 517 | #if 0 |
525 | if (data & THREE_DIMMS_PRESENT) | 518 | if (data & THREE_DIMMS_PRESENT) |
526 | pvt->channel[i].dimms = 3; | 519 | pvt->channel[i].dimms = 3; |
@@ -1068,7 +1061,7 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) | |||
1068 | count = sprintf(data, "socket 0 data unavailable\n"); | 1061 | count = sprintf(data, "socket 0 data unavailable\n"); |
1069 | continue; | 1062 | continue; |
1070 | } | 1063 | } |
1071 | if (!pvt->is_registered) | 1064 | if (!pvt->is_registered[i]) |
1072 | count = sprintf(data, "socket %d, dimm0: %lu\n" | 1065 | count = sprintf(data, "socket %d, dimm0: %lu\n" |
1073 | "dimm1: %lu\ndimm2: %lu\n", | 1066 | "dimm1: %lu\ndimm2: %lu\n", |
1074 | i, | 1067 | i, |
@@ -1310,7 +1303,9 @@ static int mci_bind_devs(struct mem_ctl_info *mci) | |||
1310 | struct pci_dev *pdev; | 1303 | struct pci_dev *pdev; |
1311 | int i, j, func, slot; | 1304 | int i, j, func, slot; |
1312 | 1305 | ||
1306 | |||
1313 | for (i = 0; i < pvt->sockets; i++) { | 1307 | for (i = 0; i < pvt->sockets; i++) { |
1308 | pvt->is_registered[i] = 0; | ||
1314 | for (j = 0; j < N_DEVS; j++) { | 1309 | for (j = 0; j < N_DEVS; j++) { |
1315 | pdev = pci_devs[j].pdev[i]; | 1310 | pdev = pci_devs[j].pdev[i]; |
1316 | if (!pdev) | 1311 | if (!pdev) |
@@ -1334,6 +1329,10 @@ static int mci_bind_devs(struct mem_ctl_info *mci) | |||
1334 | debugf0("Associated fn %d.%d, dev = %p, socket %d\n", | 1329 | debugf0("Associated fn %d.%d, dev = %p, socket %d\n", |
1335 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | 1330 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), |
1336 | pdev, i); | 1331 | pdev, i); |
1332 | |||
1333 | if (PCI_SLOT(pdev->devfn) == 3 && | ||
1334 | PCI_FUNC(pdev->devfn) == 2) | ||
1335 | pvt->is_registered[i] = 1; | ||
1337 | } | 1336 | } |
1338 | } | 1337 | } |
1339 | 1338 | ||
@@ -1533,6 +1532,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, | |||
1533 | u32 syndrome = m->misc >> 32; | 1532 | u32 syndrome = m->misc >> 32; |
1534 | u32 errnum = find_first_bit(&error, 32); | 1533 | u32 errnum = find_first_bit(&error, 32); |
1535 | int csrow; | 1534 | int csrow; |
1535 | #ifdef CONFIG_SMP | ||
1536 | u32 socket_id = cpu_data[m->cpu].phys_proc_id; | ||
1537 | #else | ||
1538 | u32 socket_id = 0; | ||
1539 | #endif | ||
1536 | 1540 | ||
1537 | if (m->mcgstatus & 1) | 1541 | if (m->mcgstatus & 1) |
1538 | type = "FATAL"; | 1542 | type = "FATAL"; |
@@ -1596,19 +1600,22 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, | |||
1596 | msg = kasprintf(GFP_ATOMIC, | 1600 | msg = kasprintf(GFP_ATOMIC, |
1597 | "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " | 1601 | "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " |
1598 | "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", | 1602 | "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", |
1599 | type, (long long) m->addr, m->cpu, dimm, channel, | 1603 | type, (long long) m->addr, socket_id, dimm, channel, |
1600 | syndrome, core_err_cnt, (long long)m->status, | 1604 | syndrome, core_err_cnt, (long long)m->status, |
1601 | (long long)m->misc, optype, err); | 1605 | (long long)m->misc, optype, err); |
1602 | 1606 | ||
1603 | debugf0("%s", msg); | 1607 | debugf0("%s", msg); |
1604 | 1608 | ||
1605 | csrow = pvt->csrow_map[m->cpu][channel][dimm]; | 1609 | if (socket_id < NUM_SOCKETS) |
1610 | csrow = pvt->csrow_map[socket_id][channel][dimm]; | ||
1611 | else | ||
1612 | csrow = -1; | ||
1606 | 1613 | ||
1607 | /* Call the helper to output message */ | 1614 | /* Call the helper to output message */ |
1608 | if (m->mcgstatus & 1) | 1615 | if (m->mcgstatus & 1) |
1609 | edac_mc_handle_fbd_ue(mci, csrow, 0, | 1616 | edac_mc_handle_fbd_ue(mci, csrow, 0, |
1610 | 0 /* FIXME: should be channel here */, msg); | 1617 | 0 /* FIXME: should be channel here */, msg); |
1611 | else if (!pvt->is_registered) | 1618 | else if (!pvt->is_registered[socket_id]) |
1612 | edac_mc_handle_fbd_ce(mci, csrow, | 1619 | edac_mc_handle_fbd_ce(mci, csrow, |
1613 | 0 /* FIXME: should be channel here */, msg); | 1620 | 0 /* FIXME: should be channel here */, msg); |
1614 | 1621 | ||
@@ -1647,7 +1654,7 @@ static void i7core_check_error(struct mem_ctl_info *mci) | |||
1647 | 1654 | ||
1648 | /* check memory count errors */ | 1655 | /* check memory count errors */ |
1649 | for (i = 0; i < pvt->sockets; i++) | 1656 | for (i = 0; i < pvt->sockets; i++) |
1650 | if (!pvt->is_registered) | 1657 | if (!pvt->is_registered[i]) |
1651 | i7core_udimm_check_mc_ecc_err(mci, i); | 1658 | i7core_udimm_check_mc_ecc_err(mci, i); |
1652 | else | 1659 | else |
1653 | i7core_rdimm_check_mc_ecc_err(mci, i); | 1660 | i7core_rdimm_check_mc_ecc_err(mci, i); |