]> www.infradead.org Git - users/mchehab/edac.git/commitdiff
edac: Initialize the dimm label with the known information
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 9 Feb 2012 14:05:20 +0000 (11:05 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 8 May 2012 11:45:17 +0000 (08:45 -0300)
While userspace doesn't fill the dimm labels, add there the dimm location,
as described by the used memory model. This could eventually match what
is described at the dmidecode, making easier for people to identify the
memory.

For example, on an Intel motherboard, the memory is described as:

Memory Device
Array Handle: 0x0029
Error Information Handle: Not Provided
Total Width: 64 bits
Data Width: 64 bits
Size: 2048 MB
Form Factor: DIMM
Set: 1
Locator: A1_DIMM0
Bank Locator: A1_Node0_Channel0_Dimm0
Type: <OUT OF SPEC>
Type Detail: Synchronous
Speed: 800 MHz
Manufacturer: A1_Manufacturer0
Serial Number: A1_SerNum0
Asset Tag: A1_AssetTagNum0
Part Number: A1_PartNum0

After this patch, the memory label will be filled with:
/sys/devices/system/edac/mc/mc0/dimm0/dimm_label:mc#0channel#0slot#0

With somewhat matches what it is at the Bank Locator DMI information.
So, it is easier to associate the dimm labels, of course assuming that
the DMI has the Bank Locator filled, and the BIOS doesn't have any bugs.

Yet, even without it, several motherboards are provided with enough
info to map from channel/slot (or branch/channel/slot) into the DIMM
label. So, letting the EDAC core fill it, by default is a good thing.

It should noticed that, as the label filling happens at the
edac_mc_alloc(), drivers can override it to better describe the memories
(and some actually do it).

Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/edac/edac_mc.c
drivers/edac/edac_mc_sysfs.c
include/linux/edac.h

index 03f8fb2e5a6c7d0cc48e90ad7db8552b63b9411d..e5b55632359f54d94ff9c76e102fb19efa26a7d5 100644 (file)
@@ -210,10 +210,10 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        struct dimm_info *dimm;
        u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
        unsigned pos[EDAC_MAX_LAYERS];
-       void *pvt, *ptr = NULL;
        unsigned size, tot_dimms = 1, count = 1;
        unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
-       int i, j, err, row, chn;
+       void *pvt, *p, *ptr = NULL;
+       int i, j, err, row, chn, n, len;
        bool per_rank = false;
 
        BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
@@ -325,9 +325,22 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
                        i, per_rank ? "rank" : "dimm", (dimm - mci->dimms),
                        pos[0], pos[1], pos[2], row, chn);
 
-               /* Copy DIMM location */
-               for (j = 0; j < n_layers; j++)
+               /*
+                * Copy DIMM location and initialize the memory location
+                */
+               len = sizeof(dimm->label);
+               p = dimm->label;
+               n = snprintf(p, len, "mc#%u", mc_num);
+               p += n;
+               len -= n;
+               for (j = 0; j < n_layers; j++) {
+                       n = snprintf(p, len, "%s#%u",
+                                    edac_layer_name[layers[j].type],
+                                    pos[j]);
+                       p += n;
+                       len -= n;
                        dimm->location[j] = pos[j];
+               }
 
                /* Link it to the csrows old API data */
                chan->dimm = dimm;
@@ -834,7 +847,7 @@ static void edac_inc_ce_error(struct mem_ctl_info *mci,
 {
        int i, index = 0;
 
-       mci->ce_count++;
+       mci->ce_mc++;
 
        if (!enable_per_layer_report) {
                mci->ce_noinfo_count++;
@@ -858,7 +871,7 @@ static void edac_inc_ue_error(struct mem_ctl_info *mci,
 {
        int i, index = 0;
 
-       mci->ue_count++;
+       mci->ue_mc++;
 
        if (!enable_per_layer_report) {
                mci->ce_noinfo_count++;
index c0275e61cfd30501536f015cc1e3af72a59f4a8e..cfeb92c08f0647e7ba2b6fc1b1a6fb1d1a9408d2 100644 (file)
@@ -425,8 +425,8 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
 
        mci->ue_noinfo_count = 0;
        mci->ce_noinfo_count = 0;
-       mci->ue_count = 0;
-       mci->ce_count = 0;
+       mci->ue_mc = 0;
+       mci->ce_mc = 0;
 
        for (row = 0; row < mci->nr_csrows; row++) {
                struct csrow_info *ri = &mci->csrows[row];
@@ -495,12 +495,12 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
 /* default attribute files for the MCI object */
 static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
 {
-       return sprintf(data, "%d\n", mci->ue_count);
+       return sprintf(data, "%d\n", mci->ue_mc);
 }
 
 static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data)
 {
-       return sprintf(data, "%d\n", mci->ce_count);
+       return sprintf(data, "%d\n", mci->ce_mc);
 }
 
 static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data)
index c8f507df5490eff79469f595b114bee474ff5133..d6b0c258eb4fb0b6a430d1fb80985ea972a19497 100644 (file)
@@ -577,7 +577,7 @@ struct mem_ctl_info {
         * already handles that.
         */
        u32 ce_noinfo_count, ue_noinfo_count;
-       u32 ue_count, ce_count;
+       u32 ue_mc, ce_mc;
        u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
 
        struct completion complete;