diff options
author | jc25722 <none@none> | 2006-09-29 04:43:00 -0700 |
---|---|---|
committer | jc25722 <none@none> | 2006-09-29 04:43:00 -0700 |
commit | 2f48339a0c14421b8826b39fc3ab783a064cb77b (patch) | |
tree | ff49f79c47a10ee893d144e58146a55cd1bbc2db /usr/src | |
parent | 731b94c18e9b5138386b0074dc75321a7edf0fb4 (diff) | |
download | illumos-joyent-2f48339a0c14421b8826b39fc3ab783a064cb77b.tar.gz |
6371709 Events with different AFARs should be treated as separate events
Diffstat (limited to 'usr/src')
5 files changed, 139 insertions, 55 deletions
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c index f240974776..8af910607c 100644 --- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c +++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c @@ -1239,22 +1239,32 @@ cmd_xxcu_train_match(cmd_errcl_t mask) return (0); } - +/* + * Search for the entry that matches the ena and the AFAR + * if we have a valid AFAR, otherwise just match the ENA + */ cmd_xxcu_trw_t * -cmd_trw_lookup(uint64_t ena) +cmd_trw_lookup(uint64_t ena, uint8_t afar_status, uint64_t afar) { int i; - for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { + if (afar_status == AFLT_STAT_VALID) { + for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { + if (cmd.cmd_xxcu_trw[i].trw_ena == ena && + cmd.cmd_xxcu_trw[i].trw_afar == afar) + return (&cmd.cmd_xxcu_trw[i]); + } + } else { + for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { if (cmd.cmd_xxcu_trw[i].trw_ena == ena) return (&cmd.cmd_xxcu_trw[i]); + } } - return (NULL); } cmd_xxcu_trw_t * -cmd_trw_alloc(uint64_t ena) +cmd_trw_alloc(uint64_t ena, uint64_t afar) { int i; @@ -1262,6 +1272,7 @@ cmd_trw_alloc(uint64_t ena) cmd_xxcu_trw_t *trw = &cmd.cmd_xxcu_trw[i]; if (trw->trw_ena == NULL) { trw->trw_ena = ena; + trw->trw_afar = afar; return (trw); } } diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h index c9ff6ac050..5c88d6cc4c 100644 --- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h +++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h @@ -205,6 +205,7 @@ extern void cmd_cpu_uec_set_allmatch(fmd_hdl_t *, cmd_cpu_t *); typedef struct cmd_xxcu_trw { uint64_t trw_ena; /* the ENA for this group of ereports */ + uint64_t trw_afar; /* the AFAR for this group of ereports */ cmd_errcl_t trw_mask; /* ereports seen thus far with this ENA */ uint16_t trw_cpuid; /* CPU to which this watcher belongs */ uint8_t trw_ref; /* number of ereports with this ENA */ @@ -212,8 +213,8 @@ typedef struct cmd_xxcu_trw { uint32_t trw_pad; } cmd_xxcu_trw_t; -extern cmd_xxcu_trw_t *cmd_trw_lookup(uint64_t); -extern cmd_xxcu_trw_t *cmd_trw_alloc(uint64_t); +extern cmd_xxcu_trw_t *cmd_trw_lookup(uint64_t, uint8_t, uint64_t); +extern cmd_xxcu_trw_t *cmd_trw_alloc(uint64_t, uint64_t); extern void cmd_trw_restore(fmd_hdl_t *); extern void cmd_trw_write(fmd_hdl_t *); extern void cmd_trw_ref(fmd_hdl_t *, cmd_xxcu_trw_t *, cmd_errcl_t); @@ -663,6 +664,9 @@ extern int cmd_cpu_synd_check(uint16_t); extern int cmd_cpu_synd_check(uint32_t); #endif /* sun4u */ +extern int cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t, + uint64_t *afar); + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c index 65effd3def..4e1891898e 100644 --- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c +++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c @@ -352,9 +352,17 @@ cmd_xxcu_resolve(fmd_hdl_t *hdl, cmd_xr_t *xr, fmd_event_t *ep, { cmd_xxcu_trw_t *trw; cmd_errcl_t cause; + uint64_t afar; - if ((trw = cmd_trw_lookup(xr->xr_ena)) == NULL) { - hdlr(hdl, xr, ep); + + afar = NULL; + + if (xr->xr_afar_status == AFLT_STAT_VALID) + afar = xr->xr_afar; + + if ((trw = cmd_trw_lookup(xr->xr_ena, + xr->xr_afar_status, afar)) == NULL) { + fmd_hdl_debug(hdl, "cmd_trw_lookup: Not found\n"); return; } @@ -414,7 +422,9 @@ cmd_xxcu_initial(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, cmd_cpu_t *cpu; cmd_xr_t *xr; uint64_t ena; + uint64_t afar; uint8_t level = clcode & CMD_ERRCL_LEVEL_EXTRACT; + uint8_t afar_status; clcode &= CMD_ERRCL_LEVEL_MASK; /* keep level bits out of train masks */ @@ -428,11 +438,21 @@ cmd_xxcu_initial(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, (void) nvlist_lookup_uint64(nvl, FM_EREPORT_ENA, &ena); + if (cmd_afar_valid(hdl, nvl, clcode, &afar) != 0) { + afar_status = AFLT_STAT_INVALID; + afar = NULL; + } else { + afar_status = AFLT_STAT_VALID; + } + fmd_hdl_debug(hdl, "scheduling %s (%llx) for redelivery\n", class, clcode); + fmd_hdl_debug(hdl, "looking up ena %llx,afar %llx with\n", ena, afar); + + fmd_hdl_debug(hdl, "afar status of %02x\n", afar_status); - if ((trw = cmd_trw_lookup(ena)) == NULL) { - if ((trw = cmd_trw_alloc(ena)) == NULL) { + if ((trw = cmd_trw_lookup(ena, afar_status, afar)) == NULL) { + if ((trw = cmd_trw_alloc(ena, afar)) == NULL) { fmd_hdl_debug(hdl, "failed to get new trw\n"); goto redeliver; } diff --git a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c index 9f07d1b878..7ae7fae7b9 100644 --- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c +++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -79,3 +78,20 @@ cmd_cpu_synd_check(uint16_t synd) else return (0); } +int +cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t clcode, + uint64_t *afar) +{ + uint8_t afar_status; + + if (nvlist_lookup_uint8(nvl, + FM_EREPORT_PAYLOAD_NAME_AFAR_STATUS, &afar_status) == 0) { + if (afar_status == AFLT_STAT_VALID) { + (void) nvlist_lookup_uint64(nvl, + FM_EREPORT_PAYLOAD_NAME_AFAR, afar); + return (0); + } else + return (-1); + } + return (-1); +} diff --git a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c index 6fa9378c69..1e2361c482 100644 --- a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c +++ b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,6 +44,8 @@ #include <sys/fm/cpu/UltraSPARC-T1.h> #include <sys/niagararegs.h> +int cmd_afsr_check(fmd_hdl_t *, uint64_t, cmd_errcl_t, uint8_t *); + int cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode) { @@ -60,6 +61,42 @@ cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode) &xr->xr_synd) != 0) return (-1); + if (cmd_afsr_check(hdl, niagara_l2_afsr, clcode, + &xr->xr_synd_status) != 0) + return (-1); + + xr->xr_afar_status = xr->xr_synd_status; + return (0); +} + +int +cmd_cpu_synd_check(uint32_t synd) +{ + int i; + + /* + * Niagara L2 fetches from a memory location containing a UE + * are given a poison syndrome in one or more 7 bit subsyndromes + * each covering one of 4 4 byte checkwords. + * + * 0 is an invalid syndrome because it denotes no error, but + * is associated with an ereport -- meaning there WAS an error. + */ + if (synd == 0) + return (-1); + + for (i = 0; i < 4; i++) { + if (((synd >> i*NI_L2_POISON_SYND_SIZE) & + NI_L2_POISON_SYND_MASK) == NI_L2_POISON_SYND_FROM_DAU) + return (-1); + } + return (0); +} + +int +cmd_afsr_check(fmd_hdl_t *hdl, uint64_t afsr, + cmd_errcl_t clcode, uint8_t *stat_val) +{ /* * Set Niagara afar and synd validity. * For a given set of error registers, the payload value is valid iff @@ -69,65 +106,61 @@ cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode) switch (clcode) { case CMD_ERRCL_LDAU: case CMD_ERRCL_LDSU: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P02) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P02) == 0) ? + AFLT_STAT_VALID: AFLT_STAT_INVALID; break; case CMD_ERRCL_LDWU: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P03) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P03) == 0) ? + AFLT_STAT_VALID : AFLT_STAT_INVALID; break; case CMD_ERRCL_LDRU: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P04) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P04) == 0) ? + AFLT_STAT_VALID : AFLT_STAT_INVALID; break; case CMD_ERRCL_LDAC: case CMD_ERRCL_LDSC: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P07) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P07) == 0) ? + AFLT_STAT_VALID : AFLT_STAT_INVALID; break; case CMD_ERRCL_LDWC: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P08) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P08) == 0) ? + AFLT_STAT_VALID : AFLT_STAT_INVALID; break; case CMD_ERRCL_LDRC: - xr->xr_synd_status = - ((niagara_l2_afsr & NI_L2AFSR_P09) == 0) ? - AFLT_STAT_VALID : AFLT_STAT_INVALID; + *stat_val = + ((afsr & NI_L2AFSR_P09) == 0) ? + AFLT_STAT_VALID : AFLT_STAT_INVALID; break; default: fmd_hdl_debug(hdl, "Niagara unrecognized l2cache error\n"); - xr->xr_synd_status = 0; return (-1); } - xr->xr_afar_status = xr->xr_synd_status; return (0); } + int -cmd_cpu_synd_check(uint32_t synd) +cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t clcode, + uint64_t *afar) { - int i; + uint64_t niagara_l2_afsr = 0; + uint8_t stat_val; + if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_AFSR, + &niagara_l2_afsr) != 0) + return (-1); - /* - * Niagara L2 fetches from a memory location containing a UE - * are given a poison syndrome in one or more 7 bit subsyndromes - * each covering one of 4 4 byte checkwords. - * - * 0 is an invalid syndrome because it denotes no error, but - * is associated with an ereport -- meaning there WAS an error. - */ - if (synd == 0) + if (cmd_afsr_check(hdl, niagara_l2_afsr, clcode, &stat_val) != 0) return (-1); - for (i = 0; i < 4; i++) { - if (((synd >> i*NI_L2_POISON_SYND_SIZE) & - NI_L2_POISON_SYND_MASK) == NI_L2_POISON_SYND_FROM_DAU) - return (-1); + if (stat_val == AFLT_STAT_VALID) { + if (nvlist_lookup_uint64(nvl, + FM_EREPORT_PAYLOAD_NAME_L2_REAL_AFAR, afar) == 0) + return (0); } - return (0); + return (-1); } |