mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface
@ 2025-11-06  1:54 Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 1/3] EDAC/amd64: Generate ctl_name string at runtime Avadhut Naik
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Avadhut Naik @ 2025-11-06  1:54 UTC (permalink / raw)
  To: linux-edac, linux-doc
  Cc: bp, gregkh, corbet, chenhuacai, mchehab+huawei, yazen.ghannam,
	linux-kernel, avadhut.naik

This patchset undertakes some cleanups in the amd64_edac module and
removes the legacy EDAC sysfs interface since it has been obsolete for
more than a decade.

The first patch removes explicit assignment of the ctl_name string and
instead generates it at runtime using scnprintf.

The second patch removes the NUM_CONTROLLERS macro and instead uses the
max_mcs variable to determine the size of chipselect array.

The third patch removes the old EDAC sysfs interface.

NOTE:
These cleanups were earlier submitted as part of the set adding EDAC
support for AMD's newer Family 1Ah-based SOCs.[1] However, since the
support patches were critical to enabling EDAC on newer AMD SOCs and
since these cleanups were still under review, the set was split up.

[1]: https://lore.kernel.org/all/20250909185748.1621098-1-avadhut.naik@amd.com/

Changes in v2:
 - Drop the patch that set zn_regs_v2 flag for all SOCs based on Family
1Ah and later.
 - Change MAX_CTL_NAMELEN macro from 20 to 19.
 - Modify commit message of the second patch per feedback received.
 - Skip deprecation and just remove the old EDAC sysfs interface.

Links:
v1: https://lore.kernel.org/all/20251013173632.1449366-1-avadhut.naik@amd.com/

Avadhut Naik (3):
  EDAC/amd64: Generate ctl_name string at runtime
  EDAC/amd64: Remove NUM_CONTROLLERS macro
  edac: Remove the legacy EDAC sysfs interface

 Documentation/admin-guide/RAS/main.rst     | 142 +-------
 arch/loongarch/configs/loongson3_defconfig |   1 -
 drivers/edac/Kconfig                       |   8 -
 drivers/edac/amd64_edac.c                  |  61 +---
 drivers/edac/amd64_edac.h                  |   7 +-
 drivers/edac/edac_mc_sysfs.c               | 404 ---------------------
 6 files changed, 22 insertions(+), 601 deletions(-)


