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: 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
This commit is contained in:
parent
977b1ce7c1
commit
c498afaf7d
@ -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 @@ 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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user