summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgavinm <none@none>2006-04-10 16:52:08 -0700
committergavinm <none@none>2006-04-10 16:52:08 -0700
commit52d60c845b4569ed1f136c204372e7e5a3535239 (patch)
treeee261c3fd4b3cf525210e56ff134fc6e01d93aaf
parentd8260c5137b0926a897a3763eca8997922ad7401 (diff)
downloadillumos-joyent-52d60c845b4569ed1f136c204372e7e5a3535239.tar.gz
6390211 amd64 panicsys() is always called with on_panic_stack == 1
6406417 ereport_size not big enough for nvlist bloat
-rw-r--r--usr/src/uts/common/sys/fm/util.h9
-rw-r--r--usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c37
-rw-r--r--usr/src/uts/intel/ia32/ml/i86_subr.s11
3 files changed, 44 insertions, 13 deletions
diff --git a/usr/src/uts/common/sys/fm/util.h b/usr/src/uts/common/sys/fm/util.h
index 33f5876cab..4934814d86 100644
--- a/usr/src/uts/common/sys/fm/util.h
+++ b/usr/src/uts/common/sys/fm/util.h
@@ -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.
@@ -56,8 +55,8 @@ extern "C" {
* same representation for *both* 32-bit and 64-bit producers and consumers.
*/
#define ERPT_MAGIC 0xf00d4eddU
-#define ERPT_MAX_ERRS 32
-#define ERPT_DATA_SZ (3 * 1024)
+#define ERPT_MAX_ERRS 16
+#define ERPT_DATA_SZ (6 * 1024)
#define ERPT_EVCH_MAX 256
#define ERPT_HIWAT 64
diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c
index 533e5c82f6..656eb19f6d 100644
--- a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c
+++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c
@@ -490,7 +490,7 @@ ao_ereport_create_resource_elem(nvlist_t **nvlp, nv_alloc_t *nva,
"memory-controller", unump->unum_mc,
"dimm", unump->unum_dimms[dimmnum]);
- fm_nvlist_destroy(snvl, FM_NVA_FREE);
+ fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
}
static void
@@ -512,7 +512,7 @@ ao_ereport_add_resource(nvlist_t *payload, nv_alloc_t *nva, mc_unum_t *unump)
DATA_TYPE_NVLIST_ARRAY, nelems, elems, NULL);
for (i = 0; i < nelems; i++)
- fm_nvlist_destroy(elems[i], FM_NVA_FREE);
+ fm_nvlist_destroy(elems[i], nva ? FM_NVA_RETAIN : FM_NVA_FREE);
}
static void
@@ -595,7 +595,7 @@ ao_ereport_post(const ao_cpu_logout_t *acl,
int bankno, const ao_error_disp_t *aed)
{
ao_data_t *ao = acl->acl_ao;
- errorq_elem_t *eqep;
+ errorq_elem_t *eqep, *scr_eqep;
nvlist_t *ereport, *detector;
nv_alloc_t *nva = NULL;
char buf[FM_MAX_CLASS];
@@ -604,9 +604,23 @@ ao_ereport_post(const ao_cpu_logout_t *acl,
if ((eqep = errorq_reserve(ereport_errorq)) == NULL)
return;
ereport = errorq_elem_nvl(ereport_errorq, eqep);
- nva = errorq_elem_nva(ereport_errorq, eqep);
+
+ /*
+ * Now try to allocate another element for scratch space and
+ * use that for further scratch space (eg for constructing
+ * nvlists to add the main ereport). If we can't reserve
+ * a scratch element just fallback to working within the
+ * element we already have, and hope for the best. All this
+ * is necessary because the fixed buffer nv allocator does
+ * not reclaim freed space and nvlist construction is
+ * expensive.
+ */
+ if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL)
+ nva = errorq_elem_nva(ereport_errorq, scr_eqep);
+ else
+ nva = errorq_elem_nva(ereport_errorq, eqep);
} else {
- ereport = fm_nvlist_create(nva);
+ ereport = fm_nvlist_create(NULL);
}
/*
@@ -625,16 +639,27 @@ ao_ereport_post(const ao_cpu_logout_t *acl,
FM_ENA_FMT1), detector, NULL);
/*
+ * We're done with 'detector' so reclaim the scratch space.
+ */
+ if (panicstr) {
+ fm_nvlist_destroy(detector, FM_NVA_RETAIN);
+ nv_alloc_reset(nva);
+ } else {
+ fm_nvlist_destroy(detector, FM_NVA_FREE);
+ }
+
+ /*
* Encode the error-specific data that was saved in the logout area.
*/
ao_ereport_add_logout(ao, ereport, nva, acl, bankno, aed);
if (panicstr) {
errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC);
+ if (scr_eqep)
+ errorq_cancel(ereport_errorq, scr_eqep);
} else {
(void) fm_ereport_post(ereport, EVCH_TRYHARD);
fm_nvlist_destroy(ereport, FM_NVA_FREE);
- fm_nvlist_destroy(detector, FM_NVA_FREE);
}
}
diff --git a/usr/src/uts/intel/ia32/ml/i86_subr.s b/usr/src/uts/intel/ia32/ml/i86_subr.s
index 61a7429fe4..6d9709945b 100644
--- a/usr/src/uts/intel/ia32/ml/i86_subr.s
+++ b/usr/src/uts/intel/ia32/ml/i86_subr.s
@@ -3155,7 +3155,14 @@ dtrace_vpanic(const char *format, va_list alist)
call panic_trigger /* %eax = panic_trigger() */
vpanic_common:
- cmpl $0, %eax
+ /*
+ * The panic_trigger result is in %eax from the call above, and
+ * dtrace_panic places it in %eax before branching here.
+ * The rdmsr instructions that follow below will clobber %eax so
+ * we stash the panic_trigger result in %r11d.
+ */
+ movl %eax, %r11d
+ cmpl $0, %r11d
je 0f
/*
@@ -3243,7 +3250,7 @@ vpanic_common:
movq REGOFF_RDI(%rsp), %rdi /* format */
movq REGOFF_RSI(%rsp), %rsi /* alist */
movq %rsp, %rdx /* struct regs */
- movl %eax, %ecx /* on_panic_stack */
+ movl %r11d, %ecx /* on_panic_stack */
call panicsys
addq $REGSIZE, %rsp
popq %rdi