Commit c498afaf authored by Robert Richter's avatar Robert Richter Committed by Borislav Petkov

EDAC: Introduce an mci_for_each_dimm() iterator

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: default avatarRobert Richter <rrichter@marvell.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarMauro 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
parent 977b1ce7
...@@ -145,15 +145,18 @@ static void edac_mc_dump_channel(struct rank_info *chan) ...@@ -145,15 +145,18 @@ static void edac_mc_dump_channel(struct rank_info *chan)
edac_dbg(4, " channel->dimm = %p\n", chan->dimm); 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]; char location[80];
if (!dimm->nr_pages)
return;
edac_dimm_info_location(dimm, location, sizeof(location)); edac_dimm_info_location(dimm, location, sizeof(location));
edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n", edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n",
dimm->mci->csbased ? "rank" : "dimm", 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 = %p\n", dimm);
edac_dbg(4, " dimm->label = '%s'\n", dimm->label); edac_dbg(4, " dimm->label = '%s'\n", dimm->label);
edac_dbg(4, " dimm->nr_pages = 0x%x\n", dimm->nr_pages); 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, ...@@ -712,6 +715,7 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
edac_mc_dump_mci(mci); edac_mc_dump_mci(mci);
if (edac_debug_level >= 4) { if (edac_debug_level >= 4) {
struct dimm_info *dimm;
int i; int i;
for (i = 0; i < mci->nr_csrows; 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, ...@@ -728,9 +732,9 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
if (csrow->channels[j]->dimm->nr_pages) if (csrow->channels[j]->dimm->nr_pages)
edac_mc_dump_channel(csrow->channels[j]); edac_mc_dump_channel(csrow->channels[j]);
} }
for (i = 0; i < mci->tot_dimms; i++)
if (mci->dimms[i]->nr_pages) mci_for_each_dimm(mci, dimm)
edac_mc_dump_dimm(mci->dimms[i], i); edac_mc_dump_dimm(dimm);
} }
#endif #endif
mutex_lock(&mem_ctls_mutex); mutex_lock(&mem_ctls_mutex);
...@@ -1088,6 +1092,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, ...@@ -1088,6 +1092,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
const char *msg, const char *msg,
const char *other_detail) const char *other_detail)
{ {
struct dimm_info *dimm;
char *p; char *p;
int row = -1, chan = -1; int row = -1, chan = -1;
int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer }; 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, ...@@ -1148,9 +1153,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
p = e->label; p = e->label;
*p = '\0'; *p = '\0';
for (i = 0; i < mci->tot_dimms; i++) { mci_for_each_dimm(mci, dimm) {
struct dimm_info *dimm = mci->dimms[i];
if (top_layer >= 0 && top_layer != dimm->location[0]) if (top_layer >= 0 && top_layer != dimm->location[0])
continue; continue;
if (mid_layer >= 0 && mid_layer != dimm->location[1]) if (mid_layer >= 0 && mid_layer != dimm->location[1])
......
...@@ -621,8 +621,7 @@ static const struct device_type dimm_attr_type = { ...@@ -621,8 +621,7 @@ static const struct device_type dimm_attr_type = {
/* Create a DIMM object under specifed memory controller device */ /* Create a DIMM object under specifed memory controller device */
static int edac_create_dimm_object(struct mem_ctl_info *mci, static int edac_create_dimm_object(struct mem_ctl_info *mci,
struct dimm_info *dimm, struct dimm_info *dimm)
int index)
{ {
int err; int err;
dimm->mci = mci; dimm->mci = mci;
...@@ -632,9 +631,9 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, ...@@ -632,9 +631,9 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
dimm->dev.parent = &mci->dev; dimm->dev.parent = &mci->dev;
if (mci->csbased) if (mci->csbased)
dev_set_name(&dimm->dev, "rank%d", index); dev_set_name(&dimm->dev, "rank%d", dimm->idx);
else else
dev_set_name(&dimm->dev, "dimm%d", index); dev_set_name(&dimm->dev, "dimm%d", dimm->idx);
dev_set_drvdata(&dimm->dev, dimm); dev_set_drvdata(&dimm->dev, dimm);
pm_runtime_forbid(&mci->dev); pm_runtime_forbid(&mci->dev);
...@@ -916,7 +915,8 @@ static const struct device_type mci_attr_type = { ...@@ -916,7 +915,8 @@ static const struct device_type mci_attr_type = {
int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
const struct attribute_group **groups) const struct attribute_group **groups)
{ {
int i, err; struct dimm_info *dimm;
int err;
/* get the /sys/devices/system/edac subsys reference */ /* get the /sys/devices/system/edac subsys reference */
mci->dev.type = &mci_attr_type; mci->dev.type = &mci_attr_type;
...@@ -940,13 +940,12 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, ...@@ -940,13 +940,12 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
/* /*
* Create the dimm/rank devices * Create the dimm/rank devices
*/ */
for (i = 0; i < mci->tot_dimms; i++) { mci_for_each_dimm(mci, dimm) {
struct dimm_info *dimm = mci->dimms[i];
/* Only expose populated DIMMs */ /* Only expose populated DIMMs */
if (!dimm->nr_pages) if (!dimm->nr_pages)
continue; continue;
err = edac_create_dimm_object(mci, dimm, i); err = edac_create_dimm_object(mci, dimm);
if (err) if (err)
goto fail_unregister_dimm; goto fail_unregister_dimm;
} }
...@@ -961,12 +960,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, ...@@ -961,12 +960,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
return 0; return 0;
fail_unregister_dimm: fail_unregister_dimm:
for (i--; i >= 0; i--) { mci_for_each_dimm(mci, dimm) {
struct dimm_info *dimm = mci->dimms[i]; if (device_is_registered(&dimm->dev))
if (!dimm->nr_pages) device_unregister(&dimm->dev);
continue;
device_unregister(&dimm->dev);
} }
device_unregister(&mci->dev); device_unregister(&mci->dev);
...@@ -978,7 +974,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, ...@@ -978,7 +974,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
*/ */
void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
{ {
int i; struct dimm_info *dimm;
edac_dbg(0, "\n"); edac_dbg(0, "\n");
...@@ -989,8 +985,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -989,8 +985,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
edac_delete_csrow_objects(mci); edac_delete_csrow_objects(mci);
#endif #endif
for (i = 0; i < mci->tot_dimms; i++) { mci_for_each_dimm(mci, dimm) {
struct dimm_info *dimm = mci->dimms[i];
if (dimm->nr_pages == 0) if (dimm->nr_pages == 0)
continue; continue;
edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev)); edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev));
......
...@@ -90,12 +90,13 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg) ...@@ -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) 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++) { mci_for_each_dimm(mci, dimm) {
if (mci->dimms[i]->smbios_handle == handle) if (dimm->smbios_handle == handle)
return i; return dimm->idx;
} }
return -1; return -1;
} }
......
...@@ -846,20 +846,17 @@ static void i5100_init_interleaving(struct pci_dev *pdev, ...@@ -846,20 +846,17 @@ static void i5100_init_interleaving(struct pci_dev *pdev,
static void i5100_init_csrows(struct mem_ctl_info *mci) static void i5100_init_csrows(struct mem_ctl_info *mci)
{ {
int i;
struct i5100_priv *priv = mci->pvt_info; struct i5100_priv *priv = mci->pvt_info;
struct dimm_info *dimm;
for (i = 0; i < mci->tot_dimms; i++) { mci_for_each_dimm(mci, dimm) {
struct dimm_info *dimm; const unsigned long npages = i5100_npages(mci, dimm->idx);
const unsigned long npages = i5100_npages(mci, i); const unsigned int chan = i5100_csrow_to_chan(mci, dimm->idx);
const unsigned int chan = i5100_csrow_to_chan(mci, i); const unsigned int rank = i5100_csrow_to_rank(mci, dimm->idx);
const unsigned int rank = i5100_csrow_to_rank(mci, i);
if (!npages) if (!npages)
continue; continue;
dimm = edac_get_dimm(mci, chan, rank, 0);
dimm->nr_pages = npages; dimm->nr_pages = npages;
dimm->grain = 32; dimm->grain = 32;
dimm->dtype = (priv->mtr[chan][rank].width == 4) ? dimm->dtype = (priv->mtr[chan][rank].width == 4) ?
......
...@@ -599,6 +599,13 @@ struct mem_ctl_info { ...@@ -599,6 +599,13 @@ struct mem_ctl_info {
u16 fake_inject_count; 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 * edac_get_dimm_by_index - Get DIMM info at @index from a memory
* controller * controller
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment