aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasayoshi Mizuma <m.mizuma@jp.fujitsu.com>2018-07-24 15:02:13 -0400
committerBorislav Petkov <bp@suse.de>2018-07-25 05:17:15 -0400
commit190bd6e98afc512fb16d4a471acd488e36141637 (patch)
tree0c017ecb2a0a5090250a2641298cf53369e83fd6
parent6663484b4e2d98f5609dc1b90fe4c242dd8fe18a (diff)
EDAC, sb_edac: Add support for systems with segmented PCI buses
Extend the driver to check whether segment number and bus number matches when deciding how to group memory controller PCI devices to CPU sockets. Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com> Reviewed-by: Tony Luck <tony.luck@intel.com> Cc: Mauro Carvalho Chehab <mchehab@kernel.org> Cc: linux-edac <linux-edac@vger.kernel.org> Link: http://lkml.kernel.org/r/20180724190213.26359-1-msys.mizuma@gmail.com [ Cleanup commit message. ] Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r--drivers/edac/sb_edac.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 4a89c8093307..07726fb00321 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -352,6 +352,7 @@ struct pci_id_table {
352 352
353struct sbridge_dev { 353struct sbridge_dev {
354 struct list_head list; 354 struct list_head list;
355 int seg;
355 u8 bus, mc; 356 u8 bus, mc;
356 u8 node_id, source_id; 357 u8 node_id, source_id;
357 struct pci_dev **pdev; 358 struct pci_dev **pdev;
@@ -729,7 +730,8 @@ static inline int numcol(u32 mtr)
729 return 1 << cols; 730 return 1 << cols;
730} 731}
731 732
732static struct sbridge_dev *get_sbridge_dev(u8 bus, enum domain dom, int multi_bus, 733static struct sbridge_dev *get_sbridge_dev(int seg, u8 bus, enum domain dom,
734 int multi_bus,
733 struct sbridge_dev *prev) 735 struct sbridge_dev *prev)
734{ 736{
735 struct sbridge_dev *sbridge_dev; 737 struct sbridge_dev *sbridge_dev;
@@ -747,14 +749,15 @@ static struct sbridge_dev *get_sbridge_dev(u8 bus, enum domain dom, int multi_bu
747 : sbridge_edac_list.next, struct sbridge_dev, list); 749 : sbridge_edac_list.next, struct sbridge_dev, list);
748 750
749 list_for_each_entry_from(sbridge_dev, &sbridge_edac_list, list) { 751 list_for_each_entry_from(sbridge_dev, &sbridge_edac_list, list) {
750 if (sbridge_dev->bus == bus && (dom == SOCK || dom == sbridge_dev->dom)) 752 if ((sbridge_dev->seg == seg) && (sbridge_dev->bus == bus) &&
753 (dom == SOCK || dom == sbridge_dev->dom))
751 return sbridge_dev; 754 return sbridge_dev;
752 } 755 }
753 756
754 return NULL; 757 return NULL;
755} 758}
756 759
757static struct sbridge_dev *alloc_sbridge_dev(u8 bus, enum domain dom, 760static struct sbridge_dev *alloc_sbridge_dev(int seg, u8 bus, enum domain dom,
758 const struct pci_id_table *table) 761 const struct pci_id_table *table)
759{ 762{
760 struct sbridge_dev *sbridge_dev; 763 struct sbridge_dev *sbridge_dev;
@@ -771,6 +774,7 @@ static struct sbridge_dev *alloc_sbridge_dev(u8 bus, enum domain dom,
771 return NULL; 774 return NULL;
772 } 775 }
773 776
777 sbridge_dev->seg = seg;
774 sbridge_dev->bus = bus; 778 sbridge_dev->bus = bus;
775 sbridge_dev->dom = dom; 779 sbridge_dev->dom = dom;
776 sbridge_dev->n_devs = table->n_devs_per_imc; 780 sbridge_dev->n_devs = table->n_devs_per_imc;
@@ -2246,6 +2250,7 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
2246 struct sbridge_dev *sbridge_dev = NULL; 2250 struct sbridge_dev *sbridge_dev = NULL;
2247 const struct pci_id_descr *dev_descr = &table->descr[devno]; 2251 const struct pci_id_descr *dev_descr = &table->descr[devno];
2248 struct pci_dev *pdev = NULL; 2252 struct pci_dev *pdev = NULL;
2253 int seg = 0;
2249 u8 bus = 0; 2254 u8 bus = 0;
2250 int i = 0; 2255 int i = 0;
2251 2256
@@ -2276,10 +2281,12 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
2276 /* End of list, leave */ 2281 /* End of list, leave */
2277 return -ENODEV; 2282 return -ENODEV;
2278 } 2283 }
2284 seg = pci_domain_nr(pdev->bus);
2279 bus = pdev->bus->number; 2285 bus = pdev->bus->number;
2280 2286
2281next_imc: 2287next_imc:
2282 sbridge_dev = get_sbridge_dev(bus, dev_descr->dom, multi_bus, sbridge_dev); 2288 sbridge_dev = get_sbridge_dev(seg, bus, dev_descr->dom,
2289 multi_bus, sbridge_dev);
2283 if (!sbridge_dev) { 2290 if (!sbridge_dev) {
2284 /* If the HA1 wasn't found, don't create EDAC second memory controller */ 2291 /* If the HA1 wasn't found, don't create EDAC second memory controller */
2285 if (dev_descr->dom == IMC1 && devno != 1) { 2292 if (dev_descr->dom == IMC1 && devno != 1) {
@@ -2292,7 +2299,7 @@ next_imc:
2292 if (dev_descr->dom == SOCK) 2299 if (dev_descr->dom == SOCK)
2293 goto out_imc; 2300 goto out_imc;
2294 2301
2295 sbridge_dev = alloc_sbridge_dev(bus, dev_descr->dom, table); 2302 sbridge_dev = alloc_sbridge_dev(seg, bus, dev_descr->dom, table);
2296 if (!sbridge_dev) { 2303 if (!sbridge_dev) {
2297 pci_dev_put(pdev); 2304 pci_dev_put(pdev);
2298 return -ENOMEM; 2305 return -ENOMEM;