base-commit: d05ab93a9183520b2a6965765e14a3e6bdf01f90
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] EDAC/amd64: Generate ctl_name string at runtime
  2025-11-06  1:54 [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface Avadhut Naik
@ 2025-11-06  1:54 ` Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 2/3] EDAC/amd64: Remove NUM_CONTROLLERS macro Avadhut Naik
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Avadhut Naik @ 2025-11-06  1:54 UTC (permalink / raw)
  To: linux-edac, linux-doc
  Cc: bp, gregkh, corbet, chenhuacai, mchehab+huawei, yazen.ghannam,
	linux-kernel, avadhut.naik

Currently, the ctl_name string is statically assigned based on the family
and model of the SOC when the amd64_edac module is loaded.

The same, however, is not exactly needed as the string can be generated
and assigned at runtime through scnprintf().

Remove all static assignments and generate the string at runtime. Also,
cleanup the switch cases which became defunct and consolidate identical
cases.

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
---
 drivers/edac/amd64_edac.c | 56 +++++++--------------------------------
 drivers/edac/amd64_edac.h |  4 ++-
 2 files changed, 13 insertions(+), 47 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 2f6ab783bf20..886ad075d222 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -3766,6 +3766,7 @@ static int per_family_init(struct amd64_pvt *pvt)
 	pvt->stepping	= boot_cpu_data.x86_stepping;
 	pvt->model	= boot_cpu_data.x86_model;
 	pvt->fam	= boot_cpu_data.x86;
+	char *tmp_name = NULL;
 	pvt->max_mcs	= 2;
 
 	/*
@@ -3779,7 +3780,7 @@ static int per_family_init(struct amd64_pvt *pvt)
 
 	switch (pvt->fam) {
 	case 0xf:
-		pvt->ctl_name				= (pvt->ext_model >= K8_REV_F) ?
+		tmp_name				= (pvt->ext_model >= K8_REV_F) ?
 							  "K8 revF or later" : "K8 revE or earlier";
 		pvt->f1_id				= PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP;
 		pvt->f2_id				= PCI_DEVICE_ID_AMD_K8_NB_MEMCTL;
@@ -3788,7 +3789,6 @@ static int per_family_init(struct amd64_pvt *pvt)
 		break;
 
 	case 0x10:
-		pvt->ctl_name				= "F10h";
 		pvt->f1_id				= PCI_DEVICE_ID_AMD_10H_NB_MAP;
 		pvt->f2_id				= PCI_DEVICE_ID_AMD_10H_NB_DRAM;
 		pvt->ops->dbam_to_cs			= f10_dbam_to_chip_select;
@@ -3797,12 +3797,10 @@ static int per_family_init(struct amd64_pvt *pvt)
 	case 0x15:
 		switch (pvt->model) {
 		case 0x30:
-			pvt->ctl_name			= "F15h_M30h";
 			pvt->f1_id			= PCI_DEVICE_ID_AMD_15H_M30H_NB_F1;
 			pvt->f2_id			= PCI_DEVICE_ID_AMD_15H_M30H_NB_F2;
 			break;
 		case 0x60:
-			pvt->ctl_name			= "F15h_M60h";
 			pvt->f1_id			= PCI_DEVICE_ID_AMD_15H_M60H_NB_F1;
 			pvt->f2_id			= PCI_DEVICE_ID_AMD_15H_M60H_NB_F2;
 			pvt->ops->dbam_to_cs		= f15_m60h_dbam_to_chip_select;
@@ -3811,7 +3809,6 @@ static int per_family_init(struct amd64_pvt *pvt)
 			/* Richland is only client */
 			return -ENODEV;
 		default:
-			pvt->ctl_name			= "F15h";
 			pvt->f1_id			= PCI_DEVICE_ID_AMD_15H_NB_F1;
 			pvt->f2_id			= PCI_DEVICE_ID_AMD_15H_NB_F2;
 			pvt->ops->dbam_to_cs		= f15_dbam_to_chip_select;
@@ -3822,12 +3819,10 @@ static int per_family_init(struct amd64_pvt *pvt)
 	case 0x16:
 		switch (pvt->model) {
 		case 0x30:
-			pvt->ctl_name			= "F16h_M30h";
 			pvt->f1_id			= PCI_DEVICE_ID_AMD_16H_M30H_NB_F1;
 			pvt->f2_id			= PCI_DEVICE_ID_AMD_16H_M30H_NB_F2;
 			break;
 		default:
-			pvt->ctl_name			= "F16h";
 			pvt->f1_id			= PCI_DEVICE_ID_AMD_16H_NB_F1;
 			pvt->f2_id			= PCI_DEVICE_ID_AMD_16H_NB_F2;
 			break;
@@ -3836,76 +3831,51 @@ static int per_family_init(struct amd64_pvt *pvt)
 
 	case 0x17:
 		switch (pvt->model) {
-		case 0x10 ... 0x2f:
-			pvt->ctl_name			= "F17h_M10h";
-			break;
 		case 0x30 ... 0x3f:
-			pvt->ctl_name			= "F17h_M30h";
 			pvt->max_mcs			= 8;
 			break;
-		case 0x60 ... 0x6f:
-			pvt->ctl_name			= "F17h_M60h";
-			break;
-		case 0x70 ... 0x7f:
-			pvt->ctl_name			= "F17h_M70h";
-			break;
 		default:
-			pvt->ctl_name			= "F17h";
 			break;
 		}
 		break;
 
 	case 0x18:
-		pvt->ctl_name				= "F18h";
 		break;
 
 	case 0x19:
 		switch (pvt->model) {
 		case 0x00 ... 0x0f:
-			pvt->ctl_name			= "F19h";
 			pvt->max_mcs			= 8;
 			break;
 		case 0x10 ... 0x1f:
-			pvt->ctl_name			= "F19h_M10h";
 			pvt->max_mcs			= 12;
 			pvt->flags.zn_regs_v2		= 1;
 			break;
-		case 0x20 ... 0x2f:
-			pvt->ctl_name			= "F19h_M20h";
-			break;
 		case 0x30 ... 0x3f:
 			if (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) {
-				pvt->ctl_name		= "MI200";
+				tmp_name			= "MI200";
 				pvt->max_mcs		= 4;
 				pvt->dram_type		= MEM_HBM2;
 				pvt->gpu_umc_base	= 0x50000;
 				pvt->ops		= &gpu_ops;
 			} else {
-				pvt->ctl_name		= "F19h_M30h";
 				pvt->max_mcs		= 8;
 			}
 			break;
-		case 0x50 ... 0x5f:
-			pvt->ctl_name			= "F19h_M50h";
-			break;
 		case 0x60 ... 0x6f:
-			pvt->ctl_name			= "F19h_M60h";
 			pvt->flags.zn_regs_v2		= 1;
 			break;
 		case 0x70 ... 0x7f:
-			pvt->ctl_name			= "F19h_M70h";
 			pvt->max_mcs			= 4;
 			pvt->flags.zn_regs_v2		= 1;
 			break;
 		case 0x90 ... 0x9f:
-			pvt->ctl_name			= "F19h_M90h";
 			pvt->max_mcs			= 4;
 			pvt->dram_type			= MEM_HBM3;
 			pvt->gpu_umc_base		= 0x90000;
 			pvt->ops			= &gpu_ops;
 			break;
 		case 0xa0 ... 0xaf:
-			pvt->ctl_name			= "F19h_MA0h";
 			pvt->max_mcs			= 12;
 			pvt->flags.zn_regs_v2		= 1;
 			break;
@@ -3915,34 +3885,22 @@ static int per_family_init(struct amd64_pvt *pvt)
 	case 0x1A:
 		switch (pvt->model) {
 		case 0x00 ... 0x1f:
-			pvt->ctl_name           = "F1Ah";
 			pvt->max_mcs            = 12;
 			pvt->flags.zn_regs_v2   = 1;
 			break;
 		case 0x40 ... 0x4f:
-			pvt->ctl_name           = "F1Ah_M40h";
 			pvt->flags.zn_regs_v2   = 1;
 			break;
 		case 0x50 ... 0x57:
-			pvt->ctl_name           = "F1Ah_M50h";
+		case 0xc0 ... 0xc7:
 			pvt->max_mcs            = 16;
 			pvt->flags.zn_regs_v2   = 1;
 			break;
 		case 0x90 ... 0x9f:
-			pvt->ctl_name           = "F1Ah_M90h";
-			pvt->max_mcs            = 8;
-			pvt->flags.zn_regs_v2   = 1;
-			break;
 		case 0xa0 ... 0xaf:
-			pvt->ctl_name           = "F1Ah_MA0h";
 			pvt->max_mcs            = 8;
 			pvt->flags.zn_regs_v2   = 1;
 			break;
-		case 0xc0 ... 0xc7:
-			pvt->ctl_name           = "F1Ah_MC0h";
-			pvt->max_mcs            = 16;
-			pvt->flags.zn_regs_v2   = 1;
-			break;
 		}
 		break;
 
@@ -3951,6 +3909,12 @@ static int per_family_init(struct amd64_pvt *pvt)
 		return -ENODEV;
 	}
 
+	if (tmp_name)
+		scnprintf(pvt->ctl_name, sizeof(pvt->ctl_name), tmp_name);
+	else
+		scnprintf(pvt->ctl_name, sizeof(pvt->ctl_name), "F%02Xh_M%02Xh",
+			  pvt->fam, pvt->model);
+
 	return 0;
 }
 
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index d70b8a8d0b09..4ec6133d5179 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -101,6 +101,8 @@
 #define ON true
 #define OFF false
 
+#define MAX_CTL_NAMELEN	19
+
 /*
  * PCI-defined configuration space registers
  */
@@ -362,7 +364,7 @@ struct amd64_pvt {
 	/* x4, x8, or x16 syndromes in use */
 	u8 ecc_sym_sz;
 
-	const char *ctl_name;
+	char ctl_name[MAX_CTL_NAMELEN];
 	u16 f1_id, f2_id;
 	/* Maximum number of memory controllers per die/node. */
 	u8 max_mcs;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] EDAC/amd64: Remove NUM_CONTROLLERS macro
  2025-11-06  1:54 [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 1/3] EDAC/amd64: Generate ctl_name string at runtime Avadhut Naik
@ 2025-11-06  1:54 ` Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 3/3] edac: Remove the legacy EDAC sysfs interface Avadhut Naik
  2025-11-07 12:40 ` [PATCH v2 0/3] Cleanups in amd64_edac and removal of " Borislav Petkov
  3 siblings, 0 replies; 5+ messages in thread
From: Avadhut Naik @ 2025-11-06  1:54 UTC (permalink / raw)
  To: linux-edac, linux-doc
  Cc: bp, gregkh, corbet, chenhuacai, mchehab+huawei, yazen.ghannam,
	linux-kernel, avadhut.naik

Currently, the NUM_CONTROLLERS macro is used to limit the amount of
memory controllers (UMCs) available per node.

The number of UMCs available per node, however, is already cached by
the max_mcs variable of struct amd64_pvt. Allocate the relevant data
structures dynamically using the variable instead of static allocation
through the macro.

The max_mcs variable is used for legacy systems too. These systems have
a max of 2 controllers. Since the default value of max_mcs, set in
per_family_init(), is 2, these legacy systems are also covered by this
change.

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
---
 drivers/edac/amd64_edac.c | 5 +++++
 drivers/edac/amd64_edac.h | 3 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 886ad075d222..2391f3469961 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -3732,6 +3732,7 @@ static void hw_info_put(struct amd64_pvt *pvt)
 	pci_dev_put(pvt->F1);
 	pci_dev_put(pvt->F2);
 	kfree(pvt->umc);
+	kfree(pvt->csels);
 }
 
 static struct low_ops umc_ops = {
@@ -3915,6 +3916,10 @@ static int per_family_init(struct amd64_pvt *pvt)
 		scnprintf(pvt->ctl_name, sizeof(pvt->ctl_name), "F%02Xh_M%02Xh",
 			  pvt->fam, pvt->model);
 
+	pvt->csels = kcalloc(pvt->max_mcs, sizeof(*pvt->csels), GFP_KERNEL);
+	if (!pvt->csels)
+		return -ENOMEM;
+
 	return 0;
 }
 
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 4ec6133d5179..1757c1b99fc8 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -96,7 +96,6 @@
 /* Hardware limit on ChipSelect rows per MC and processors per system */
 #define NUM_CHIPSELECTS			8
 #define DRAM_RANGES			8
-#define NUM_CONTROLLERS			16
 
 #define ON true
 #define OFF false
@@ -348,7 +347,7 @@ struct amd64_pvt {
 	u32 dbam1;		/* DRAM Base Address Mapping reg for DCT1 */
 
 	/* one for each DCT/UMC */
-	struct chip_select csels[NUM_CONTROLLERS];
+	struct chip_select *csels;
 
 	/* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */
 	struct dram_range ranges[DRAM_RANGES];
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] edac: Remove the legacy EDAC sysfs interface
  2025-11-06  1:54 [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 1/3] EDAC/amd64: Generate ctl_name string at runtime Avadhut Naik
  2025-11-06  1:54 ` [PATCH v2 2/3] EDAC/amd64: Remove NUM_CONTROLLERS macro Avadhut Naik
