Linux EDAC development
 help / color / mirror / Atom feed
* [1/1] EDAC, sb_edac: Classify memory mirroring modes.
@ 2017-07-31  6:23 Borislav Petkov
  0 siblings, 0 replies; 3+ messages in thread
From: Borislav Petkov @ 2017-07-31  6:23 UTC (permalink / raw)
  To: Qiuxu Zhuo; +Cc: mchehab, tony.luck, arozansk, patrickg, linux-edac

On Thu, Jul 27, 2017 at 11:42:16PM +0800, Qiuxu Zhuo wrote:
> Basically there are full memory mirroring and address range partial
> memory mirroring(supported by Haswell EX and Broadwell EX) modes.
> 
> a) In full memory mirroring, the memory behind each memory controller
>    is mirrored, the memory is split into two identical mirrors (primary
>    and secondary), half of the memory is reserved for redundancy.
> 
> b) In address range partial memory mirroring, the memory size(range)
>    of primary and secondary behind each memory controller can be user
>    defined by the TAD0 register. The rest memory ranges defined by
>    TAD1/TAD2/... in that memory controller are non-mirrored.
> 
> For more detail mirroring, see the following link written by Tony Luck:
> https://01.org/lkp/blogs/tonyluck/2016/address-range-partial-memory-mirroring-linux
> 
> Currently the sb_edac driver only supports address decoding in full
> memory mirroring and non-mirroring modes. In address range partial memory
> mirroring mode, it may fail to decode address that falls in non-mirroring
> area (the following was one of this kind failed logs).
>   ---
>   mce: Uncorrected hardware memory error in user-access at 566d53a400
>   Memory failure: 0x566d53a: Killing einj_mem_uc:4647 due to hardware memory corruption
>   Memory failure: 0x566d53a: recovery action for dirty LRU page: Recovered
>   mce: [Hardware Error]: Machine check events logged
>   EDAC sbridge MC1: HANDLING MCE MEMORY ERROR
>   EDAC sbridge MC1: CPU 48: Machine Check Event: 0 Bank 7: ec00000000010090
>   EDAC sbridge MC1: TSC 4b914aa5a99dab
>   EDAC sbridge MC1: ADDR 566d53a400
>   EDAC sbridge MC1: MISC 1443a0c86
>   EDAC sbridge MC1: PROCESSOR 0:406f1 TIME 1499712764 SOCKET 2 APIC 80
>   EDAC MC1: 0 UE Can't discover the memory rank for ch addr 0x7fb54e900 on any memory ( page:0x0 offset:0x0 grain:32)
>   mce: [Hardware Error]: Machine check events logged
>   ---
> 
> This patch classifies memory mirroring modes, and makes the address decoding
> in address range partial memory mode correct.
> 
> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> ---
>  drivers/edac/sb_edac.c | 45 ++++++++++++++++++++++++++++++++-------------
>  1 file changed, 32 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
> index 80d860c..cae3a5b 100644
> --- a/drivers/edac/sb_edac.c
> +++ b/drivers/edac/sb_edac.c
> @@ -300,6 +300,12 @@ enum domain {
>  	SOCK,
>  };
>  
> +enum mirroring_mode {
> +	NON_MIRRORING,
> +	ADDR_RANGE_MIRRORING,
> +	FULL_MIRRORING,
> +};
> +
>  struct sbridge_pvt;
>  struct sbridge_info {
>  	enum type	type;
> @@ -377,8 +383,9 @@ struct sbridge_pvt {
>  	struct sbridge_channel	channel[NUM_CHANNELS];
>  
>  	/* Memory type detection */
> -	bool			is_mirrored, is_lockstep, is_close_pg;
> +	bool			is_cur_addr_mirrored, is_lockstep, is_close_pg;
>  	bool			is_chan_hash;
> +	enum mirroring_mode	mirroring_md;

Call that variable simply "mirror_mode"

>  	/* Memory description */
>  	u64			tolm, tohm;
> @@ -1648,10 +1655,6 @@ static int get_dimm_config(struct mem_ctl_info *mci)
>  	enum edac_type mode;
>  	u32 reg;
>  
> -	if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
> -		pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, &reg);
> -		pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
> -	}
>  	pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
>  	edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
>  		 pvt->sbridge_dev->mc,
> @@ -1663,21 +1666,32 @@ static int get_dimm_config(struct mem_ctl_info *mci)
>  	 */
>  	if (pvt->info.type == KNIGHTS_LANDING) {
>  		mode = EDAC_S4ECD4ED;
> -		pvt->is_mirrored = false;
> +		pvt->mirroring_md = NON_MIRRORING;
> +		pvt->is_cur_addr_mirrored = false;
>  
>  		if (knl_get_dimm_capacity(pvt, knl_mc_sizes) != 0)
>  			return -1;
>  		pci_read_config_dword(pvt->pci_ta, KNL_MCMTR, &pvt->info.mcmtr);
>  	} else {
> +		if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
> +			pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, &reg);

