Skip to content

Commit 4aa92c8

Browse files
Robert Richtersuryasaimadhu
authored andcommitted
EDAC/mc: Remove per layer counters
Looking at how mci->{ue,ce}_per_layer[EDAC_MAX_LAYERS] is used, it turns out that only the leaves in the memory hierarchy are consumed (in sysfs), but not the intermediate layers, e.g.: count = dimm->mci->ce_per_layer[dimm->mci->n_layers-1][dimm->idx]; These unused counters only add complexity, remove them. The error counter values are directly stored in struct dimm_info now. Signed-off-by: Robert Richter <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Acked-by: Aristeu Rozanski <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 1853ee7 commit 4aa92c8

File tree

3 files changed

+27
-64
lines changed

3 files changed

+27
-64
lines changed

drivers/edac/edac_mc.c

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
451451
{
452452
struct mem_ctl_info *mci;
453453
struct edac_mc_layer *layer;
454-
u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
455-
unsigned int idx, size, tot_dimms = 1, count = 1;
456-
unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
454+
unsigned int idx, size, tot_dimms = 1;
455+
unsigned int tot_csrows = 1, tot_channels = 1;
457456
void *pvt, *ptr = NULL;
458-
int i;
459457
bool per_rank = false;
460458

461459
if (WARN_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0))
@@ -482,19 +480,10 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
482480
* stringent as what the compiler would provide if we could simply
483481
* hardcode everything into a single struct.
484482
*/
485-
mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
486-
layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
487-
for (i = 0; i < n_layers; i++) {
488-
count *= layers[i].size;
489-
edac_dbg(4, "errcount layer %d size %d\n", i, count);
490-
ce_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
491-
ue_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
492-
tot_errcount += 2 * count;
493-
}
494-
495-
edac_dbg(4, "allocating %d error counters\n", tot_errcount);
496-
pvt = edac_align_ptr(&ptr, sz_pvt, 1);
497-
size = ((unsigned long)pvt) + sz_pvt;
483+
mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
484+
layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
485+
pvt = edac_align_ptr(&ptr, sz_pvt, 1);
486+
size = ((unsigned long)pvt) + sz_pvt;
498487

