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)
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])
......
......@@ -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 @@ int edac_create_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");
......@@ -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));
......
......@@ -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;
}
......
......@@ -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) ?
......
......@@ -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
......
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