aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r--drivers/edac/edac_mc.c107
1 files changed, 70 insertions, 37 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 4a6fdc03740e..db2ba31ba2b1 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -210,15 +210,15 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
210{ 210{
211 struct mem_ctl_info *mci; 211 struct mem_ctl_info *mci;
212 struct edac_mc_layer *layer; 212 struct edac_mc_layer *layer;
213 struct csrow_info *csi, *csr; 213 struct csrow_info *csr;
214 struct rank_info *chi, *chp, *chan; 214 struct rank_info *chan;
215 struct dimm_info *dimm; 215 struct dimm_info *dimm;
216 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS]; 216 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
217 unsigned pos[EDAC_MAX_LAYERS]; 217 unsigned pos[EDAC_MAX_LAYERS];
218 unsigned size, tot_dimms = 1, count = 1; 218 unsigned size, tot_dimms = 1, count = 1;
219 unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0; 219 unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
220 void *pvt, *p, *ptr = NULL; 220 void *pvt, *p, *ptr = NULL;
221 int i, j, row, chn, n, len; 221 int i, j, row, chn, n, len, off;
222 bool per_rank = false; 222 bool per_rank = false;
223 223
224 BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0); 224 BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
@@ -244,9 +244,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
244 */ 244 */
245 mci = edac_align_ptr(&ptr, sizeof(*mci), 1); 245 mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
246 layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers); 246 layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
247 csi = edac_align_ptr(&ptr, sizeof(*csi), tot_csrows);
248 chi = edac_align_ptr(&ptr, sizeof(*chi), tot_csrows * tot_channels);
249 dimm = edac_align_ptr(&ptr, sizeof(*dimm), tot_dimms);
250 for (i = 0; i < n_layers; i++) { 247 for (i = 0; i < n_layers; i++) {
251 count *= layers[i].size; 248 count *= layers[i].size;
252 debugf4("%s: errcount layer %d size %d\n", __func__, i, count); 249 debugf4("%s: errcount layer %d size %d\n", __func__, i, count);
@@ -264,6 +261,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
264 tot_dimms, 261 tot_dimms,
265 per_rank ? "ranks" : "dimms", 262 per_rank ? "ranks" : "dimms",
266 tot_csrows * tot_channels); 263 tot_csrows * tot_channels);
264
267 mci = kzalloc(size, GFP_KERNEL); 265 mci = kzalloc(size, GFP_KERNEL);
268 if (mci == NULL) 266 if (mci == NULL)
269 return NULL; 267 return NULL;
@@ -272,9 +270,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
272 * rather than an imaginary chunk of memory located at address 0. 270 * rather than an imaginary chunk of memory located at address 0.
273 */ 271 */
274 layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer)); 272 layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
275 csi = (struct csrow_info *)(((char *)mci) + ((unsigned long)csi));
276 chi = (struct rank_info *)(((char *)mci) + ((unsigned long)chi));
277 dimm = (struct dimm_info *)(((char *)mci) + ((unsigned long)dimm));
278 for (i = 0; i < n_layers; i++) { 273 for (i = 0; i < n_layers; i++) {
279 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i])); 274 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
280 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i])); 275 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
@@ -283,8 +278,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
283 278
284 /* setup index and various internal pointers */ 279 /* setup index and various internal pointers */
285 mci->mc_idx = mc_num; 280 mci->mc_idx = mc_num;
286 mci->csrows = csi;
287 mci->dimms = dimm;
288 mci->tot_dimms = tot_dimms; 281 mci->tot_dimms = tot_dimms;
289 mci->pvt_info = pvt; 282 mci->pvt_info = pvt;
290 mci->n_layers = n_layers; 283 mci->n_layers = n_layers;
@@ -295,39 +288,60 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
295 mci->mem_is_per_rank = per_rank; 288 mci->mem_is_per_rank = per_rank;
296 289
297 /* 290 /*
298 * Fill the csrow struct 291 * Alocate and fill the csrow/channels structs
299 */ 292 */
293 mci->csrows = kcalloc(sizeof(*mci->csrows), tot_csrows, GFP_KERNEL);
294 if (!mci->csrows)
295 goto error;
300 for (row = 0; row < tot_csrows; row++) { 296 for (row = 0; row < tot_csrows; row++) {
301 csr = &csi[row]; 297 csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL);
298 if (!csr)
299 goto error;
300 mci->csrows[row] = csr;
302 csr->csrow_idx = row; 301 csr->csrow_idx = row;
303 csr->mci = mci; 302 csr->mci = mci;
304 csr->nr_channels = tot_channels; 303 csr->nr_channels = tot_channels;
305 chp = &chi[row * tot_channels]; 304 csr->channels = kcalloc(sizeof(*csr->channels), tot_channels,
306 csr->channels = chp; 305 GFP_KERNEL);
306 if (!csr->channels)
307 goto error;
307 308
308 for (chn = 0; chn < tot_channels; chn++) { 309 for (chn = 0; chn < tot_channels; chn++) {
309 chan = &chp[chn]; 310 chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL);
311 if (!chan)
312 goto error;
313 csr->channels[chn] = chan;
310 chan->chan_idx = chn; 314 chan->chan_idx = chn;
311 chan->csrow = csr; 315 chan->csrow = csr;
312 } 316 }
313 } 317 }
314 318
315 /* 319 /*
316 * Fill the dimm struct 320 * Allocate and fill the dimm structs
317 */ 321 */
322 mci->dimms = kcalloc(sizeof(*mci->dimms), tot_dimms, GFP_KERNEL);
323 if (!mci->dimms)
324 goto error;
325
318 memset(&pos, 0, sizeof(pos)); 326 memset(&pos, 0, sizeof(pos));
319 row = 0; 327 row = 0;
320 chn = 0; 328 chn = 0;
321 debugf4("%s: initializing %d %s\n", __func__, tot_dimms, 329 debugf4("%s: initializing %d %s\n", __func__, tot_dimms,
322 per_rank ? "ranks" : "dimms"); 330 per_rank ? "ranks" : "dimms");
323 for (i = 0; i < tot_dimms; i++) { 331 for (i = 0; i < tot_dimms; i++) {
324 chan = &csi[row].channels[chn]; 332 chan = mci->csrows[row]->channels[chn];
325 dimm = EDAC_DIMM_PTR(layer, mci->dimms, n_layers, 333 off = EDAC_DIMM_OFF(layer, n_layers, pos[0], pos[1], pos[2]);
326 pos[0], pos[1], pos[2]); 334 if (off < 0 || off >= tot_dimms) {
335 edac_mc_printk(mci, KERN_ERR, "EDAC core bug: EDAC_DIMM_OFF is trying to do an illegal data access\n");
336 goto error;
337 }
338
339 dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL);
340 mci->dimms[off] = dimm;
327 dimm->mci = mci; 341 dimm->mci = mci;
328 342
329 debugf2("%s: %d: %s%zd (%d:%d:%d): row %d, chan %d\n", __func__, 343 debugf2("%s: %d: %s%i (%d:%d:%d): row %d, chan %d\n", __func__,
330 i, per_rank ? "rank" : "dimm", (dimm - mci->dimms), 344 i, per_rank ? "rank" : "dimm", off,
331 pos[0], pos[1], pos[2], row, chn); 345 pos[0], pos[1], pos[2], row, chn);
332 346
333 /* 347 /*
@@ -381,6 +395,28 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
381 */ 395 */
382 396
383 return mci; 397 return mci;
398
399error:
400 if (mci->dimms) {
401 for (i = 0; i < tot_dimms; i++)
402 kfree(mci->dimms[i]);
403 kfree(mci->dimms);
404 }
405 if (mci->csrows) {
406 for (chn = 0; chn < tot_channels; chn++) {
407 csr = mci->csrows[chn];
408 if (csr) {
409 for (chn = 0; chn < tot_channels; chn++)
410 kfree(csr->channels[chn]);
411 kfree(csr);
412 }
413 kfree(mci->csrows[i]);
414 }
415 kfree(mci->csrows);
416 }
417 kfree(mci);
418
419 return NULL;
384} 420}
385EXPORT_SYMBOL_GPL(edac_mc_alloc); 421EXPORT_SYMBOL_GPL(edac_mc_alloc);
386 422
@@ -393,10 +429,8 @@ void edac_mc_free(struct mem_ctl_info *mci)
393{ 429{
394 debugf1("%s()\n", __func__); 430 debugf1("%s()\n", __func__);
395 431
432 /* the mci instance is freed here, when the sysfs object is dropped */
396 edac_unregister_sysfs(mci); 433 edac_unregister_sysfs(mci);
397
398 /* free the mci instance memory here */
399 kfree(mci);
400} 434}
401EXPORT_SYMBOL_GPL(edac_mc_free); 435EXPORT_SYMBOL_GPL(edac_mc_free);
402 436
@@ -668,13 +702,12 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
668 for (i = 0; i < mci->nr_csrows; i++) { 702 for (i = 0; i < mci->nr_csrows; i++) {
669 int j; 703 int j;
670 704
671 edac_mc_dump_csrow(&mci->csrows[i]); 705 edac_mc_dump_csrow(mci->csrows[i]);
672 for (j = 0; j < mci->csrows[i].nr_channels; j++) 706 for (j = 0; j < mci->csrows[i]->nr_channels; j++)
673 edac_mc_dump_channel(&mci->csrows[i]. 707 edac_mc_dump_channel(mci->csrows[i]->channels[j]);
674 channels[j]);
675 } 708 }
676 for (i = 0; i < mci->tot_dimms; i++) 709 for (i = 0; i < mci->tot_dimms; i++)
677 edac_mc_dump_dimm(&mci->dimms[i]); 710 edac_mc_dump_dimm(mci->dimms[i]);
678 } 711 }
679#endif 712#endif
680 mutex_lock(&mem_ctls_mutex); 713 mutex_lock(&mem_ctls_mutex);
@@ -793,17 +826,17 @@ static void edac_mc_scrub_block(unsigned long page, unsigned long offset,
793/* FIXME - should return -1 */ 826/* FIXME - should return -1 */
794int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) 827int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
795{ 828{
796 struct csrow_info *csrows = mci->csrows; 829 struct csrow_info **csrows = mci->csrows;
797 int row, i, j, n; 830 int row, i, j, n;
798 831
799 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page); 832 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page);
800 row = -1; 833 row = -1;
801 834
802 for (i = 0; i < mci->nr_csrows; i++) { 835 for (i = 0; i < mci->nr_csrows; i++) {
803 struct csrow_info *csrow = &csrows[i]; 836 struct csrow_info *csrow = csrows[i];
804 n = 0; 837 n = 0;
805 for (j = 0; j < csrow->nr_channels; j++) { 838 for (j = 0; j < csrow->nr_channels; j++) {
806 struct dimm_info *dimm = csrow->channels[j].dimm; 839 struct dimm_info *dimm = csrow->channels[j]->dimm;
807 n += dimm->nr_pages; 840 n += dimm->nr_pages;
808 } 841 }
809 if (n == 0) 842 if (n == 0)
@@ -1062,7 +1095,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
1062 p = label; 1095 p = label;
1063 *p = '\0'; 1096 *p = '\0';
1064 for (i = 0; i < mci->tot_dimms; i++) { 1097 for (i = 0; i < mci->tot_dimms; i++) {
1065 struct dimm_info *dimm = &mci->dimms[i]; 1098 struct dimm_info *dimm = mci->dimms[i];
1066 1099
1067 if (top_layer >= 0 && top_layer != dimm->location[0]) 1100 if (top_layer >= 0 && top_layer != dimm->location[0])
1068 continue; 1101 continue;
@@ -1120,13 +1153,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
1120 strcpy(label, "unknown memory"); 1153 strcpy(label, "unknown memory");
1121 if (type == HW_EVENT_ERR_CORRECTED) { 1154 if (type == HW_EVENT_ERR_CORRECTED) {
1122 if (row >= 0) { 1155 if (row >= 0) {
1123 mci->csrows[row].ce_count++; 1156 mci->csrows[row]->ce_count++;
1124 if (chan >= 0) 1157 if (chan >= 0)
1125 mci->csrows[row].channels[chan].ce_count++; 1158 mci->csrows[row]->channels[chan]->ce_count++;
1126 } 1159 }
1127 } else 1160 } else
1128 if (row >= 0) 1161 if (row >= 0)
1129 mci->csrows[row].ue_count++; 1162 mci->csrows[row]->ue_count++;
1130 } 1163 }
1131 1164
1132 /* Fill the RAM location data */ 1165 /* Fill the RAM location data */