499488
edac_dbg(1, "allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
500489
size,
@@ -513,10 +502,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
513502
* rather than an imaginary chunk of memory located at address 0.
514503
*/
515504
layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
516-
for (i = 0; i < n_layers; i++) {
517-
mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
518-
mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
519-
}
520505
pvt = sz_pvt ? (((char *)mci) + ((unsigned long)pvt)) : NULL;
521506

522507
/* setup index and various internal pointers */
@@ -949,48 +934,28 @@ static void edac_inc_ce_error(struct edac_raw_error_desc *e)
949934
{
950935
int pos[EDAC_MAX_LAYERS] = { e->top_layer, e->mid_layer, e->low_layer };
951936
struct mem_ctl_info *mci = error_desc_to_mci(e);
952-
int i, index = 0;
937+
struct dimm_info *dimm = edac_get_dimm(mci, pos[0], pos[1], pos[2]);
953938

954939
mci->ce_mc += e->error_count;
955940

956-
if (pos[0] < 0) {
941+
if (dimm)
942+
dimm->ce_count += e->error_count;
943+
else
957944
mci->ce_noinfo_count += e->error_count;
958-
return;
959-
}
960-
961-
for (i = 0; i < mci->n_layers; i++) {
962-
if (pos[i] < 0)
963-
break;
964-
index += pos[i];
965-
mci->ce_per_layer[i][index] += e->error_count;
966-
967-
if (i < mci->n_layers - 1)
968-
index *= mci->layers[i + 1].size;
969-
}
970945
}
971946

972947
static void edac_inc_ue_error(struct edac_raw_error_desc *e)
973948
{
974949
int pos[EDAC_MAX_LAYERS] = { e->top_layer, e->mid_layer, e->low_layer };
975950
struct mem_ctl_info *mci = error_desc_to_mci(e);
976-
int i, index = 0;
951+
struct dimm_info *dimm = edac_get_dimm(mci, pos[0], pos[1], pos[2]);
977952

978953
mci->ue_mc += e->error_count;
979954

980-
if (pos[0] < 0) {
955+
if (dimm)
956+
dimm->ue_count += e->error_count;
957+
else
981958
mci->ue_noinfo_count += e->error_count;
982-
return;
983-
}
984-
985-
for (i = 0; i < mci->n_layers; i++) {
986-
if (pos[i] < 0)
987-
break;
988-
index += pos[i];
989-
mci->ue_per_layer[i][index] += e->error_count;
990-
991-
if (i < mci->n_layers - 1)
992-
index *= mci->layers[i + 1].size;
993-
}
994959
}
995960

996961
static void edac_ce_error(struct edac_raw_error_desc *e)
@@ -1143,8 +1108,8 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
11431108

11441109
/*
11451110
* Check if the event report is consistent and if the memory location is
1146-
* known. If it is, the DIMM(s) label info will be filled and the
1147-
* per-layer error counters will be incremented.
1111+
* known. If it is, the DIMM(s) label info will be filled and the DIMM's
1112+
* error counters will be incremented.
11481113
*/
11491114
for (i = 0; i < mci->n_layers; i++) {
11501115
if (pos[i] >= (int)mci->layers[i].size) {

drivers/edac/edac_mc_sysfs.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -551,21 +551,17 @@ static ssize_t dimmdev_ce_count_show(struct device *dev,
551551
char *data)
552552
{
553553
struct dimm_info *dimm = to_dimm(dev);
554-
u32 count;
555554

556-
count = dimm->mci->ce_per_layer[dimm->mci->n_layers-1][dimm->idx];
557-
return sprintf(data, "%u\n", count);
555+
return sprintf(data, "%u\n", dimm->ce_count);
558556
}
559557

560558
static ssize_t dimmdev_ue_count_show(struct device *dev,
561559
struct device_attribute *mattr,
562560
char *data)
563561
{
564562
struct dimm_info *dimm = to_dimm(dev);
565-
u32 count;
566563

567-
count = dimm->mci->ue_per_layer[dimm->mci->n_layers-1][dimm->idx];
568-
return sprintf(data, "%u\n", count);
564+
return sprintf(data, "%u\n", dimm->ue_count);
569565
}
570566

571567
/* dimm/rank attribute files */
@@ -661,7 +657,9 @@ static ssize_t mci_reset_counters_store(struct device *dev,
661657
const char *data, size_t count)
662658
{
663659
struct mem_ctl_info *mci = to_mci(dev);
664-
int cnt, row, chan, i;
660+
struct dimm_info *dimm;
661+
int row, chan;
662+
665663
mci->ue_mc = 0;
666664
mci->ce_mc = 0;
667665
mci->ue_noinfo_count = 0;
@@ -677,11 +675,9 @@ static ssize_t mci_reset_counters_store(struct device *dev,
677675
ri->channels[chan]->ce_count = 0;
678676
}
679677

680-
cnt = 1;
681-
for (i = 0; i < mci->n_layers; i++) {
682-
cnt *= mci->layers[i].size;
683-
memset(mci->ce_per_layer[i], 0, cnt * sizeof(u32));
684-
memset(mci->ue_per_layer[i], 0, cnt * sizeof(u32));
678+
mci_for_each_dimm(mci, dimm) {
679+
dimm->ue_count = 0;
680+
dimm->ce_count = 0;
685681
}
686682

687683
mci->start_time = jiffies;

include/linux/edac.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ struct dimm_info {
383383
unsigned int csrow, cschannel; /* Points to the old API data */
384384

385385
u16 smbios_handle; /* Handle for SMBIOS type 17 */
386+
387+
u32 ce_count;
388+
u32 ue_count;
386389
};
387390

388391
/**
@@ -559,7 +562,6 @@ struct mem_ctl_info {
559562
*/
560563
u32 ce_noinfo_count, ue_noinfo_count;
561564
u32 ue_mc, ce_mc;
562-
u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
563565

564566
struct completion complete;
565567

0 commit comments

Comments
 (0)