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

EDAC/mc: Split edac_mc_alloc() into smaller functions

edac_mc_alloc() is huge. Factor out code by moving it to the two new
functions edac_mc_alloc_csrows() and edac_mc_alloc_dimms(). Do not
move code yet for better review.

 [ bp: sort local args in reversed fir tree order. ]
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>
Acked-by: default avatarAristeu Rozanski <aris@redhat.com>
Link: https://lkml.kernel.org/r/20200123090210.26933-2-rrichter@marvell.com
parent bea1bfd5
...@@ -311,6 +311,9 @@ static void mci_release(struct device *dev) ...@@ -311,6 +311,9 @@ static void mci_release(struct device *dev)
kfree(mci); kfree(mci);
} }
static int edac_mc_alloc_csrows(struct mem_ctl_info *mci);
static int edac_mc_alloc_dimms(struct mem_ctl_info *mci);
struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
unsigned int n_layers, unsigned int n_layers,
struct edac_mc_layer *layers, struct edac_mc_layer *layers,
...@@ -318,15 +321,11 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, ...@@ -318,15 +321,11 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct edac_mc_layer *layer; struct edac_mc_layer *layer;
struct csrow_info *csr;
struct rank_info *chan;
struct dimm_info *dimm;
u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS]; u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
unsigned int pos[EDAC_MAX_LAYERS];
unsigned int idx, size, tot_dimms = 1, count = 1; unsigned int idx, size, tot_dimms = 1, count = 1;
unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0; unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
void *pvt, *p, *ptr = NULL; void *pvt, *ptr = NULL;
int i, j, row, chn, n, len; int i;
bool per_rank = false; bool per_rank = false;
if (WARN_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0)) if (WARN_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0))
...@@ -401,16 +400,43 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, ...@@ -401,16 +400,43 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
mci->num_cschannel = tot_channels; mci->num_cschannel = tot_channels;
mci->csbased = per_rank; mci->csbased = per_rank;
if (edac_mc_alloc_csrows(mci))
goto error;
if (edac_mc_alloc_dimms(mci))
goto error;
mci->op_state = OP_ALLOC;
return mci;
error:
_edac_mc_free(mci);
return NULL;
}
EXPORT_SYMBOL_GPL(edac_mc_alloc);
static int edac_mc_alloc_csrows(struct mem_ctl_info *mci)
{
unsigned int tot_channels = mci->num_cschannel;
unsigned int tot_csrows = mci->nr_csrows;
unsigned int row, chn;
/* /*
* Alocate and fill the csrow/channels structs * Alocate and fill the csrow/channels structs
*/ */
mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL); mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL);
if (!mci->csrows) if (!mci->csrows)
goto error; return -ENOMEM;
for (row = 0; row < tot_csrows; row++) { for (row = 0; row < tot_csrows; row++) {
struct csrow_info *csr;
csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL); csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL);
if (!csr) if (!csr)
goto error; return -ENOMEM;
mci->csrows[row] = csr; mci->csrows[row] = csr;
csr->csrow_idx = row; csr->csrow_idx = row;
csr->mci = mci; csr->mci = mci;
...@@ -418,34 +444,51 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, ...@@ -418,34 +444,51 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
csr->channels = kcalloc(tot_channels, sizeof(*csr->channels), csr->channels = kcalloc(tot_channels, sizeof(*csr->channels),
GFP_KERNEL); GFP_KERNEL);
if (!csr->channels) if (!csr->channels)
goto error; return -ENOMEM;
for (chn = 0; chn < tot_channels; chn++) { for (chn = 0; chn < tot_channels; chn++) {
struct rank_info *chan;
chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL); chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL);
if (!chan) if (!chan)
goto error; return -ENOMEM;
csr->channels[chn] = chan; csr->channels[chn] = chan;
chan->chan_idx = chn; chan->chan_idx = chn;
chan->csrow = csr; chan->csrow = csr;
} }
} }
return 0;
}
static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
{
unsigned int pos[EDAC_MAX_LAYERS];
unsigned int row, chn, idx;
int layer;
void *p;
/* /*
* Allocate and fill the dimm structs * Allocate and fill the dimm structs
*/ */
mci->dimms = kcalloc(tot_dimms, sizeof(*mci->dimms), GFP_KERNEL); mci->dimms = kcalloc(mci->tot_dimms, sizeof(*mci->dimms), GFP_KERNEL);
if (!mci->dimms) if (!mci->dimms)
goto error; return -ENOMEM;
memset(&pos, 0, sizeof(pos)); memset(&pos, 0, sizeof(pos));
row = 0; row = 0;
chn = 0; chn = 0;
for (idx = 0; idx < tot_dimms; idx++) { for (idx = 0; idx < mci->tot_dimms; idx++) {
struct dimm_info *dimm;
struct rank_info *chan;
int n, len;
chan = mci->csrows[row]->channels[chn]; chan = mci->csrows[row]->channels[chn];
dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL); dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL);
if (!dimm) if (!dimm)
goto error; return -ENOMEM;
mci->dimms[idx] = dimm; mci->dimms[idx] = dimm;
dimm->mci = mci; dimm->mci = mci;
dimm->idx = idx; dimm->idx = idx;
...@@ -455,16 +498,16 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, ...@@ -455,16 +498,16 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
*/ */
len = sizeof(dimm->label); len = sizeof(dimm->label);
p = dimm->label; p = dimm->label;
n = snprintf(p, len, "mc#%u", mc_num); n = snprintf(p, len, "mc#%u", mci->mc_idx);
p += n; p += n;
len -= n; len -= n;
for (j = 0; j < n_layers; j++) { for (layer = 0; layer < mci->n_layers; layer++) {
n = snprintf(p, len, "%s#%u", n = snprintf(p, len, "%s#%u",
edac_layer_name[layers[j].type], edac_layer_name[mci->layers[layer].type],
pos[j]); pos[layer]);
p += n; p += n;
len -= n; len -= n;
dimm->location[j] = pos[j]; dimm->location[layer] = pos[layer];
if (len <= 0) if (len <= 0)
break; break;
...@@ -476,39 +519,31 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, ...@@ -476,39 +519,31 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
dimm->cschannel = chn; dimm->cschannel = chn;
/* Increment csrow location */ /* Increment csrow location */
if (layers[0].is_virt_csrow) { if (mci->layers[0].is_virt_csrow) {
chn++; chn++;
if (chn == tot_channels) { if (chn == mci->num_cschannel) {
chn = 0; chn = 0;
row++; row++;
} }
} else { } else {
row++; row++;
if (row == tot_csrows) { if (row == mci->nr_csrows) {
row = 0; row = 0;
chn++; chn++;
} }
} }
/* Increment dimm location */ /* Increment dimm location */
for (j = n_layers - 1; j >= 0; j--) { for (layer = mci->n_layers - 1; layer >= 0; layer--) {
pos[j]++; pos[layer]++;
if (pos[j] < layers[j].size) if (pos[layer] < mci->layers[layer].size)
break; break;
pos[j] = 0; pos[layer] = 0;
} }
} }
mci->op_state = OP_ALLOC; return 0;
return mci;
error:
_edac_mc_free(mci);
return NULL;
} }
EXPORT_SYMBOL_GPL(edac_mc_alloc);
void edac_mc_free(struct mem_ctl_info *mci) void edac_mc_free(struct mem_ctl_info *mci)
{ {
......
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