EDAC: Introduce an mci_for_each_dimm() iterator
authorRobert Richter <rrichter@marvell.com>
Wed, 6 Nov 2019 09:33:07 +0000 (09:33 +0000)
committerBorislav Petkov <bp@suse.de>
Sun, 10 Nov 2019 11:39:40 +0000 (12:39 +0100)
Introduce an mci_for_each_dimm() iterator. It returns a pointer to
a struct dimm_info. This makes the declaration and use of an index
obsolete and avoids access to internal data of struct mci (direct array
access etc).

 [ bp: push the struct dimm_info *dimm; declaration into the
   CONFIG_EDAC_DEBUG block. ]

Signed-off-by: Robert Richter <rrichter@marvell.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Cc: "linux-edac@vger.kernel.org" <linux-edac@vger.kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Tony Luck <tony.luck@intel.com>
Link: https://lkml.kernel.org/r/20191106093239.25517-4-rrichter@marvell.com
drivers/edac/edac_mc.c
drivers/edac/edac_mc_sysfs.c
drivers/edac/ghes_edac.c
drivers/edac/i5100_edac.c
include/linux/edac.h

index cb53564..88e24ec 100644 (file)
@@ -145,15 +145,18 @@ static void edac_mc_dump_channel(struct rank_info *chan)
        edac_dbg(4, "    channel->dimm = %p\n", chan->dimm);
 }
 
-static void edac_mc_dump_dimm(struct dimm_info *dimm, int number)
+static void edac_mc_dump_dimm(struct dimm_info *dimm)
 {
        char location[80];
 
+       if (!dimm->nr_pages)
+               return;
+
        edac_dimm_info_location(dimm, location, sizeof(location));
 
        edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n",
                 dimm->mci->csbased ? "rank" : "dimm",
-                number, location, dimm->csrow, dimm->cschannel);
+                dimm->idx, location, dimm->csrow, dimm->cschannel);
        edac_dbg(4, "  dimm = %p\n", dimm);
        edac_dbg(4, "  dimm->label = '%s'\n", dimm->label);
        edac_dbg(4, "  dimm->nr_pages = 0x%x\n", dimm->nr_pages);
@@ -712,6 +715,7 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
                edac_mc_dump_mci(mci);
 
        if (edac_debug_level >= 4) {
+               struct dimm_info *dimm;
                int i;
 
                for (i = 0; i < mci->nr_csrows; i++) {
@@ -728,9 +732,9 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
                                if (csrow->channels[j]->dimm->nr_pages)
                                        edac_mc_dump_channel(csrow->channels[j]);
                }
-               for (i = 0; i < mci->tot_dimms; i++)
-                       if (mci->dimms[i]->nr_pages)
-                               edac_mc_dump_dimm(mci->dimms[i], i);
+
+               mci_for_each_dimm(mci, dimm)
+                       edac_mc_dump_dimm(dimm);
        }
 #endif
        mutex_lock(&mem_ctls_mutex);
@@ -1088,6 +1092,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                          const char *msg,
                          const char *other_detail)
 {
+       struct dimm_info *dimm;
        char *p;
        int row = -1, chan = -1;
        int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer };
@@ -1148,9 +1153,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
        p = e->label;
        *p = '\0';
 