Error handling.

> +			pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
> +			if (GET_BITFIELD(reg, 28, 28)) {
> +				pvt->mirroring_md = ADDR_RANGE_MIRRORING;
> +				edac_dbg(0, "Address range partial memory mirroring is enabled\n");
> +				goto next;
> +			}
> +		}

^ permalink raw reply	[flat|nested] 3+ messages in thread
* [1/1] EDAC, sb_edac: Classify memory mirroring modes.
@ 2017-07-31  8:53 Qiuxu Zhuo
  0 siblings, 0 replies; 3+ messages in thread
From: Qiuxu Zhuo @ 2017-07-31  8:53 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: mchehab@osg.samsung.com, Luck, Tony, arozansk@redhat.com,
	patrickg@supermicro.com, linux-edac@vger.kernel.org

PiBGcm9tOiBCb3Jpc2xhdiBQZXRrb3YgW21haWx0bzpicEBhbGllbjguZGVdDQo+ID4gIAkvKiBN
ZW1vcnkgdHlwZSBkZXRlY3Rpb24gKi8NCj4gPiAtCWJvb2wJCQlpc19taXJyb3JlZCwgaXNfbG9j
a3N0ZXAsIGlzX2Nsb3NlX3BnOw0KPiA+ICsJYm9vbAkJCWlzX2N1cl9hZGRyX21pcnJvcmVkLCBp
c19sb2Nrc3RlcCwgaXNfY2xvc2VfcGc7DQo+ID4gIAlib29sCQkJaXNfY2hhbl9oYXNoOw0KPiA+
ICsJZW51bSBtaXJyb3JpbmdfbW9kZQltaXJyb3JpbmdfbWQ7DQo+IA0KPiBDYWxsIHRoYXQgdmFy
aWFibGUgc2ltcGx5ICJtaXJyb3JfbW9kZSINCg0KT0ssIHdpbGwgdXBkYXRlIGl0IGluIHYyLiAN
Cg0KPiA+ICsJCQlwY2lfcmVhZF9jb25maWdfZHdvcmQocHZ0LT5wY2lfaGEsDQo+IEhBU1dFTExf
SEFTWVNERUZFQVRVUkUyLCAmcmVnKTsNCj4gDQo+IEVycm9yIGhhbmRsaW5nLg0KDQpPSywgd2ls
bCBhZGQgZXJyb3IgaGFuZGxpbmcgaW4gdjIuDQoNCg0KVGhhbmtzIQ0KUWl1eHUNCg0K
---
To unsubscribe from this list: send the line "unsubscribe linux-edac" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 3+ messages in thread
* [1/1] EDAC, sb_edac: Classify memory mirroring modes.
@ 2017-07-27 15:42 Qiuxu Zhuo
  0 siblings, 0 replies; 3+ messages in thread
From: Qiuxu Zhuo @ 2017-07-27 15:42 UTC (permalink / raw)
  To: bp, mchehab; +Cc: tony.luck, arozansk, patrickg, linux-edac, Qiuxu Zhuo

Basically there are full memory mirroring and address range partial
memory mirroring(supported by Haswell EX and Broadwell EX) modes.

a) In full memory mirroring, the memory behind each memory controller
   is mirrored, the memory is split into two identical mirrors (primary
   and secondary), half of the memory is reserved for redundancy.

b) In address range partial memory mirroring, the memory size(range)
   of primary and secondary behind each memory controller can be user
   defined by the TAD0 register. The rest memory ranges defined by
   TAD1/TAD2/... in that memory controller are non-mirrored.

For more detail mirroring, see the following link written by Tony Luck:
https://01.org/lkp/blogs/tonyluck/2016/address-range-partial-memory-mirroring-linux

Currently the sb_edac driver only supports address decoding in full
memory mirroring and non-mirroring modes. In address range partial memory
mirroring mode, it may fail to decode address that falls in non-mirroring
area (the following was one of this kind failed logs).
  ---
  mce: Uncorrected hardware memory error in user-access at 566d53a400
  Memory failure: 0x566d53a: Killing einj_mem_uc:4647 due to hardware memory corruption
  Memory failure: 0x566d53a: recovery action for dirty LRU page: Recovered
  mce: [Hardware Error]: Machine check events logged
  EDAC sbridge MC1: HANDLING MCE MEMORY ERROR
  EDAC sbridge MC1: CPU 48: Machine Check Event: 0 Bank 7: ec00000000010090
  EDAC sbridge MC1: TSC 4b914aa5a99dab
  EDAC sbridge MC1: ADDR 566d53a400
  EDAC sbridge MC1: MISC 1443a0c86
  EDAC sbridge MC1: PROCESSOR 0:406f1 TIME 1499712764 SOCKET 2 APIC 80
  EDAC MC1: 0 UE Can't discover the memory rank for ch addr 0x7fb54e900 on any memory ( page:0x0 offset:0x0 grain:32)
  mce: [Hardware Error]: Machine check events logged
  ---

