7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER START
7bebe46c240b554f47faeed19186123896281967jc * The contents of this file are subject to the terms of the
7bebe46c240b554f47faeed19186123896281967jc * Common Development and Distribution License (the "License").
7bebe46c240b554f47faeed19186123896281967jc * You may not use this file except in compliance with the License.
7bebe46c240b554f47faeed19186123896281967jc * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7bebe46c240b554f47faeed19186123896281967jc * See the License for the specific language governing permissions
7bebe46c240b554f47faeed19186123896281967jc * and limitations under the License.
7bebe46c240b554f47faeed19186123896281967jc * When distributing Covered Code, include this CDDL HEADER in each
7bebe46c240b554f47faeed19186123896281967jc * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7bebe46c240b554f47faeed19186123896281967jc * If applicable, add the following below this CDDL HEADER, with the
7bebe46c240b554f47faeed19186123896281967jc * fields enclosed by brackets "[]" replaced with your own identifying
7bebe46c240b554f47faeed19186123896281967jc * information: Portions Copyright [yyyy] [name of copyright owner]
7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER END
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7bebe46c240b554f47faeed19186123896281967jc * Use is subject to license terms.
7bebe46c240b554f47faeed19186123896281967jc * Support routines for managing per-Lxcache state.
7bebe46c240b554f47faeed19186123896281967jc * These values are our threshold values for SERDing CPU's based on the
7bebe46c240b554f47faeed19186123896281967jc * the # of times we have retired a cache line for each category.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int8_t cmd_lowest_way[16] = {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int cmd_num_of_bits[16] = {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_write(fmd_hdl_t *hdl, cmd_Lxcache_t *Lxcache)
7bebe46c240b554f47faeed19186123896281967jc fmd_buf_write(hdl, NULL, Lxcache->Lxcache_bufname, Lxcache,
d69c2551e89e9440043ac6ff5739b58746286f33jc switch (pstype) {
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l2data");
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l3data");
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l2tag");
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l3tag");
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("unknown");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("ACTIVE");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("FAULTING");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("RETIRED");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("UNRETIRED");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("RERETIRED");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("Unknown_flags");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("SUSPECT_DATA");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("SUSPECT_0_TAG");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("SUSPECT_1_TAG");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("CONVICTED");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("FUNCTIONING");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return ("Unknown_reason");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_pretty_print_Lxcache(fmd_hdl_t *hdl, cmd_Lxcache_t *Lxcache)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " reason = %s\n"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " flags = %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_type_to_str(Lxcache->Lxcache_type),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_reason_to_str(Lxcache->Lxcache_reason),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_flags_to_str(Lxcache->Lxcache_flags));
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_free(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache,
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "Entering cmd_Lxcache_free for %s destroy = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian nvlist_free(Lxcache->Lxcache_nvl);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Clean up the SERD engine created to handle recheck of TAGS.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * This SERD engine was created to save the event pointer.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_serdnm != NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (fmd_serd_exists(hdl, Lxcache->Lxcache_serdnm) && destroy) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_serd_destroy(hdl, Lxcache->Lxcache_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_strfree(hdl, Lxcache->Lxcache_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count = 0;
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_destroy(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_lookup_by_type_index_way_bit(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t pstype, int32_t index, int8_t way, int16_t bit)
7bebe46c240b554f47faeed19186123896281967jc for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches); Lxcache != NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (Lxcache->Lxcache_index == (uint32_t)index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (Lxcache->Lxcache_way == (uint32_t)way) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (Lxcache->Lxcache_bit == (uint16_t)bit))
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_create(fmd_hdl_t *hdl, cmd_xr_t *xr, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian nvlist_t *modasru, cmd_ptrsubtype_t pstype, int32_t index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian pstype_name = cmd_type_to_str(pstype);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:Creating new Lxcache for index=%d way=%d bit=%d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian pstype_name, cpu->cpu_cpuid, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc Lxcache = fmd_hdl_zalloc(hdl, sizeof (cmd_Lxcache_t), FMD_SLEEP);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index = (uint32_t)index;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_way = (uint32_t)way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_bit = (uint16_t)bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_flags = CMD_LxCACHE_F_ACTIVE;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retired_fmri[0] = '\0';
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc cmd_bufname(Lxcache->Lxcache_bufname, sizeof (Lxcache->Lxcache_bufname),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "Lxcache_%s_%d_%d_%d_%d", pstype_name, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: new Lxcache name is %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian pstype_name, cpu->cpu_cpuid, Lxcache->Lxcache_bufname);
7bebe46c240b554f47faeed19186123896281967jc (errno = nvlist_add_uint32(asru, FM_FMRI_CPU_CACHE_INDEX,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian asru->nvl_nvflag |= NV_UNIQUE_NAME_TYPE;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "%s_asru_%d_%d_%d", pstype_name, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_lookup_by_index_way(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cache->Lxcache_index == (uint32_t)index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cache->Lxcache_way == (uint32_t)way) &&
7bebe46c240b554f47faeed19186123896281967jcLxcache_wrapv1(fmd_hdl_t *hdl, cmd_Lxcache_pers_t *pers, size_t psz)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "size of state doesn't match size of "
7bebe46c240b554f47faeed19186123896281967jc "version 1 state (%u bytes).\n",
7bebe46c240b554f47faeed19186123896281967jc Lxcache = fmd_hdl_zalloc(hdl, sizeof (cmd_Lxcache_t), FMD_SLEEP);
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
7bebe46c240b554f47faeed19186123896281967jc * We need to first extract the cpu name by reading directly
7bebe46c240b554f47faeed19186123896281967jc * from fmd buffers in order to begin our search for Lxcache in
7bebe46c240b554f47faeed19186123896281967jc * the appropriate cpu list.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * After we identify the cpu list using buf name we look
7bebe46c240b554f47faeed19186123896281967jc * in cpu list for our Lxcache states.
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "restoring Lxcache from %s\n", ptr->ptr_name);
7bebe46c240b554f47faeed19186123896281967jc if ((Lxcachesz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
7bebe46c240b554f47faeed19186123896281967jc "not exist in saved state\n",
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "Lxcache buffer referenced by case %s "
7bebe46c240b554f47faeed19186123896281967jc "is %d bytes. Expected size is %d bytes\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_pretty_print_Lxcache(hdl, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc cpu = cmd_restore_cpu_only(hdl, cp, Lxcache->Lxcache_cpu_bufname);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\nCould not restore cpu %s\n",
7bebe46c240b554f47faeed19186123896281967jc recovered_Lxcache = Lxcache; /* save the recovered Lxcache */
7bebe46c240b554f47faeed19186123896281967jc for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches); Lxcache != NULL;
7bebe46c240b554f47faeed19186123896281967jc if (strcmp(Lxcache->Lxcache_bufname, ptr->ptr_name) == 0)
7bebe46c240b554f47faeed19186123896281967jc "for Lxcache state referenced by case %s.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to cleanup the information associated with
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the timeout routine because these are not checkpointed
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * and cannot be retored.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count = 0;
7bebe46c240b554f47faeed19186123896281967jc "cpu_id %d: serdname for the case is %s\n",
7bebe46c240b554f47faeed19186123896281967jc "cpu_id %d: restoring the case for index %d way %d bit %d\n",
7bebe46c240b554f47faeed19186123896281967jc cmd_case_restore(hdl, &Lxcache->Lxcache_case, cp, serdnm);
7bebe46c240b554f47faeed19186123896281967jc/*ARGSUSED*/
7bebe46c240b554f47faeed19186123896281967jc if (fmd_nvl_fmri_unusable(hdl, Lxcache->Lxcache_asru_nvl)) {
7bebe46c240b554f47faeed19186123896281967jc /* No need to rewrite the FMRIs in the Lxcache - they don't change */
7bebe46c240b554f47faeed19186123896281967jc while ((Lxcache = cmd_list_next(&cpu->cpu_Lxcaches)) != NULL)
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_serdnm_create(fmd_hdl_t *hdl, uint32_t cpu_id,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index, int8_t way, int16_t bit)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fmt = "cpu_%d:%s_%d_%d_%d_serd";
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian serdbase = cmd_type_to_str(pstype);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian sz = (snprintf(NULL, 0, fmt, cpu_id, serdbase, index, way, bit) + 1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) snprintf(nm, sz, fmt, cpu_id, serdbase, index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_anonymous_serdnm_create(fmd_hdl_t *hdl, uint32_t cpu_id,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index, int8_t way, int16_t bit)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fmt = "cpu_%d:%s_%d_%d_%d_anonymous_serd";
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian serdbase = cmd_type_to_str(pstype);
7bebe46c240b554f47faeed19186123896281967jc sz = (snprintf(NULL, 0, fmt, cpu_id, serdbase, index, way, bit) + 1);
7bebe46c240b554f47faeed19186123896281967jc (void) snprintf(nm, sz, fmt, cpu_id, serdbase, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc return (nm);
7bebe46c240b554f47faeed19186123896281967jc * Count the number of SERD type 2 ways retired for a given cpu
7bebe46c240b554f47faeed19186123896281967jc * These are defined to be L3 Cache data retirements
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cache->Lxcache_flags & CMD_LxCACHE_F_RETIRED) &&
7bebe46c240b554f47faeed19186123896281967jc * Count the number of SERD type 1 ways retired for a given cpu
7bebe46c240b554f47faeed19186123896281967jc * These are defined to be L2 Data, tag and L3 Tag retirements
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cache->Lxcache_flags & CMD_LxCACHE_F_RETIRED) &&
7bebe46c240b554f47faeed19186123896281967jccmd_fault_the_cpu(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc const char *fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Created case %s to retire CPU\n",
7bebe46c240b554f47faeed19186123896281967jc if ((errno = fmd_nvl_fmri_expand(hdl, cpu->cpu_asru_nvl)) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_cpu_create_faultlist(hdl, cp, cpu, fltnm, NULL, HUNDRED_PERCENT);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_retire_cpu_if_limits_exceeded(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t pstype, const char *fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /* Retrieve the number of retired ways for each category */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu_retired_1 = cmd_Lx_index_count_type1_ways(cpu);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu_retired_2 = cmd_Lx_index_count_type2_ways(cpu);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:CPU %d retired Type 1 way count is: %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, cpu_retired_1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "\n%s:CPU %d retired Type 2 way count is: %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, cpu_retired_2);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (((cpu_retired_1 > CMD_CPU_SERD_AGG_1) ||
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cpu_retired_2 > CMD_CPU_SERD_AGG_2)) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cpu->cpu_faulting != FMD_B_TRUE)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, pstype, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_fault(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fltnm, nvlist_t *rsrc, uint_t cert)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) snprintf(fltmsg, sizeof (fltmsg), "fault.cpu.%s.%s-line",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_cpu_type2name(hdl, cpu->cpu_type), fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: fltmsg = %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian flt = fmd_nvl_create_fault(hdl, fltmsg, cert,
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_add_boolean_value(flt, FM_SUSPECT_MESSAGE, B_FALSE) != 0)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to add no-message member to fault");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: adding suspect list to case %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_case_uuid(hdl, Lxcache->Lxcache_case.cc_cp));
7bebe46c240b554f47faeed19186123896281967jc fmd_case_add_suspect(hdl, Lxcache->Lxcache_case.cc_cp, flt);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_fmri_nvl2str(hdl, Lxcache->Lxcache_asru.fmri_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: Failed to save the"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired fmri string\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu_id %d:Saved the retired fmri string %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_flags &= ~(CMD_LxCACHE_F_FAULTING);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "cmd_Lxcache_close called for %s\n",
7bebe46c240b554f47faeed19186123896281967jc * We will destroy the case and serd engine.
7bebe46c240b554f47faeed19186123896281967jc * The rest will be destroyed when we retire the CPU
7bebe46c240b554f47faeed19186123896281967jc * until then we keep the Lxcache strutures alive.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_lookup_by_timeout_id(id_t id)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache->Lxcache_timeout_id == id)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index, uint64_t *tag_data)
7bebe46c240b554f47faeed19186123896281967jc "cpu_id = %d could not open %s to read tag info.\n",
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc if (ioctl(fd, MEM_CACHE_READ_ERROR_INJECTED_TAGS, &cache_info)
7bebe46c240b554f47faeed19186123896281967jc " MEM_CACHE_READ_ERROR_INJECTED_TAGS failed"
7bebe46c240b554f47faeed19186123896281967jc " errno = %d\n",
7bebe46c240b554f47faeed19186123896281967jc " MEM_CACHE_READ_TAGS failed"
7bebe46c240b554f47faeed19186123896281967jc " errno = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianget_index_retired_ways(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype, int32_t index)
7bebe46c240b554f47faeed19186123896281967jc return (-1);
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_cache_way_retire(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d open of %s failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu %d: Retiring index %d, way %d bit %d\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d MEM_CACHE_RETIRE ioctl failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_cache_way_unretire(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d open of %s failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu %d: Unretiring index %d, way %d bit %d\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d MEM_CACHE_UNRETIRE ioctl failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_Lxcache_lookup_by_type_index_way_flags(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t type, int32_t index, int8_t way, int32_t flags)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_get_bit_array_of_available_ways(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t type, int32_t index)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t bit_array_of_unavailable_ways;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t bit_array_of_available_ways;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t bit_array_of_retired_ways;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We scan the Lxcache structures for this CPU and collect
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the following 2 information.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - bit_array_of_retired_ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - bit_array_of_unavailable_ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If type is Lx_TAG then unavailable_ways will not include ways that
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * were retired due to DATA faults, because these ways can still be
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * re-retired for TAG faults.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If 3 ways have been retired then we protect the only remaining
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretired way by marking it as unavailable.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_unavailable_ways = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cmd_Lxcache->Lxcache_index == index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ((cmd_Lxcache->Lxcache_type == type) ||
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_type == match_type)) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (CMD_LxCACHE_F_RETIRED | CMD_LxCACHE_F_RERETIRED))) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If we are calling this while handling TAG errors
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we can reretire the cachelines retired due to DATA
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * errors. We will ignore the cachelnes that are
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired due to DATA faults.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((type == CMD_PTR_CPU_L2TAG) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L2DATA))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((type == CMD_PTR_CPU_L3TAG) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L3DATA))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_num_of_bits[bit_array_of_retired_ways & 0xf] == 3) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * special case: 3 ways are already retired.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The Lone unretired way is set as 1, rest are set as 0.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We now OR this with bit_array_of_unavailable_ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * so that this unretired way will not be allocated.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_retired_ways ^= 0xf;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_retired_ways &= 0xf;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_unavailable_ways |= bit_array_of_retired_ways;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ((bit_array_of_unavailable_ways ^ 0xf) & 0xf);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (bit_array_of_available_ways);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Look for a way next to the specified way that is
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * not in a retired state.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We stop when way 3 is reached.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_get_next_retirable_way(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index, cmd_ptrsubtype_t pstype, int8_t specified_way)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_ways = cmd_Lxcache_get_bit_array_of_available_ways(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_lowest_way[bit_array_of_ways & mask]);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_get_lowest_retirable_way(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index, cmd_ptrsubtype_t pstype)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit_array_of_ways = cmd_Lxcache_get_bit_array_of_available_ways(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_lowest_way[bit_array_of_ways]);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_lookup_by_type_index_way_reason(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t pstype, int32_t index, int8_t way, int32_t reason)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cmd_Lxcache->Lxcache_index == (uint32_t)index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_way == (uint32_t)way) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_reason & reason) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_type == pstype)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_lookup_by_type_index_bit_reason(cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t pstype, int32_t index, int16_t bit, int32_t reason)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cmd_Lxcache->Lxcache_index == (uint32_t)index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_bit == (uint16_t)bit) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_reason & reason) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_type == pstype)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_destroy_anonymous_serd_engines(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t type, int32_t index, int16_t bit)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((cmd_Lxcache->Lxcache_type == type) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_index == (uint32_t)index) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_bit == (uint16_t)bit) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache->Lxcache_way == (uint32_t)CMD_ANON_WAY)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (fmd_serd_exists(hdl, cc->cc_serdnm)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d destroying SERD"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_serd_destroy(hdl, cc->cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_strfree(hdl, cc->cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_fmri_nvl2str(fmd_hdl_t *hdl, nvlist_t *nvl, char *buf, size_t buflen)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_ID);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &serstr) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_SERIAL_ID);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_CACHE_INDEX, &index) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_CACHE_INDEX);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_CACHE_WAY, &way) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_CACHE_WAY);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint16(nvl, FM_FMRI_CPU_CACHE_BIT, &bit) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_CACHE_BIT);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint8(nvl, FM_FMRI_CPU_CACHE_TYPE, &type) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) strcat(missing_list, FM_FMRI_CPU_CACHE_TYPE);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\ncmd_fmri_nvl2str: missing %s in fmri\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "cpu:///%s=%u/%s=%s/%s=%u/%s=%u/%s=%d/%s=%d",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_create_case_for_Lxcache(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache->Lxcache_case.cc_cp != NULL)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache->Lxcache_case.cc_cp = cmd_case_create(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &cmd_Lxcache->Lxcache_header, CMD_PTR_LxCACHE_CASE,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm = cmd_type_to_str(cmd_Lxcache->Lxcache_type);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache->Lxcache_case.cc_cp == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:Failed to create a case for"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " index %d way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache->Lxcache_way, cmd_Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: New case %s created.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_case_add_ereport(hdl, cmd_Lxcache->Lxcache_case.cc_cp,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_repair_fmri(fmd_hdl_t *hdl, char *buf)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "Failed to repair %s err = %d\n", buf, err);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_unretire(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *unretire_this_Lxcache, const char *fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *previously_retired_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int found_reretired_cacheline = 0;
d69c2551e89e9440043ac6ff5739b58746286f33jc * If we are unretiring a cacheline retired due to suspected TAG
d69c2551e89e9440043ac6ff5739b58746286f33jc * fault, then we must first check if we are using a cacheline
d69c2551e89e9440043ac6ff5739b58746286f33jc * that was retired earlier for DATA fault.
d69c2551e89e9440043ac6ff5739b58746286f33jc * If so we will not unretire the cacheline.
d69c2551e89e9440043ac6ff5739b58746286f33jc * We will change the flags to reflect the current condition.
d69c2551e89e9440043ac6ff5739b58746286f33jc * We will return success, though.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (IS_TAG(unretire_this_Lxcache->Lxcache_type)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (unretire_this_Lxcache->Lxcache_type == CMD_PTR_CPU_L2TAG)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (unretire_this_Lxcache->Lxcache_type == CMD_PTR_CPU_L3TAG)
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d checking if there is a %s"
d69c2551e89e9440043ac6ff5739b58746286f33jc " cacheline re-retired at this index %d and way %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_lookup_by_type_index_way_flags(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, data_type, unretire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_way,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (previously_retired_Lxcache) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Found a %s cacheline re-retired at"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " this index %d and way %d. Will mark this"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, cmd_type_to_str(data_type),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We call the cmd_Lxcache_fault to inform fmd
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * about the suspect fmri. The cacheline is already
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired but the existing suspect fmri is for TAG
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * fault which will be removed in this routine.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (previously_retired_Lxcache->Lxcache_reason
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_fault(hdl, cpu, previously_retired_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_fru_nvl, certainty);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian previously_retired_Lxcache->Lxcache_flags =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Update persistent storage
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_write(hdl, previously_retired_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We have been called to unretire a cacheline retired
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * earlier due to DATA errors.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If this cacheline is marked RERETIRED then it means that
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the cacheline has been retired due to TAG errors and
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we should not be unretiring the cacheline.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (unretire_this_Lxcache->Lxcache_flags &
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d The cacheline at index %d and"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way %d which we are attempting to unretire"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " is in RERETIRED state. Therefore we will not"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " unretire it but will mark it as RETIRED.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * if we did not find a RERETIRED cacheline above
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretire the cacheline.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (!found_reretired_cacheline) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_cache_way_unretire(hdl, cpu, unretire_this_Lxcache)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_flags = CMD_LxCACHE_F_UNRETIRED;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We have exonerated the cacheline. We need to inform the fmd
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that we have repaired the suspect fmri that we retired earlier.
d69c2551e89e9440043ac6ff5739b58746286f33jc * The cpumem agent will not unretire cacheline in response to
d69c2551e89e9440043ac6ff5739b58746286f33jc * the list.repair events it receives.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (unretire_this_Lxcache->Lxcache_retired_fmri[0] != 0) {
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d Repairing the retired fmri %s",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_retired_fmri);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_retired_fmri) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Failed to repair retired fmri.",
d69c2551e89e9440043ac6ff5739b58746286f33jc * We need to retire the cacheline that we just
d69c2551e89e9440043ac6ff5739b58746286f33jc * unretired.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_cache_way_retire(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache) == B_FALSE) {
d69c2551e89e9440043ac6ff5739b58746286f33jc * A hopeless situation.
d69c2551e89e9440043ac6ff5739b58746286f33jc * cannot maintain consistency of cacheline
d69c2551e89e9440043ac6ff5739b58746286f33jc * sate between fmd and DE.
d69c2551e89e9440043ac6ff5739b58746286f33jc * Aborting the DE.
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d We are unable to repair"
d69c2551e89e9440043ac6ff5739b58746286f33jc " the fmri we just unretired and are"
d69c2551e89e9440043ac6ff5739b58746286f33jc " unable to restore the DE and fmd to"
d69c2551e89e9440043ac6ff5739b58746286f33jc " a sane state.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian unretire_this_Lxcache->Lxcache_retired_fmri[0] = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_retire(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *retire_this_Lxcache, const char *fltnm, uint_t cert)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *previously_retired_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: cmd_Lxcache_retire called for index %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way, retire_this_Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (fmd_case_solved(hdl, retire_this_Lxcache->Lxcache_case.cc_cp)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Case solved implies that the cache line is already
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired as SUSPECT_0_TAG and we are here to retire this
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * as SUSPECT_1_TAG.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We will first repair the retired cacheline
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * so that it does not get retired during replay for
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If we are able to repair the retired cacheline we close the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * case and open a new case for it.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (retire_this_Lxcache->Lxcache_reason !=
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: Unexpected condition encountered."
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " Expected the reason for retirement as"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " SUSPECT_0_TAG however found the reason"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_reason));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: We are re-retiring SUSPECT_0_TAG as"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " SUSPECT_1_TAG index %d way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: The existing case for this Lxcache has"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " has been already solved. We will first repair the suspect"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cacheline and if we are successful then close this case,"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " and open a new case.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * repair the retired cacheline.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (retire_this_Lxcache->Lxcache_retired_fmri[0] != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Repairing the retired suspect"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cacheline %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_retired_fmri);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_retired_fmri) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Failed to repair the"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired fmri.",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_retired_fmri[0] =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_case.cc_cp);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d: Closing the case %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_case_fini(hdl, retire_this_Lxcache->Lxcache_case.cc_cp,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_case.cc_cp = NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_create_case_for_Lxcache(hdl, cpu, retire_this_Lxcache)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Not a SUSPECT_0_TAG.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We should be entering this path if the cacheline is
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * transitioning from ACTIVE/UNRETIRED to RETIRED state.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If the cacheline state is not as expected we print debug
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * message and return failure.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((retire_this_Lxcache->Lxcache_flags !=
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (retire_this_Lxcache->Lxcache_flags
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Unexpected condition.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:Unexpected state %s for the"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cacheline at index %d way %d encountered.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_flags),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) cmd_fmri_nvl2str(hdl, retire_this_Lxcache->Lxcache_asru.fmri_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_list, sizeof (suspect_list));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:current suspect list is %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, suspect_list);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_fault(hdl, cpu, retire_this_Lxcache, fltnm,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_flags = CMD_LxCACHE_F_RETIRED;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (IS_TAG(retire_this_Lxcache->Lxcache_type)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If the cacheline we just retired was retired earlier
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * due to DATA faults we mark the Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * corresponding to DATA as RERETIRED.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (retire_this_Lxcache->Lxcache_type == CMD_PTR_CPU_L2TAG)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (retire_this_Lxcache->Lxcache_type == CMD_PTR_CPU_L3TAG)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d checking if there is a %s"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cacheline retired at this index %d way %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_lookup_by_type_index_way_flags(cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian data_type, retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way, CMD_LxCACHE_F_RETIRED);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (previously_retired_Lxcache) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: Found index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired earlier. Will mark this Lxcache"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " as RERETIRED.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retire_this_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * First repair the retired cacheline and if successful
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * close the existing case and create a new case.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * This cacheline has already been retired for
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Repair the previously retired DATA fault cacheline so
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that it does not get retired by fmd during replay.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (previously_retired_Lxcache->Lxcache_retired_fmri[0]
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Repairing the cacheline"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired due to data errors. %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpuid %d Failed to repair the"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired fmri.",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian previously_retired_Lxcache->Lxcache_case.cc_cp,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian previously_retired_Lxcache->Lxcache_case.cc_cp = NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian previously_retired_Lxcache->Lxcache_flags =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Update persistent storage
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_write(hdl, previously_retired_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Create a new case so that this Lxcache structure
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * gets restored on replay.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_create_case_for_Lxcache(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian previously_retired_Lxcache) == B_FALSE)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_retire_cpu_if_limits_exceeded(hdl, cpu,