-       for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = mci->dimms[i];
-
+       mci_for_each_dimm(mci, dimm) {
                if (top_layer >= 0 && top_layer != dimm->location[0])
                        continue;
                if (mid_layer >= 0 && mid_layer != dimm->location[1])
index 91e4c8f..0367554 100644 (file)
@@ -621,8 +621,7 @@ static const struct device_type dimm_attr_type = {
 
 /* Create a DIMM object under specifed memory controller device */
 static int edac_create_dimm_object(struct mem_ctl_info *mci,
-                                  struct dimm_info *dimm,
-                                  int index)
+                                  struct dimm_info *dimm)
 {
        int err;
        dimm->mci = mci;
@@ -632,9 +631,9 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
 
        dimm->dev.parent = &mci->dev;
        if (mci->csbased)
-               dev_set_name(&dimm->dev, "rank%d", index);
+               dev_set_name(&dimm->dev, "rank%d", dimm->idx);
        else
-               dev_set_name(&dimm->dev, "dimm%d", index);
+               dev_set_name(&dimm->dev, "dimm%d", dimm->idx);
        dev_set_drvdata(&dimm->dev, dimm);
        pm_runtime_forbid(&mci->dev);
 
@@ -916,7 +915,8 @@ static const struct device_type mci_attr_type = {
 int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
                                 const struct attribute_group **groups)
 {
-       int i, err;
+       struct dimm_info *dimm;
+       int err;
 
        /* get the /sys/devices/system/edac subsys reference */
        mci->dev.type = &mci_attr_type;
@@ -940,13 +940,12 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
        /*
         * Create the dimm/rank devices
         */
-       for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = mci->dimms[i];
+       mci_for_each_dimm(mci, dimm) {
                /* Only expose populated DIMMs */
                if (!dimm->nr_pages)
                        continue;
 
-               err = edac_create_dimm_object(mci, dimm, i);
+               err = edac_create_dimm_object(mci, dimm);
                if (err)
                        goto fail_unregister_dimm;
        }
@@ -961,12 +960,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
        return 0;
 
 fail_unregister_dimm:
-       for (i--; i >= 0; i--) {
-               struct dimm_info *dimm = mci->dimms[i];
-               if (!dimm->nr_pages)
-                       continue;
-
-               device_unregister(&dimm->dev);
+       mci_for_each_dimm(mci, dimm) {
+               if (device_is_registered(&dimm->dev))
+                       device_unregister(&dimm->dev);
        }
        device_unregister(&mci->dev);
 
@@ -978,7 +974,7 @@ fail_unregister_dimm:
  */
 void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
 {
-       int i;
+       struct dimm_info *dimm;
 
        edac_dbg(0, "\n");
 
@@ -989,8 +985,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
        edac_delete_csrow_objects(mci);
 #endif
 
-       for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = mci->dimms[i];
+       mci_for_each_dimm(mci, dimm) {
                if (dimm->nr_pages == 0)
                        continue;
                edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev));
index 2275d6b..fbc8b1d 100644 (file)
@@ -90,12 +90,13 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg)
 
 static int get_dimm_smbios_index(struct mem_ctl_info *mci, u16 handle)
 {
-       int i;
+       struct dimm_info *dimm;
 
-       for (i = 0; i < mci->tot_dimms; i++) {
-               if (mci->dimms[i]->smbios_handle == handle)
-                       return i;
+       mci_for_each_dimm(mci, dimm) {
+               if (dimm->smbios_handle == handle)
+                       return dimm->idx;
        }
+
        return -1;
 }
 
index 1345867..0ddc41e 100644 (file)
@@ -846,20 +846,17 @@ static void i5100_init_interleaving(struct pci_dev *pdev,
 
 static void i5100_init_csrows(struct mem_ctl_info *mci)
 {
-       int i;
        struct i5100_priv *priv = mci->pvt_info;
+       struct dimm_info *dimm;
 
-       for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm;
-               const unsigned long npages = i5100_npages(mci, i);
-               const unsigned int chan = i5100_csrow_to_chan(mci, i);
-               const unsigned int rank = i5100_csrow_to_rank(mci, i);
+       mci_for_each_dimm(mci, dimm) {
+               const unsigned long npages = i5100_npages(mci, dimm->idx);
+               const unsigned int chan = i5100_csrow_to_chan(mci, dimm->idx);
+               const unsigned int rank = i5100_csrow_to_rank(mci, dimm->idx);
 
                if (!npages)
                        continue;
 
-               dimm = edac_get_dimm(mci, chan, rank, 0);
-
                dimm->nr_pages = npages;
                dimm->grain = 32;
                dimm->dtype = (priv->mtr[chan][rank].width == 4) ?
index f4ebb14..31f99d4 100644 (file)
@@ -599,6 +599,13 @@ struct mem_ctl_info {
        u16 fake_inject_count;
 };
 
+#define mci_for_each_dimm(mci, dimm)                           \
+       for ((dimm) = (mci)->dimms[0];                          \
+            (dimm);                                            \
+            (dimm) = (dimm)->idx + 1 < (mci)->tot_dimms        \
+                    ? (mci)->dimms[(dimm)->idx + 1]            \
+                    : NULL)
+
 /**
  * edac_get_dimm_by_index - Get DIMM info at @index from a memory
  *                         controller