This patch classifies memory mirroring modes, and makes the address decoding
in address range partial memory mode correct.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
---
 drivers/edac/sb_edac.c | 45 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 80d860c..cae3a5b 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -300,6 +300,12 @@ enum domain {
 	SOCK,
 };
 
+enum mirroring_mode {
+	NON_MIRRORING,
+	ADDR_RANGE_MIRRORING,
+	FULL_MIRRORING,
+};
+
 struct sbridge_pvt;
 struct sbridge_info {
 	enum type	type;
@@ -377,8 +383,9 @@ struct sbridge_pvt {
 	struct sbridge_channel	channel[NUM_CHANNELS];
 
 	/* Memory type detection */
-	bool			is_mirrored, is_lockstep, is_close_pg;
+	bool			is_cur_addr_mirrored, is_lockstep, is_close_pg;
 	bool			is_chan_hash;
+	enum mirroring_mode	mirroring_md;
 
 	/* Memory description */
 	u64			tolm, tohm;
@@ -1648,10 +1655,6 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 	enum edac_type mode;
 	u32 reg;
 
-	if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
-		pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, &reg);
-		pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
-	}
 	pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
 	edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
 		 pvt->sbridge_dev->mc,
@@ -1663,21 +1666,32 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 	 */
 	if (pvt->info.type == KNIGHTS_LANDING) {
 		mode = EDAC_S4ECD4ED;
-		pvt->is_mirrored = false;
+		pvt->mirroring_md = NON_MIRRORING;
+		pvt->is_cur_addr_mirrored = false;
 
 		if (knl_get_dimm_capacity(pvt, knl_mc_sizes) != 0)
 			return -1;
 		pci_read_config_dword(pvt->pci_ta, KNL_MCMTR, &pvt->info.mcmtr);
 	} else {
+		if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
+			pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, &reg);
+			pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
+			if (GET_BITFIELD(reg, 28, 28)) {
+				pvt->mirroring_md = ADDR_RANGE_MIRRORING;
+				edac_dbg(0, "Address range partial memory mirroring is enabled\n");
+				goto next;
+			}
+		}
 		pci_read_config_dword(pvt->pci_ras, RASENABLES, &reg);
 		if (IS_MIRROR_ENABLED(reg)) {
-			edac_dbg(0, "Memory mirror is enabled\n");
-			pvt->is_mirrored = true;
+			pvt->mirroring_md = FULL_MIRRORING;
+			edac_dbg(0, "Full memory mirroring is enabled\n");
 		} else {
-			edac_dbg(0, "Memory mirror is disabled\n");
-			pvt->is_mirrored = false;
+			pvt->mirroring_md = NON_MIRRORING;
+			edac_dbg(0, "Memory mirroring is disabled\n");
 		}
 
+next:
 		pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
 		if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
 			edac_dbg(0, "Lockstep is enabled\n");
@@ -2092,7 +2106,8 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
 
 	pci_read_config_dword(pvt->pci_tad[base_ch], tad_ch_nilv_offset[n_tads], &tad_offset);
 
-	if (pvt->is_mirrored) {
+	if (pvt->mirroring_md == FULL_MIRRORING ||
+	    (pvt->mirroring_md == ADDR_RANGE_MIRRORING && n_tads == 0)) {
 		*channel_mask |= 1 << ((base_ch + 2) % 4);
 		switch(ch_way) {
 		case 2:
@@ -2103,8 +2118,12 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
 			sprintf(msg, "Invalid mirror set. Can't decode addr");
 			return -EINVAL;
 		}
-	} else
+
+		pvt->is_cur_addr_mirrored = true;
+	} else {
 		sck_xch = (1 << sck_way) * ch_way;
+		pvt->is_cur_addr_mirrored = false;
+	}
 
 	if (pvt->is_lockstep)
 		*channel_mask |= 1 << ((base_ch + 1) % 4);
@@ -2967,7 +2986,7 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci,
 	 * EDAC core should be handling the channel mask, in order to point
 	 * to the group of dimm's where the error may be happening.
 	 */
-	if (!pvt->is_lockstep && !pvt->is_mirrored && !pvt->is_close_pg)
+	if (!pvt->is_lockstep && !pvt->is_cur_addr_mirrored && !pvt->is_close_pg)
 		channel = first_channel;
 
 	snprintf(msg, sizeof(msg),

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

end of thread, other threads:[~2017-07-31  8:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-31  6:23 [1/1] EDAC, sb_edac: Classify memory mirroring modes Borislav Petkov
  -- strict thread matches above, loose matches on Subject: below --
2017-07-31  8:53 Qiuxu Zhuo
2017-07-27 15:42 Qiuxu Zhuo

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