aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2017-05-22 20:06:03 -0400
committerBorislav Petkov <bp@suse.de>2017-05-25 05:47:11 -0400
commit7fd562b75d7752ed50c61d65f27b558cd93a359b (patch)
treed9ec3e7a013a19aa68e567fad858e8f940fefe71 /drivers/edac
parent00cf50d90a99fac96644078f40c88a7ad43fb71c (diff)
EDAC, sb_edac: Don't use "Socket#" in the memory controller name
EDAC assigns logical memory controller numbers in the order that we find memory controllers, which depends on which PCI bus they are on. Some systems end up with MC0 on socket0, others (e.g Haswell) have MC0 on socket3. All this is made more confusing for users because we use the string "Socket" while generating names for memory controllers, but the number that we attach there is the memory controller number. E.g. EDAC MC0: Giving out device to module sbridge_edac.c controller Haswell Socket#0: DEV 0000:ff:12.0 (INTERRUPT) Change the names to say "SrcID#%d" (where the number we use is read from the h/w associated with the memory controller instead of some logical number internal to the EDAC driver). New message: EDAC MC0: Giving out device to module sbridge_edac.c controller Haswell SrcID#3: DEV 0000:ff:12.0 (INTERRUPT) Reported-by: Andrey Korolyov <andrey@xdel.ru> Reported-by: Patrick Geary <patrickg@supermicro.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Cc: linux-edac <linux-edac@vger.kernel.org> Link: http://lkml.kernel.org/r/20170523000603.87748-1-qiuxu.zhuo@intel.com Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/sb_edac.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index fe4ffeaa623b..1990978e7963 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -1594,6 +1594,23 @@ static int knl_get_dimm_capacity(struct sbridge_pvt *pvt, u64 *mc_sizes)
1594 return 0; 1594 return 0;
1595} 1595}
1596 1596
1597static void get_source_id(struct mem_ctl_info *mci)
1598{
1599 struct sbridge_pvt *pvt = mci->pvt_info;
1600 u32 reg;
1601
1602 if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL ||
1603 pvt->info.type == KNIGHTS_LANDING)
1604 pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, &reg);
1605 else
1606 pci_read_config_dword(pvt->pci_br0, SAD_TARGET, &reg);
1607
1608 if (pvt->info.type == KNIGHTS_LANDING)
1609 pvt->sbridge_dev->source_id = SOURCE_ID_KNL(reg);
1610 else
1611 pvt->sbridge_dev->source_id = SOURCE_ID(reg);
1612}
1613
1597static int get_dimm_config(struct mem_ctl_info *mci) 1614static int get_dimm_config(struct mem_ctl_info *mci)
1598{ 1615{
1599 struct sbridge_pvt *pvt = mci->pvt_info; 1616 struct sbridge_pvt *pvt = mci->pvt_info;
@@ -1611,17 +1628,6 @@ static int get_dimm_config(struct mem_ctl_info *mci)
1611 pci_read_config_dword(pvt->pci_ha0, HASWELL_HASYSDEFEATURE2, &reg); 1628 pci_read_config_dword(pvt->pci_ha0, HASWELL_HASYSDEFEATURE2, &reg);
1612 pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21); 1629 pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
1613 } 1630 }
1614 if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL ||
1615 pvt->info.type == KNIGHTS_LANDING)
1616 pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, &reg);
1617 else
1618 pci_read_config_dword(pvt->pci_br0, SAD_TARGET, &reg);
1619
1620 if (pvt->info.type == KNIGHTS_LANDING)
1621 pvt->sbridge_dev->source_id = SOURCE_ID_KNL(reg);
1622 else
1623 pvt->sbridge_dev->source_id = SOURCE_ID(reg);
1624
1625 pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt); 1631 pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
1626 edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n", 1632 edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
1627 pvt->sbridge_dev->mc, 1633 pvt->sbridge_dev->mc,
@@ -3222,12 +3228,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3222 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 3228 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
3223 pvt->info.interleave_pkg = ibridge_interleave_pkg; 3229 pvt->info.interleave_pkg = ibridge_interleave_pkg;
3224 pvt->info.get_width = ibridge_get_width; 3230 pvt->info.get_width = ibridge_get_width;
3225 mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge Socket#%d", mci->mc_idx);
3226 3231
3227 /* Store pci devices at mci for faster access */ 3232 /* Store pci devices at mci for faster access */
3228 rc = ibridge_mci_bind_devs(mci, sbridge_dev); 3233 rc = ibridge_mci_bind_devs(mci, sbridge_dev);
3229 if (unlikely(rc < 0)) 3234 if (unlikely(rc < 0))
3230 goto fail0; 3235 goto fail0;
3236 get_source_id(mci);
3237 mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge SrcID#%d",
3238 pvt->sbridge_dev->source_id);
3231 break; 3239 break;
3232 case SANDY_BRIDGE: 3240 case SANDY_BRIDGE:
3233 pvt->info.rankcfgr = SB_RANK_CFG_A; 3241 pvt->info.rankcfgr = SB_RANK_CFG_A;
@@ -3245,12 +3253,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3245 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); 3253 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
3246 pvt->info.interleave_pkg = sbridge_interleave_pkg; 3254 pvt->info.interleave_pkg = sbridge_interleave_pkg;
3247 pvt->info.get_width = sbridge_get_width; 3255 pvt->info.get_width = sbridge_get_width;
3248 mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge Socket#%d", mci->mc_idx);
3249 3256
3250 /* Store pci devices at mci for faster access */ 3257 /* Store pci devices at mci for faster access */
3251 rc = sbridge_mci_bind_devs(mci, sbridge_dev); 3258 rc = sbridge_mci_bind_devs(mci, sbridge_dev);
3252 if (unlikely(rc < 0)) 3259 if (unlikely(rc < 0))
3253 goto fail0; 3260 goto fail0;
3261 get_source_id(mci);
3262 mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge SrcID#%d",
3263 pvt->sbridge_dev->source_id);
3254 break; 3264 break;
3255 case HASWELL: 3265 case HASWELL:
3256 /* rankcfgr isn't used */ 3266 /* rankcfgr isn't used */
@@ -3268,12 +3278,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3268 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 3278 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
3269 pvt->info.interleave_pkg = ibridge_interleave_pkg; 3279 pvt->info.interleave_pkg = ibridge_interleave_pkg;
3270 pvt->info.get_width = ibridge_get_width; 3280 pvt->info.get_width = ibridge_get_width;
3271 mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell Socket#%d", mci->mc_idx);
3272 3281
3273 /* Store pci devices at mci for faster access */ 3282 /* Store pci devices at mci for faster access */
3274 rc = haswell_mci_bind_devs(mci, sbridge_dev); 3283 rc = haswell_mci_bind_devs(mci, sbridge_dev);
3275 if (unlikely(rc < 0)) 3284 if (unlikely(rc < 0))
3276 goto fail0; 3285 goto fail0;
3286 get_source_id(mci);
3287 mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell SrcID#%d",
3288 pvt->sbridge_dev->source_id);
3277 break; 3289 break;
3278 case BROADWELL: 3290 case BROADWELL:
3279 /* rankcfgr isn't used */ 3291 /* rankcfgr isn't used */
@@ -3291,12 +3303,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3291 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 3303 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
3292 pvt->info.interleave_pkg = ibridge_interleave_pkg; 3304 pvt->info.interleave_pkg = ibridge_interleave_pkg;
3293 pvt->info.get_width = broadwell_get_width; 3305 pvt->info.get_width = broadwell_get_width;
3294 mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell Socket#%d", mci->mc_idx);
3295 3306
3296 /* Store pci devices at mci for faster access */ 3307 /* Store pci devices at mci for faster access */
3297 rc = broadwell_mci_bind_devs(mci, sbridge_dev); 3308 rc = broadwell_mci_bind_devs(mci, sbridge_dev);
3298 if (unlikely(rc < 0)) 3309 if (unlikely(rc < 0))
3299 goto fail0; 3310 goto fail0;
3311 get_source_id(mci);
3312 mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell SrcID#%d",
3313 pvt->sbridge_dev->source_id);
3300 break; 3314 break;
3301 case KNIGHTS_LANDING: 3315 case KNIGHTS_LANDING:
3302 /* pvt->info.rankcfgr == ??? */ 3316 /* pvt->info.rankcfgr == ??? */
@@ -3314,12 +3328,13 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3314 pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list); 3328 pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list);
3315 pvt->info.interleave_pkg = ibridge_interleave_pkg; 3329 pvt->info.interleave_pkg = ibridge_interleave_pkg;
3316 pvt->info.get_width = knl_get_width; 3330 pvt->info.get_width = knl_get_width;
3317 mci->ctl_name = kasprintf(GFP_KERNEL,
3318 "Knights Landing Socket#%d", mci->mc_idx);
3319 3331
3320 rc = knl_mci_bind_devs(mci, sbridge_dev); 3332 rc = knl_mci_bind_devs(mci, sbridge_dev);
3321 if (unlikely(rc < 0)) 3333 if (unlikely(rc < 0))
3322 goto fail0; 3334 goto fail0;
3335 get_source_id(mci);
3336 mci->ctl_name = kasprintf(GFP_KERNEL, "Knights Landing SrcID#%d",
3337 pvt->sbridge_dev->source_id);
3323 break; 3338 break;
3324 } 3339 }
3325 3340
@@ -3334,13 +3349,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
3334 if (unlikely(edac_mc_add_mc(mci))) { 3349 if (unlikely(edac_mc_add_mc(mci))) {
3335 edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); 3350 edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
3336 rc = -EINVAL; 3351 rc = -EINVAL;
3337 goto fail0; 3352 goto fail;
3338 } 3353 }
3339 3354
3340 return 0; 3355 return 0;
3341 3356
3342fail0: 3357fail:
3343 kfree(mci->ctl_name); 3358 kfree(mci->ctl_name);
3359fail0:
3344 edac_mc_free(mci); 3360 edac_mc_free(mci);
3345 sbridge_dev->mci = NULL; 3361 sbridge_dev->mci = NULL;
3346 return rc; 3362 return rc;