@ 2025-11-06  1:54 ` Avadhut Naik
  2025-11-07 12:40 ` [PATCH v2 0/3] Cleanups in amd64_edac and removal of " Borislav Petkov
  3 siblings, 0 replies; 5+ messages in thread
From: Avadhut Naik @ 2025-11-06  1:54 UTC (permalink / raw)
  To: linux-edac, linux-doc
  Cc: bp, gregkh, corbet, chenhuacai, mchehab+huawei, yazen.ghannam,
	linux-kernel, avadhut.naik

Commit 199747106934 ("edac: add a new per-dimm API and make the old
per-virtual-rank API obsolete") introduced a new per-dimm sysfs interface
for EDAC making the old per-virtual-rank sysfs interface obsolete.

Since this new sysfs interface was introduced more than a decade ago,
remove the obsolete legacy interface.

Signed-off-by: Avadhut Naik <avadhut.naik@amd.com>
---
 Documentation/admin-guide/RAS/main.rst     | 142 +-------
 arch/loongarch/configs/loongson3_defconfig |   1 -
 drivers/edac/Kconfig                       |   8 -
 drivers/edac/edac_mc_sysfs.c               | 404 ---------------------
 4 files changed, 3 insertions(+), 552 deletions(-)

diff --git a/Documentation/admin-guide/RAS/main.rst b/Documentation/admin-guide/RAS/main.rst
index 447bfde509fb..5a45db32c49b 100644
--- a/Documentation/admin-guide/RAS/main.rst
+++ b/Documentation/admin-guide/RAS/main.rst
@@ -406,24 +406,8 @@ index of the MC::
 		   |->mc2
 		   ....
 
-Under each ``mcX`` directory each ``csrowX`` is again represented by a
-``csrowX``, where ``X`` is the csrow index::
-
-	.../mc/mc0/
-		|
-		|->csrow0
-		|->csrow2
-		|->csrow3
-		....
-
-Notice that there is no csrow1, which indicates that csrow0 is composed
-of a single ranked DIMMs. This should also apply in both Channels, in
-order to have dual-channel mode be operational. Since both csrow2 and
-csrow3 are populated, this indicates a dual ranked set of DIMMs for
-channels 0 and 1.
-
-Within each of the ``mcX`` and ``csrowX`` directories are several EDAC
-control and attribute files.
+Within each of the ``mcX`` directory are several EDAC control and
+attribute files.
 
 ``mcX`` directories
 -------------------
@@ -569,7 +553,7 @@ this ``X`` memory module:
 		- Unbuffered-DDR
 
 .. [#f5] On some systems, the memory controller doesn't have any logic
-  to identify the memory module. On such systems, the directory is called ``rankX`` and works on a similar way as the ``csrowX`` directories.
+  to identify the memory module. On such systems, the directory is called ``rankX``.
   On modern Intel memory controllers, the memory controller identifies the
   memory modules directly. On such systems, the directory is called ``dimmX``.
 
@@ -577,126 +561,6 @@ this ``X`` memory module:
   symlinks inside the sysfs mapping that are automatically created by
   the sysfs subsystem. Currently, they serve no purpose.
 
-``csrowX`` directories
-----------------------
-
-When CONFIG_EDAC_LEGACY_SYSFS is enabled, sysfs will contain the ``csrowX``
-directories. As this API doesn't work properly for Rambus, FB-DIMMs and
-modern Intel Memory Controllers, this is being deprecated in favor of
-``dimmX`` directories.
-
-In the ``csrowX`` directories are EDAC control and attribute files for
-this ``X`` instance of csrow:
-
-
-- ``ue_count`` - Total Uncorrectable Errors count attribute file
-
-	This attribute file displays the total count of uncorrectable
-	errors that have occurred on this csrow. If panic_on_ue is set
-	this counter will not have a chance to increment, since EDAC
-	will panic the system.
-
-
-- ``ce_count`` - Total Correctable Errors count attribute file
-
-	This attribute file displays the total count of correctable
-	errors that have occurred on this csrow. This count is very
-	important to examine. CEs provide early indications that a
-	DIMM is beginning to fail. This count field should be
-	monitored for non-zero values and report such information
-	to the system administrator.
-
-
-- ``size_mb`` - Total memory managed by this csrow attribute file
-
-	This attribute file displays, in count of megabytes, the memory
-	that this csrow contains.
-
-
-- ``mem_type`` - Memory Type attribute file
-
-	This attribute file will display what type of memory is currently
-	on this csrow. Normally, either buffered or unbuffered memory.
-	Examples:
-
-		- Registered-DDR
-		- Unbuffered-DDR
-
-
-- ``edac_mode`` - EDAC Mode of operation attribute file
-
-	This attribute file will display what type of Error detection
-	and correction is being utilized.
-
-
-- ``dev_type`` - Device type attribute file
-
-	This attribute file will display what type of DRAM device is
-	being utilized on this DIMM.
-	Examples:
-
-		- x1
-		- x2
-		- x4
-		- x8
-
-
-- ``ch0_ce_count`` - Channel 0 CE Count attribute file
-
-	This attribute file will display the count of CEs on this
-	DIMM located in channel 0.
-
-
-- ``ch0_ue_count`` - Channel 0 UE Count attribute file
-
-	This attribute file will display the count of UEs on this
-	DIMM located in channel 0.
-
-
-- ``ch0_dimm_label`` - Channel 0 DIMM Label control file
-
-
-	This control file allows this DIMM to have a label assigned
-	to it. With this label in the module, when errors occur
-	the output can provide the DIMM label in the system log.
-	This becomes vital for panic events to isolate the
-	cause of the UE event.
-
-	DIMM Labels must be assigned after booting, with information
-	that correctly identifies the physical slot with its
-	silk screen label. This information is currently very
-	motherboard specific and determination of this information
-	must occur in userland at this time.
-
-
-- ``ch1_ce_count`` - Channel 1 CE Count attribute file
-
-
-	This attribute file will display the count of CEs on this
-	DIMM located in channel 1.
-
-
-- ``ch1_ue_count`` - Channel 1 UE Count attribute file
-
-
-	This attribute file will display the count of UEs on this
-	DIMM located in channel 0.
-
-
-- ``ch1_dimm_label`` - Channel 1 DIMM Label control file
-
-	This control file allows this DIMM to have a label assigned
-	to it. With this label in the module, when errors occur
-	the output can provide the DIMM label in the system log.
-	This becomes vital for panic events to isolate the
-	cause of the UE event.
-
-	DIMM Labels must be assigned after booting, with information
-	that correctly identifies the physical slot with its
-	silk screen label. This information is currently very
-	motherboard specific and determination of this information
-	must occur in userland at this time.
-
 
 System Logging
 --------------
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index 3e838c229cd5..50e1304e7a6f 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -917,7 +917,6 @@ CONFIG_MMC=y
 CONFIG_MMC_LOONGSON2=m
 CONFIG_INFINIBAND=m
 CONFIG_EDAC=y
-# CONFIG_EDAC_LEGACY_SYSFS is not set
 CONFIG_EDAC_LOONGSON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_EFI=y
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 39352b9b7a7e..9a7ff42064e9 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -23,14 +23,6 @@ menuconfig EDAC
 
 if EDAC
 
-config EDAC_LEGACY_SYSFS
-	bool "EDAC legacy sysfs"
-	default y
-	help
-	  Enable the compatibility sysfs nodes.
-	  Use 'Y' if your edac utilities aren't ported to work with the newer
-	  structures.
-
 config EDAC_DEBUG
 	bool "Debugging"
 	select DEBUG_FS
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 8689631f1905..091cc6aae8a9 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -115,401 +115,6 @@ static const char * const edac_caps[] = {
 	[EDAC_S16ECD16ED] = "S16ECD16ED"
 };
 
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-/*
- * EDAC sysfs CSROW data structures and methods
- */
-
-#define to_csrow(k) container_of(k, struct csrow_info, dev)
-
-/*
- * We need it to avoid namespace conflicts between the legacy API
- * and the per-dimm/per-rank one
- */
-#define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \
-	static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store)
-
-struct dev_ch_attribute {
-	struct device_attribute attr;
-	unsigned int channel;
-};
-
-#define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
-	static struct dev_ch_attribute dev_attr_legacy_##_name = \
-		{ __ATTR(_name, _mode, _show, _store), (_var) }
-
-#define to_channel(k) (container_of(k, struct dev_ch_attribute, attr)->channel)
-
-/* Set of more default csrow<id> attribute show/store functions */
-static ssize_t csrow_ue_count_show(struct device *dev,
-				   struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-
-	return sysfs_emit(data, "%u\n", csrow->ue_count);
-}
-
-static ssize_t csrow_ce_count_show(struct device *dev,
-				   struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-
-	return sysfs_emit(data, "%u\n", csrow->ce_count);
-}
-
-static ssize_t csrow_size_show(struct device *dev,
-			       struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-	int i;
-	u32 nr_pages = 0;
-
-	for (i = 0; i < csrow->nr_channels; i++)
-		nr_pages += csrow->channels[i]->dimm->nr_pages;
-	return sysfs_emit(data, "%u\n", PAGES_TO_MiB(nr_pages));
-}
-
-static ssize_t csrow_mem_type_show(struct device *dev,
-				   struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-
-	return sysfs_emit(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]);
-}
-
-static ssize_t csrow_dev_type_show(struct device *dev,
-				   struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-
-	return sysfs_emit(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]);
-}
-
-static ssize_t csrow_edac_mode_show(struct device *dev,
-				    struct device_attribute *mattr,
-				    char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-
-	return sysfs_emit(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]);
-}
-
-/* show/store functions for DIMM Label attributes */
-static ssize_t channel_dimm_label_show(struct device *dev,
-				       struct device_attribute *mattr,
-				       char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-	unsigned int chan = to_channel(mattr);
-	struct rank_info *rank = csrow->channels[chan];
-
-	/* if field has not been initialized, there is nothing to send */
-	if (!rank->dimm->label[0])
-		return 0;
-
-	return sysfs_emit(data, "%s\n", rank->dimm->label);
-}
-
-static ssize_t channel_dimm_label_store(struct device *dev,
-					struct device_attribute *mattr,
-					const char *data, size_t count)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-	unsigned int chan = to_channel(mattr);
-	struct rank_info *rank = csrow->channels[chan];
-	size_t copy_count = count;
-
-	if (count == 0)
-		return -EINVAL;
-
-	if (data[count - 1] == '\0' || data[count - 1] == '\n')
-		copy_count -= 1;
-
-	if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label))
-		return -EINVAL;
-
-	memcpy(rank->dimm->label, data, copy_count);
-	rank->dimm->label[copy_count] = '\0';
-
-	return count;
-}
-
-/* show function for dynamic chX_ce_count attribute */
-static ssize_t channel_ce_count_show(struct device *dev,
-				     struct device_attribute *mattr, char *data)
-{
-	struct csrow_info *csrow = to_csrow(dev);
-	unsigned int chan = to_channel(mattr);
-	struct rank_info *rank = csrow->channels[chan];
-
-	return sysfs_emit(data, "%u\n", rank->ce_count);
-}
-
-/* cwrow<id>/attribute files */
-DEVICE_ATTR_LEGACY(size_mb, S_IRUGO, csrow_size_show, NULL);
-DEVICE_ATTR_LEGACY(dev_type, S_IRUGO, csrow_dev_type_show, NULL);
-DEVICE_ATTR_LEGACY(mem_type, S_IRUGO, csrow_mem_type_show, NULL);
-DEVICE_ATTR_LEGACY(edac_mode, S_IRUGO, csrow_edac_mode_show, NULL);
-DEVICE_ATTR_LEGACY(ue_count, S_IRUGO, csrow_ue_count_show, NULL);
-DEVICE_ATTR_LEGACY(ce_count, S_IRUGO, csrow_ce_count_show, NULL);
-
-/* default attributes of the CSROW<id> object */
-static struct attribute *csrow_attrs[] = {
-	&dev_attr_legacy_dev_type.attr,
-	&dev_attr_legacy_mem_type.attr,
-	&dev_attr_legacy_edac_mode.attr,
-	&dev_attr_legacy_size_mb.attr,
-	&dev_attr_legacy_ue_count.attr,
-	&dev_attr_legacy_ce_count.attr,
-	NULL,
-};
-
-static const struct attribute_group csrow_attr_grp = {
-	.attrs	= csrow_attrs,
-};
-
-static const struct attribute_group *csrow_attr_groups[] = {
-	&csrow_attr_grp,
-	NULL
-};
-
-static const struct device_type csrow_attr_type = {
-	.groups		= csrow_attr_groups,
-};
-
-/*
- * possible dynamic channel DIMM Label attribute files
- *
- */
-DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 0);
-DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 1);
-DEVICE_CHANNEL(ch2_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 2);
-DEVICE_CHANNEL(ch3_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 3);
-DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 4);
-DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 5);
-DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 6);
-DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 7);
-DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 8);
-DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 9);
-DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 10);
-DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 11);
-DEVICE_CHANNEL(ch12_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 12);
-DEVICE_CHANNEL(ch13_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 13);
-DEVICE_CHANNEL(ch14_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 14);
-DEVICE_CHANNEL(ch15_dimm_label, S_IRUGO | S_IWUSR,
-	channel_dimm_label_show, channel_dimm_label_store, 15);
-
-/* Total possible dynamic DIMM Label attribute file table */
-static struct attribute *dynamic_csrow_dimm_attr[] = {
-	&dev_attr_legacy_ch0_dimm_label.attr.attr,
-	&dev_attr_legacy_ch1_dimm_label.attr.attr,
-	&dev_attr_legacy_ch2_dimm_label.attr.attr,
-	&dev_attr_legacy_ch3_dimm_label.attr.attr,
-	&dev_attr_legacy_ch4_dimm_label.attr.attr,
-	&dev_attr_legacy_ch5_dimm_label.attr.attr,
-	&dev_attr_legacy_ch6_dimm_label.attr.attr,
-	&dev_attr_legacy_ch7_dimm_label.attr.attr,
-	&dev_attr_legacy_ch8_dimm_label.attr.attr,
-	&dev_attr_legacy_ch9_dimm_label.attr.attr,
-	&dev_attr_legacy_ch10_dimm_label.attr.attr,
-	&dev_attr_legacy_ch11_dimm_label.attr.attr,
-	&dev_attr_legacy_ch12_dimm_label.attr.attr,
-	&dev_attr_legacy_ch13_dimm_label.attr.attr,
-	&dev_attr_legacy_ch14_dimm_label.attr.attr,
-	&dev_attr_legacy_ch15_dimm_label.attr.attr,
-	NULL
-};
-
-/* possible dynamic channel ce_count attribute files */
-DEVICE_CHANNEL(ch0_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 0);
-DEVICE_CHANNEL(ch1_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 1);
-DEVICE_CHANNEL(ch2_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 2);
-DEVICE_CHANNEL(ch3_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 3);
-DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 4);
-DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 5);
-DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 6);
-DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 7);
-DEVICE_CHANNEL(ch8_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 8);
-DEVICE_CHANNEL(ch9_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 9);
-DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 10);
-DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 11);
-DEVICE_CHANNEL(ch12_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 12);
-DEVICE_CHANNEL(ch13_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 13);
-DEVICE_CHANNEL(ch14_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 14);
-DEVICE_CHANNEL(ch15_ce_count, S_IRUGO,
-		   channel_ce_count_show, NULL, 15);
-
-/* Total possible dynamic ce_count attribute file table */
-static struct attribute *dynamic_csrow_ce_count_attr[] = {
-	&dev_attr_legacy_ch0_ce_count.attr.attr,
-	&dev_attr_legacy_ch1_ce_count.attr.attr,
-	&dev_attr_legacy_ch2_ce_count.attr.attr,
-	&dev_attr_legacy_ch3_ce_count.attr.attr,
-	&dev_attr_legacy_ch4_ce_count.attr.attr,
-	&dev_attr_legacy_ch5_ce_count.attr.attr,
-	&dev_attr_legacy_ch6_ce_count.attr.attr,
-	&dev_attr_legacy_ch7_ce_count.attr.attr,
-	&dev_attr_legacy_ch8_ce_count.attr.attr,
-	&dev_attr_legacy_ch9_ce_count.attr.attr,
-	&dev_attr_legacy_ch10_ce_count.attr.attr,
-	&dev_attr_legacy_ch11_ce_count.attr.attr,
-	&dev_attr_legacy_ch12_ce_count.attr.attr,
-	&dev_attr_legacy_ch13_ce_count.attr.attr,
-	&dev_attr_legacy_ch14_ce_count.attr.attr,
-	&dev_attr_legacy_ch15_ce_count.attr.attr,
-	NULL
-};
-
-static umode_t csrow_dev_is_visible(struct kobject *kobj,
-				    struct attribute *attr, int idx)
-{
-	struct device *dev = kobj_to_dev(kobj);
-	struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
-
-	if (idx >= csrow->nr_channels)
-		return 0;
-
-	if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) {
-		WARN_ONCE(1, "idx: %d\n", idx);
-		return 0;
-	}
-
-	/* Only expose populated DIMMs */
-	if (!csrow->channels[idx]->dimm->nr_pages)
-		return 0;
-
-	return attr->mode;
-}
-
-
-static const struct attribute_group csrow_dev_dimm_group = {
-	.attrs = dynamic_csrow_dimm_attr,
-	.is_visible = csrow_dev_is_visible,
-};
-
-static const struct attribute_group csrow_dev_ce_count_group = {
-	.attrs = dynamic_csrow_ce_count_attr,
-	.is_visible = csrow_dev_is_visible,
-};
-
-static const struct attribute_group *csrow_dev_groups[] = {
-	&csrow_dev_dimm_group,
-	&csrow_dev_ce_count_group,
-	NULL
-};
-
-static void csrow_release(struct device *dev)
-{
-	/*
-	 * Nothing to do, just unregister sysfs here. The mci
-	 * device owns the data and will also release it.
-	 */
-}
-
-static inline int nr_pages_per_csrow(struct csrow_info *csrow)
-{
-	int chan, nr_pages = 0;
-
-	for (chan = 0; chan < csrow->nr_channels; chan++)
-		nr_pages += csrow->channels[chan]->dimm->nr_pages;
-
-	return nr_pages;
-}
-
-/* Create a CSROW object under specified edac_mc_device */
-static int edac_create_csrow_object(struct mem_ctl_info *mci,
-				    struct csrow_info *csrow, int index)
-{
-	int err;
-
-	csrow->dev.type = &csrow_attr_type;
-	csrow->dev.groups = csrow_dev_groups;
-	csrow->dev.release = csrow_release;
-	device_initialize(&csrow->dev);
-	csrow->dev.parent = &mci->dev;
-	csrow->mci = mci;
-	dev_set_name(&csrow->dev, "csrow%d", index);
-	dev_set_drvdata(&csrow->dev, csrow);
-
-	err = device_add(&csrow->dev);
-	if (err) {
-		edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev));
-		put_device(&csrow->dev);
-		return err;
-	}
-
-	edac_dbg(0, "device %s created\n", dev_name(&csrow->dev));
-
-	return 0;
-}
-
-/* Create a CSROW object under specified edac_mc_device */
-static int edac_create_csrow_objects(struct mem_ctl_info *mci)
-{
-	int err, i;
-	struct csrow_info *csrow;
-
-	for (i = 0; i < mci->nr_csrows; i++) {
-		csrow = mci->csrows[i];
-		if (!nr_pages_per_csrow(csrow))
-			continue;
-		err = edac_create_csrow_object(mci, mci->csrows[i], i);
-		if (err < 0)
-			goto error;
-	}
-	return 0;
-
-error:
-	for (--i; i >= 0; i--) {
-		if (device_is_registered(&mci->csrows[i]->dev))
-			device_unregister(&mci->csrows[i]->dev);
-	}
-
-	return err;
-}
-
-static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
-{
-	int i;
-
-	for (i = 0; i < mci->nr_csrows; i++) {
-		if (device_is_registered(&mci->csrows[i]->dev))
-			device_unregister(&mci->csrows[i]->dev);
-	}
-}
-
-#endif
-
 /*
  * Per-dimm (or per-rank) devices
  */
