Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

EDAC/{skx_common,skx}: Use configuration data, not global macros

Use model-specific configuration data for the number of memory controllers
per socket, channels per memory controller, and DIMMs per channel as
intended, instead of relying on global macros for maximum values.

No functional changes intended.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/r/20250731145534.2759334-2-qiuxu.zhuo@intel.com

authored by

Qiuxu Zhuo and committed by
Tony Luck
219af5df 2e6fe1bb

+30 -20
+20 -13
drivers/edac/skx_base.c
··· 33 33 #define MASK26 0x3FFFFFF /* Mask for 2^26 */ 34 34 #define MASK29 0x1FFFFFFF /* Mask for 2^29 */ 35 35 36 + static struct res_config skx_cfg = { 37 + .type = SKX, 38 + .decs_did = 0x2016, 39 + .busno_cfg_offset = 0xcc, 40 + .ddr_imc_num = 2, 41 + .ddr_chan_num = 3, 42 + .ddr_dimm_num = 2, 43 + }; 44 + 36 45 static struct skx_dev *get_skx_dev(struct pci_bus *bus, u8 idx) 37 46 { 38 47 struct skx_dev *d; ··· 61 52 62 53 struct munit { 63 54 u16 did; 64 - u16 devfn[SKX_NUM_IMC]; 55 + u16 devfn[2]; 65 56 u8 busidx; 66 57 u8 per_socket; 67 58 enum munittype mtype; ··· 98 89 if (!pdev) 99 90 break; 100 91 ndev++; 101 - if (m->per_socket == SKX_NUM_IMC) { 102 - for (i = 0; i < SKX_NUM_IMC; i++) 92 + if (m->per_socket == skx_cfg.ddr_imc_num) { 93 + for (i = 0; i < skx_cfg.ddr_imc_num; i++) 103 94 if (m->devfn[i] == pdev->devfn) 104 95 break; 105 - if (i == SKX_NUM_IMC) 96 + if (i == skx_cfg.ddr_imc_num) 106 97 goto fail; 107 98 } 108 99 d = get_skx_dev(pdev->bus, m->busidx); ··· 166 157 return -ENODEV; 167 158 } 168 159 169 - static struct res_config skx_cfg = { 170 - .type = SKX, 171 - .decs_did = 0x2016, 172 - .busno_cfg_offset = 0xcc, 173 - }; 174 - 175 160 static const struct x86_cpu_id skx_cpuids[] = { 176 161 X86_MATCH_VFM(INTEL_SKYLAKE_X, &skx_cfg), 177 162 { } ··· 189 186 /* Only the mcmtr on the first channel is effective */ 190 187 pci_read_config_dword(imc->chan[0].cdev, 0x87c, &mcmtr); 191 188 192 - for (i = 0; i < SKX_NUM_CHANNELS; i++) { 189 + for (i = 0; i < cfg->ddr_chan_num; i++) { 193 190 ndimms = 0; 194 191 pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap); 195 192 pci_read_config_dword(imc->chan[i].cdev, 0x400, &mcddrtcfg); 196 - for (j = 0; j < SKX_NUM_DIMMS; j++) { 193 + for (j = 0; j < cfg->ddr_dimm_num; j++) { 197 194 dimm = edac_get_dimm(mci, i, j, 0); 198 195 pci_read_config_dword(imc->chan[i].cdev, 199 196 0x80 + 4 * j, &mtr); ··· 623 620 return -ENODEV; 624 621 625 622 cfg = (struct res_config *)id->driver_data; 623 + skx_set_res_cfg(cfg); 626 624 627 625 rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm); 628 626 if (rc) ··· 656 652 goto fail; 657 653 658 654 edac_dbg(2, "src_id = %d\n", src_id); 659 - for (i = 0; i < SKX_NUM_IMC; i++) { 655 + for (i = 0; i < cfg->ddr_imc_num; i++) { 660 656 d->imc[i].mc = mc++; 661 657 d->imc[i].lmc = i; 662 658 d->imc[i].src_id = src_id; 659 + d->imc[i].num_channels = cfg->ddr_chan_num; 660 + d->imc[i].num_dimms = cfg->ddr_dimm_num; 661 + 663 662 rc = skx_register_mci(&d->imc[i], d->imc[i].chan[0].cdev, 664 663 "Skylake Socket", EDAC_MOD_STR, 665 664 skx_get_dimm_config, cfg);
+9 -7
drivers/edac/skx_common.c
··· 320 320 */ 321 321 int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list) 322 322 { 323 + int ndev = 0, imc_num = cfg->ddr_imc_num + cfg->hbm_imc_num; 323 324 struct pci_dev *pdev, *prev; 324 325 struct skx_dev *d; 325 326 u32 reg; 326 - int ndev = 0; 327 327 328 328 prev = NULL; 329 329 for (;;) { ··· 354 354 d->seg = GET_BITFIELD(reg, 16, 23); 355 355 } 356 356 357 - edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x\n", 358 - d->bus[0], d->bus[1], d->bus[2], d->bus[3]); 357 + d->num_imc = imc_num; 358 + 359 + edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x, imcs %d\n", 360 + d->bus[0], d->bus[1], d->bus[2], d->bus[3], imc_num); 359 361 list_add_tail(&d->list, &dev_edac_list); 360 362 prev = pdev; 361 363 ··· 543 541 544 542 /* Allocate a new MC control structure */ 545 543 layers[0].type = EDAC_MC_LAYER_CHANNEL; 546 - layers[0].size = NUM_CHANNELS; 544 + layers[0].size = imc->num_channels; 547 545 layers[0].is_virt_csrow = false; 548 546 layers[1].type = EDAC_MC_LAYER_SLOT; 549 - layers[1].size = NUM_DIMMS; 547 + layers[1].size = imc->num_dimms; 550 548 layers[1].is_virt_csrow = true; 551 549 mci = edac_mc_alloc(imc->mc, ARRAY_SIZE(layers), layers, 552 550 sizeof(struct skx_pvt)); ··· 786 784 787 785 list_for_each_entry_safe(d, tmp, &dev_edac_list, list) { 788 786 list_del(&d->list); 789 - for (i = 0; i < NUM_IMC; i++) { 787 + for (i = 0; i < d->num_imc; i++) { 790 788 if (d->imc[i].mci) 791 789 skx_unregister_mci(&d->imc[i]); 792 790 ··· 796 794 if (d->imc[i].mbase) 797 795 iounmap(d->imc[i].mbase); 798 796 799 - for (j = 0; j < NUM_CHANNELS; j++) { 797 + for (j = 0; j < d->imc[i].num_channels; j++) { 800 798 if (d->imc[i].chan[j].cdev) 801 799 pci_dev_put(d->imc[i].chan[j].cdev); 802 800 }
+1
drivers/edac/skx_common.h
··· 134 134 struct pci_dev *uracu; /* for i10nm CPU */ 135 135 struct pci_dev *pcu_cr3; /* for HBM memory detection */ 136 136 u32 mcroute; 137 + int num_imc; 137 138 /* 138 139 * Some server BIOS may hide certain memory controllers, and the 139 140 * EDAC driver skips those hidden memory controllers. However, the