hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/include/linux/edac.h
....@@ -31,14 +31,6 @@
3131 extern int edac_op_state;
3232
3333 struct bus_type *edac_get_sysfs_subsys(void);
34
-int edac_get_report_status(void);
35
-void edac_set_report_status(int new);
36
-
37
-enum {
38
- EDAC_REPORTING_ENABLED,
39
- EDAC_REPORTING_DISABLED,
40
- EDAC_REPORTING_FORCE
41
-};
4234
4335 static inline void opstate_init(void)
4436 {
....@@ -362,87 +354,16 @@
362354 */
363355 #define EDAC_MAX_LAYERS 3
364356
365
-/**
366
- * EDAC_DIMM_OFF - Macro responsible to get a pointer offset inside a pointer
367
- * array for the element given by [layer0,layer1,layer2]
368
- * position
369
- *
370
- * @layers: a struct edac_mc_layer array, describing how many elements
371
- * were allocated for each layer
372
- * @nlayers: Number of layers at the @layers array
373
- * @layer0: layer0 position
374
- * @layer1: layer1 position. Unused if n_layers < 2
375
- * @layer2: layer2 position. Unused if n_layers < 3
376
- *
377
- * For 1 layer, this macro returns "var[layer0] - var";
378
- *
379
- * For 2 layers, this macro is similar to allocate a bi-dimensional array
380
- * and to return "var[layer0][layer1] - var";
381
- *
382
- * For 3 layers, this macro is similar to allocate a tri-dimensional array
383
- * and to return "var[layer0][layer1][layer2] - var".
384
- *
385
- * A loop could be used here to make it more generic, but, as we only have
386
- * 3 layers, this is a little faster.
387
- *
388
- * By design, layers can never be 0 or more than 3. If that ever happens,
389
- * a NULL is returned, causing an OOPS during the memory allocation routine,
390
- * with would point to the developer that he's doing something wrong.
391
- */
392
-#define EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2) ({ \
393
- int __i; \
394
- if ((nlayers) == 1) \
395
- __i = layer0; \
396
- else if ((nlayers) == 2) \
397
- __i = (layer1) + ((layers[1]).size * (layer0)); \
398
- else if ((nlayers) == 3) \
399
- __i = (layer2) + ((layers[2]).size * ((layer1) + \
400
- ((layers[1]).size * (layer0)))); \
401
- else \
402
- __i = -EINVAL; \
403
- __i; \
404
-})
405
-
406
-/**
407
- * EDAC_DIMM_PTR - Macro responsible to get a pointer inside a pointer array
408
- * for the element given by [layer0,layer1,layer2] position
409
- *
410
- * @layers: a struct edac_mc_layer array, describing how many elements
411
- * were allocated for each layer
412
- * @var: name of the var where we want to get the pointer
413
- * (like mci->dimms)
414
- * @nlayers: Number of layers at the @layers array
415
- * @layer0: layer0 position
416
- * @layer1: layer1 position. Unused if n_layers < 2
417
- * @layer2: layer2 position. Unused if n_layers < 3
418
- *
419
- * For 1 layer, this macro returns "var[layer0]";
420
- *
421
- * For 2 layers, this macro is similar to allocate a bi-dimensional array
422
- * and to return "var[layer0][layer1]";
423
- *
424
- * For 3 layers, this macro is similar to allocate a tri-dimensional array
425
- * and to return "var[layer0][layer1][layer2]";
426
- */
427
-#define EDAC_DIMM_PTR(layers, var, nlayers, layer0, layer1, layer2) ({ \
428
- typeof(*var) __p; \
429
- int ___i = EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2); \
430
- if (___i < 0) \
431
- __p = NULL; \
432
- else \
433
- __p = (var)[___i]; \
434
- __p; \
435
-})
436
-
437357 struct dimm_info {
438358 struct device dev;
439359
440360 char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */
441361
442362 /* Memory location data */
443
- unsigned location[EDAC_MAX_LAYERS];
363
+ unsigned int location[EDAC_MAX_LAYERS];
444364
445365 struct mem_ctl_info *mci; /* the parent */
366
+ unsigned int idx; /* index within the parent dimm array */
446367
447368 u32 grain; /* granularity of reported error in bytes */
448369 enum dev_type dtype; /* memory device type */
....@@ -451,7 +372,12 @@
451372
452373 u32 nr_pages; /* number of pages on this dimm */
453374
454
- unsigned csrow, cschannel; /* Points to the old API data */
375
+ unsigned int csrow, cschannel; /* Points to the old API data */
376
+
377
+ u16 smbios_handle; /* Handle for SMBIOS type 17 */
378
+
379
+ u32 ce_count;
380
+ u32 ue_count;
455381 };
456382
457383 /**
....@@ -511,6 +437,7 @@
511437 * struct edac_raw_error_desc - Raw error report structure
512438 * @grain: minimum granularity for an error report, in bytes
513439 * @error_count: number of errors of the same type
440
+ * @type: severity of the error (CE/UE/Fatal)
514441 * @top_layer: top layer of the error (layer[0])
515442 * @mid_layer: middle layer of the error (layer[1])
516443 * @low_layer: low layer of the error (layer[2])
....@@ -522,20 +449,14 @@
522449 * @location: location of the error
523450 * @label: label of the affected DIMM(s)
524451 * @other_detail: other driver-specific detail about the error
525
- * @enable_per_layer_report: if false, the error affects all layers
526
- * (typically, a memory controller error)
527452 */
528453 struct edac_raw_error_desc {
529
- /*
530
- * NOTE: everything before grain won't be cleaned by
531
- * edac_raw_error_desc_clean()
532
- */
533454 char location[LOCATION_SIZE];
534455 char label[(EDAC_MC_LABEL_LEN + 1 + sizeof(OTHER_LABEL)) * EDAC_MAX_LABELS];
535456 long grain;
536457
537
- /* the vars below and grain will be cleaned on every new error report */
538458 u16 error_count;
459
+ enum hw_event_mc_err_type type;
539460 int top_layer;
540461 int mid_layer;
541462 int low_layer;
....@@ -544,7 +465,6 @@
544465 unsigned long syndrome;
545466 const char *msg;
546467 const char *other_detail;
547
- bool enable_per_layer_report;
548468 };
549469
550470 /* MEMORY controller information structure
....@@ -595,7 +515,7 @@
595515 unsigned long page);
596516 int mc_idx;
597517 struct csrow_info **csrows;
598
- unsigned nr_csrows, num_cschannel;
518
+ unsigned int nr_csrows, num_cschannel;
599519
600520 /*
601521 * Memory Controller hierarchy
....@@ -606,14 +526,14 @@
606526 * of the recent drivers enumerate memories per DIMM, instead.
607527 * When the memory controller is per rank, csbased is true.
608528 */
609
- unsigned n_layers;
529
+ unsigned int n_layers;
610530 struct edac_mc_layer *layers;
611531 bool csbased;
612532
613533 /*
614534 * DIMM info. Will eventually remove the entire csrows_info some day
615535 */
616
- unsigned tot_dimms;
536
+ unsigned int tot_dimms;
617537 struct dimm_info **dimms;
618538
619539 /*
....@@ -634,7 +554,6 @@
634554 */
635555 u32 ce_noinfo_count, ue_noinfo_count;
636556 u32 ue_mc, ce_mc;
637
- u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
638557
639558 struct completion complete;
640559
....@@ -668,9 +587,54 @@
668587 u16 fake_inject_count;
669588 };
670589
671
-/*
672
- * Maximum number of memory controllers in the coherent fabric.
673
- */
674
-#define EDAC_MAX_MCS 2 * MAX_NUMNODES
590
+#define mci_for_each_dimm(mci, dimm) \
591
+ for ((dimm) = (mci)->dimms[0]; \
592
+ (dimm); \
593
+ (dimm) = (dimm)->idx + 1 < (mci)->tot_dimms \
594
+ ? (mci)->dimms[(dimm)->idx + 1] \
595
+ : NULL)
675596
676
-#endif
597
+/**
598
+ * edac_get_dimm - Get DIMM info from a memory controller given by
599
+ * [layer0,layer1,layer2] position
600
+ *
601
+ * @mci: MC descriptor struct mem_ctl_info
602
+ * @layer0: layer0 position
603
+ * @layer1: layer1 position. Unused if n_layers < 2
604
+ * @layer2: layer2 position. Unused if n_layers < 3
605
+ *
606
+ * For 1 layer, this function returns "dimms[layer0]";
607
+ *
608
+ * For 2 layers, this function is similar to allocating a two-dimensional
609
+ * array and returning "dimms[layer0][layer1]";
610
+ *
611
+ * For 3 layers, this function is similar to allocating a tri-dimensional
612
+ * array and returning "dimms[layer0][layer1][layer2]";
613
+ */
614
+static inline struct dimm_info *edac_get_dimm(struct mem_ctl_info *mci,
615
+ int layer0, int layer1, int layer2)
616
+{
617
+ int index;
618
+
619
+ if (layer0 < 0
620
+ || (mci->n_layers > 1 && layer1 < 0)
621
+ || (mci->n_layers > 2 && layer2 < 0))
622
+ return NULL;
623
+
624
+ index = layer0;
625
+
626
+ if (mci->n_layers > 1)
627
+ index = index * mci->layers[1].size + layer1;
628
+
629
+ if (mci->n_layers > 2)
630
+ index = index * mci->layers[2].size + layer2;
631
+
632
+ if (index < 0 || index >= mci->tot_dimms)
633
+ return NULL;
634
+
635
+ if (WARN_ON_ONCE(mci->dimms[index]->idx != index))
636
+ return NULL;
637
+
638
+ return mci->dimms[index];
639
+}
640
+#endif /* _LINUX_EDAC_H_ */