@@ -989,12 +594,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
 			goto fail;
 	}
 
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-	err = edac_create_csrow_objects(mci);
-	if (err < 0)
-		goto fail;
-#endif
-
 	edac_create_debugfs_nodes(mci);
 	return 0;
 
@@ -1019,9 +618,6 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
 #ifdef CONFIG_EDAC_DEBUG
 	edac_debugfs_remove_recursive(mci->debugfs);
 #endif
-#ifdef CONFIG_EDAC_LEGACY_SYSFS
-	edac_delete_csrow_objects(mci);
-#endif
 
 	mci_for_each_dimm(mci, dimm) {
 		if (!device_is_registered(&dimm->dev))
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface
  2025-11-06  1:54 [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface Avadhut Naik
                   ` (2 preceding siblings ...)
  2025-11-06  1:54 ` [PATCH v2 3/3] edac: Remove the legacy EDAC sysfs interface Avadhut Naik
@ 2025-11-07 12:40 ` Borislav Petkov
  3 siblings, 0 replies; 5+ messages in thread
From: Borislav Petkov @ 2025-11-07 12:40 UTC (permalink / raw)
  To: Avadhut Naik
  Cc: linux-edac, linux-doc, gregkh, corbet, chenhuacai,
	mchehab+huawei, yazen.ghannam, linux-kernel

On Thu, Nov 06, 2025 at 01:54:43AM +0000, Avadhut Naik wrote:
> This patchset undertakes some cleanups in the amd64_edac module and
> removes the legacy EDAC sysfs interface since it has been obsolete for
> more than a decade.
> 
> The first patch removes explicit assignment of the ctl_name string and
> instead generates it at runtime using scnprintf.
> 
> The second patch removes the NUM_CONTROLLERS macro and instead uses the
> max_mcs variable to determine the size of chipselect array.
> 
> The third patch removes the old EDAC sysfs interface.
> 
> NOTE:
> These cleanups were earlier submitted as part of the set adding EDAC
> support for AMD's newer Family 1Ah-based SOCs.[1] However, since the
> support patches were critical to enabling EDAC on newer AMD SOCs and
> since these cleanups were still under review, the set was split up.
> 
> [1]: https://lore.kernel.org/all/20250909185748.1621098-1-avadhut.naik@amd.com/
> 
> Changes in v2:
>  - Drop the patch that set zn_regs_v2 flag for all SOCs based on Family
> 1Ah and later.
>  - Change MAX_CTL_NAMELEN macro from 20 to 19.
>  - Modify commit message of the second patch per feedback received.
>  - Skip deprecation and just remove the old EDAC sysfs interface.
> 
> Links:
> v1: https://lore.kernel.org/all/20251013173632.1449366-1-avadhut.naik@amd.com/
> 
> Avadhut Naik (3):
>   EDAC/amd64: Generate ctl_name string at runtime
>   EDAC/amd64: Remove NUM_CONTROLLERS macro
>   edac: Remove the legacy EDAC sysfs interface
> 
>  Documentation/admin-guide/RAS/main.rst     | 142 +-------
>  arch/loongarch/configs/loongson3_defconfig |   1 -
>  drivers/edac/Kconfig                       |   8 -
>  drivers/edac/amd64_edac.c                  |  61 +---
>  drivers/edac/amd64_edac.h                  |   7 +-
>  drivers/edac/edac_mc_sysfs.c               | 404 ---------------------
>  6 files changed, 22 insertions(+), 601 deletions(-)

Queued, thanks.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-11-07 12:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-06  1:54 [PATCH v2 0/3] Cleanups in amd64_edac and removal of legacy EDAC sysfs interface Avadhut Naik
2025-11-06  1:54 ` [PATCH v2 1/3] EDAC/amd64: Generate ctl_name string at runtime Avadhut Naik
2025-11-06  1:54 ` [PATCH v2 2/3] EDAC/amd64: Remove NUM_CONTROLLERS macro Avadhut Naik
2025-11-06  1:54 ` [PATCH v2 3/3] edac: Remove the legacy EDAC sysfs interface Avadhut Naik
2025-11-07 12:40 ` [PATCH v2 0/3] Cleanups in amd64_edac and removal of " Borislav Petkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®