Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/cddl/osnet/sys/kern Sync with upstream r315983.
details: https://anonhg.NetBSD.org/src/rev/f44dfd21a6fa
branches: trunk
changeset: 999522:f44dfd21a6fa
user: hannken <hannken%NetBSD.org@localhost>
date: Fri Jun 07 10:31:21 2019 +0000
description:
Sync with upstream r315983.
diffstat:
external/cddl/osnet/sys/kern/callb.c | 112 +++++-
external/cddl/osnet/sys/kern/fm.c | 664 ++++++++++++++++++++++++++++++++--
2 files changed, 714 insertions(+), 62 deletions(-)
diffs (truncated from 1049 to 300 lines):
diff -r 88bd161751e0 -r f44dfd21a6fa external/cddl/osnet/sys/kern/callb.c
--- a/external/cddl/osnet/sys/kern/callb.c Fri Jun 07 07:41:22 2019 +0000
+++ b/external/cddl/osnet/sys/kern/callb.c Fri Jun 07 10:31:21 2019 +0000
@@ -1,12 +1,9 @@
-/* $NetBSD: callb.c,v 1.1 2009/08/07 20:57:57 haad Exp $ */
-
/*
* 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.
@@ -22,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
@@ -111,14 +106,24 @@
callb_fini(void *dummy __unused)
{
callb_t *cp;
+ int i;
mutex_enter(&ct->ct_lock);
- while ((cp = ct->ct_freelist) != NULL) {
- ct->ct_freelist = cp->c_next;
- ct->ct_ncallb--;
- kmem_free(cp, sizeof (callb_t));
+ for (i = 0; i < 16; i++) {
+ while ((cp = ct->ct_freelist) != NULL) {
+ ct->ct_freelist = cp->c_next;
+ ct->ct_ncallb--;
+ kmem_free(cp, sizeof (callb_t));
+ }
+ if (ct->ct_ncallb == 0)
+ break;
+ /* Not all callbacks finished, waiting for the rest. */
+ mutex_exit(&ct->ct_lock);
+ tsleep(ct, 0, "callb", hz / 4);
+ mutex_enter(&ct->ct_lock);
}
- ASSERT(ct->ct_ncallb == 0);
+ if (ct->ct_ncallb > 0)
+ printf("%s: Leaked %d callbacks!\n", __func__, ct->ct_ncallb);
mutex_exit(&ct->ct_lock);
mutex_destroy(&callb_safe_mutex);
mutex_destroy(&callb_table.ct_lock);
@@ -270,7 +275,7 @@
#ifdef CALLB_DEBUG
printf("callb_execute: name=%s func=%p arg=%p\n",
- cp->c_name, (void *)cp->c_func, (void *)cp->c_arg);
+ cp->c_name, (void *)cp->c_func, (void *)cp->c_arg);
#endif /* CALLB_DEBUG */
mutex_exit(&ct->ct_lock);
@@ -309,12 +314,14 @@
switch (code) {
case CB_CODE_CPR_CHKPT:
cp->cc_events |= CALLB_CPR_START;
+#ifdef CPR_NOT_THREAD_SAFE
while (!(cp->cc_events & CALLB_CPR_SAFE))
/* cv_timedwait() returns -1 if it times out. */
- if ((ret = cv_timedwait(&cp->cc_callb_cv,
- cp->cc_lockp,
- callb_timeout_sec * hz)) == -1)
+ if ((ret = cv_reltimedwait(&cp->cc_callb_cv,
+ cp->cc_lockp, (callb_timeout_sec * hz),
+ TR_CLOCK_TICK)) == -1)
break;
+#endif
break;
case CB_CODE_CPR_RESUME:
@@ -360,3 +367,74 @@
cv_broadcast(&ct->ct_busy_cv);
mutex_exit(&ct->ct_lock);
}
+
+#ifdef illumos
+/*
+ * Return a boolean value indicating whether a particular kernel thread is
+ * stopped in accordance with the cpr callback protocol. If returning
+ * false, also return a pointer to the thread name via the 2nd argument.
+ */
+boolean_t
+callb_is_stopped(kthread_id_t tp, caddr_t *thread_name)
+{
+ callb_t *cp;
+ boolean_t ret_val;
+
+ mutex_enter(&ct->ct_lock);
+
+ for (cp = ct->ct_first_cb[CB_CL_CPR_DAEMON];
+ cp != NULL && tp != cp->c_thread; cp = cp->c_next)
+ ;
+
+ ret_val = (cp != NULL);
+ if (ret_val) {
+ /*
+ * We found the thread in the callback table and have
+ * provisionally set the return value to true. Now
+ * see if it is marked "safe" and is sleeping or stopped.
+ */
+ callb_cpr_t *ccp = (callb_cpr_t *)cp->c_arg;
+
+ *thread_name = cp->c_name; /* in case not stopped */
+ mutex_enter(ccp->cc_lockp);
+
+ if (ccp->cc_events & CALLB_CPR_SAFE) {
+ int retry;
+
+ mutex_exit(ccp->cc_lockp);
+ for (retry = 0; retry < CALLB_MAX_RETRY; retry++) {
+ thread_lock(tp);
+ if (tp->t_state & (TS_SLEEP | TS_STOPPED)) {
+ thread_unlock(tp);
+ break;
+ }
+ thread_unlock(tp);
+ delay(CALLB_THREAD_DELAY);
+ }
+ ret_val = retry < CALLB_MAX_RETRY;
+ } else {
+ ret_val =
+ (ccp->cc_events & CALLB_CPR_ALWAYS_SAFE) != 0;
+ mutex_exit(ccp->cc_lockp);
+ }
+ } else {
+ /*
+ * Thread not found in callback table. Make the best
+ * attempt to identify the thread in the error message.
+ */
+ ulong_t offset;
+ char *sym = kobj_getsymname((uintptr_t)tp->t_startpc,
+ &offset);
+
+ *thread_name = sym ? sym : "*unknown*";
+ }
+
+ mutex_exit(&ct->ct_lock);
+ return (ret_val);
+}
+#endif /* illumos */
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+SYSINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_init, NULL);
+SYSUNINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_fini, NULL);
+#endif
diff -r 88bd161751e0 -r f44dfd21a6fa external/cddl/osnet/sys/kern/fm.c
--- a/external/cddl/osnet/sys/kern/fm.c Fri Jun 07 07:41:22 2019 +0000
+++ b/external/cddl/osnet/sys/kern/fm.c Fri Jun 07 10:31:21 2019 +0000
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -53,18 +52,24 @@
*/
#include <sys/types.h>
-#include <sys/pset.h>
#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
#include <sys/sysevent.h>
#include <sys/nvpair.h>
#include <sys/cmn_err.h>
#include <sys/cpuvar.h>
#include <sys/sysmacros.h>
#include <sys/systm.h>
+#include <sys/compress.h>
+#include <sys/cpuvar.h>
+#include <sys/kobj.h>
+#include <sys/kstat.h>
+#include <sys/processor.h>
+#ifdef __NetBSD__
#include <sys/cpu.h>
-#include <sys/atomic.h>
+#else
+#include <sys/pcpu.h>
+#endif
+#include <sys/sunddi.h>
#include <sys/systeminfo.h>
#include <sys/sysevent/eventdefs.h>
#include <sys/fm/util.h>
@@ -78,7 +83,11 @@
static const char *fm_msgid = "SUNOS-8000-0G";
static char *volatile fm_panicstr = NULL;
+#ifdef illumos
errorq_t *ereport_errorq;
+#endif
+void *ereport_dumpbuf;
+size_t ereport_dumplen;
static uint_t ereport_chanlen = ERPT_EVCH_MAX;
static evchan_t *ereport_chan = NULL;
@@ -86,6 +95,86 @@
static size_t ereport_size = 0;
static int ereport_cols = 80;
+extern void fastreboot_disable_highpil(void);
+
+/*
+ * Common fault management kstats to record ereport generation
+ * failures
+ */
+
+struct erpt_kstat {
+ kstat_named_t erpt_dropped; /* num erpts dropped on post */
+ kstat_named_t erpt_set_failed; /* num erpt set failures */
+ kstat_named_t fmri_set_failed; /* num fmri set failures */
+ kstat_named_t payload_set_failed; /* num payload set failures */
+};
+
+static struct erpt_kstat erpt_kstat_data = {
+ { "erpt-dropped", KSTAT_DATA_UINT64 },
+ { "erpt-set-failed", KSTAT_DATA_UINT64 },
+ { "fmri-set-failed", KSTAT_DATA_UINT64 },
+ { "payload-set-failed", KSTAT_DATA_UINT64 }
+};
+
+#ifdef illumos
+/*ARGSUSED*/
+static void
+fm_drain(void *private, void *data, errorq_elem_t *eep)
+{
+ nvlist_t *nvl = errorq_elem_nvl(ereport_errorq, eep);
+
+ if (!panicstr)
+ (void) fm_ereport_post(nvl, EVCH_TRYHARD);
+ else
+ fm_nvprint(nvl);
+}
+#endif
+
+void
+fm_init(void)
+{
+ kstat_t *ksp;
+
+#ifdef illumos
+ (void) sysevent_evc_bind(FM_ERROR_CHAN,
+ &ereport_chan, EVCH_CREAT | EVCH_HOLD_PEND);
+
+ (void) sysevent_evc_control(ereport_chan,
+ EVCH_SET_CHAN_LEN, &ereport_chanlen);
+#endif
+
+ if (ereport_qlen == 0)
+ ereport_qlen = ERPT_MAX_ERRS * MAX(max_ncpus, 4);
+
+ if (ereport_size == 0)
+ ereport_size = ERPT_DATA_SZ;
+
+#ifdef illumos
+ ereport_errorq = errorq_nvcreate("fm_ereport_queue",
+ (errorq_func_t)fm_drain, NULL, ereport_qlen, ereport_size,
+ FM_ERR_PIL, ERRORQ_VITAL);
+ if (ereport_errorq == NULL)
+ panic("failed to create required ereport error queue");
+#endif
+
+ ereport_dumpbuf = kmem_alloc(ereport_size, KM_SLEEP);
+ ereport_dumplen = ereport_size;
+
+ /* Initialize ereport allocation and generation kstats */
+ ksp = kstat_create("unix", 0, "fm", "misc", KSTAT_TYPE_NAMED,
+ sizeof (struct erpt_kstat) / sizeof (kstat_named_t),
+ KSTAT_FLAG_VIRTUAL);
+
+ if (ksp != NULL) {
+ ksp->ks_data = &erpt_kstat_data;
+ kstat_install(ksp);
+ } else {
+ cmn_err(CE_NOTE, "failed to create fm/misc kstat\n");
+
+ }
+}
Home |
Main Index |
Thread Index |
Old Index