[Midnightbsd-cvs] src [9956] trunk/sys/kern: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat May 26 10:27:13 EDT 2018


Revision: 9956
          http://svnweb.midnightbsd.org/src/?rev=9956
Author:   laffer1
Date:     2018-05-26 10:27:13 -0400 (Sat, 26 May 2018)
Log Message:
-----------
 sync with freebsd

Modified Paths:
--------------
    trunk/sys/kern/subr_acl_posix1e.c
    trunk/sys/kern/subr_autoconf.c
    trunk/sys/kern/subr_param.c
    trunk/sys/kern/subr_pcpu.c
    trunk/sys/kern/subr_power.c
    trunk/sys/kern/subr_prf.c
    trunk/sys/kern/subr_prof.c
    trunk/sys/kern/subr_rman.c
    trunk/sys/kern/subr_rtc.c
    trunk/sys/kern/subr_sbuf.c
    trunk/sys/kern/subr_scanf.c
    trunk/sys/kern/subr_sglist.c
    trunk/sys/kern/subr_sleepqueue.c
    trunk/sys/kern/subr_smp.c
    trunk/sys/kern/subr_stack.c
    trunk/sys/kern/subr_syscall.c
    trunk/sys/kern/subr_taskqueue.c
    trunk/sys/kern/subr_trap.c
    trunk/sys/kern/subr_turnstile.c
    trunk/sys/kern/subr_uio.c
    trunk/sys/kern/subr_unit.c
    trunk/sys/kern/subr_witness.c

Added Paths:
-----------
    trunk/sys/kern/subr_terminal.c

Modified: trunk/sys/kern/subr_acl_posix1e.c
===================================================================
--- trunk/sys/kern/subr_acl_posix1e.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_acl_posix1e.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999-2006 Robert N. M. Watson
  * All rights reserved.
@@ -34,9 +35,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_acl_posix1e.c 232936 2012-03-13 20:27:48Z adrian $");
 
 #include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
 #include <sys/systm.h>
 #include <sys/mount.h>
 #include <sys/priv.h>
@@ -648,3 +651,42 @@
 
 	return (mode);
 }
+
+
+static int
+acl_posix1e_modload(module_t mod, int what, void *arg)
+{
+	int ret;
+
+	ret = 0;
+
+	switch (what) {
+	case MOD_LOAD:
+	case MOD_SHUTDOWN:
+		break;
+
+	case MOD_QUIESCE:
+		/* XXX TODO */
+		ret = 0;
+		break;
+
+	case MOD_UNLOAD:
+		/* XXX TODO */
+		ret = 0;
+		break;
+	default:
+		ret = EINVAL;
+		break;
+	}
+
+	return (ret);
+}
+
+static moduledata_t acl_posix1e_mod = {
+	"acl_posix1e",
+	acl_posix1e_modload,
+	NULL
+};
+
+DECLARE_MODULE(acl_posix1e, acl_posix1e_mod, SI_SUB_VFS, SI_ORDER_FIRST);
+MODULE_VERSION(acl_posix1e, 1);

Modified: trunk/sys/kern/subr_autoconf.c
===================================================================
--- trunk/sys/kern/subr_autoconf.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_autoconf.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_autoconf.c 217075 2011-01-06 22:09:37Z jhb $");
 
 #include "opt_ddb.h"
 

Modified: trunk/sys/kern/subr_param.c
===================================================================
--- trunk/sys/kern/subr_param.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_param.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1980, 1986, 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_param.c 288690 2015-10-05 05:33:30Z kib $");
 
 #include "opt_param.h"
 #include "opt_msgbuf.h"
@@ -76,13 +77,15 @@
 #define NBUF 0
 #endif
 #ifndef MAXFILES
-#define	MAXFILES (maxproc * 2)
+#define	MAXFILES (40 + 32 * maxusers)
 #endif
 
 static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
 
-int	hz;
-int	tick;
+int	hz;				/* system clock's frequency */
+int	tick;				/* usec per tick (1000000 / hz) */
+struct bintime tick_bt;			/* bintime per tick (1s / hz) */
+sbintime_t tick_sbt;
 int	maxusers;			/* base tunable */
 int	maxproc;			/* maximum # of processes */
 int	maxprocperuid;			/* max # of procs per user */
@@ -89,8 +92,8 @@
 int	maxfiles;			/* sys. wide open files limit */
 int	maxfilesperproc;		/* per-proc open files limit */
 int	msgbufsize;			/* size of kernel message buffer */
-int	ncallout;			/* maximum # of timer events */
 int	nbuf;
+int	bio_transient_maxcnt;
 int	ngroups_max;			/* max # groups per process */
 int	nswbuf;
 pid_t	pid_max = PID_MAX;
@@ -97,7 +100,11 @@
 long	maxswzone;			/* max swmeta KVA storage */
 long	maxbcache;			/* max buffer cache KVA storage */
 long	maxpipekva;			/* Limit on pipe KVA */
-int 	vm_guest;			/* Running as virtual machine guest? */
+#ifdef XEN
+int	vm_guest = VM_GUEST_XEN;
+#else
+int	vm_guest = VM_GUEST_NO;		/* Running as virtual machine guest? */
+#endif
 u_long	maxtsiz;			/* max text size */
 u_long	dfldsiz;			/* initial data size limit */
 u_long	maxdsiz;			/* max data size */
@@ -107,8 +114,6 @@
 
 SYSCTL_INT(_kern, OID_AUTO, hz, CTLFLAG_RDTUN, &hz, 0,
     "Number of clock ticks per second");
-SYSCTL_INT(_kern, OID_AUTO, ncallout, CTLFLAG_RDTUN, &ncallout, 0,
-    "Number of pre-allocated timer events");
 SYSCTL_INT(_kern, OID_AUTO, nbuf, CTLFLAG_RDTUN, &nbuf, 0,
     "Number of buffers in the buffer cache");
 SYSCTL_INT(_kern, OID_AUTO, nswbuf, CTLFLAG_RDTUN, &nswbuf, 0,
@@ -119,6 +124,9 @@
     "Maximum memory for swap metadata");
 SYSCTL_LONG(_kern, OID_AUTO, maxbcache, CTLFLAG_RDTUN, &maxbcache, 0,
     "Maximum value of vfs.maxbufspace");
+SYSCTL_INT(_kern, OID_AUTO, bio_transient_maxcnt, CTLFLAG_RDTUN,
+    &bio_transient_maxcnt, 0,
+    "Maximum number of transient BIOs mappings");
 SYSCTL_ULONG(_kern, OID_AUTO, maxtsiz, CTLFLAG_RW | CTLFLAG_TUN, &maxtsiz, 0,
     "Maximum text size");
 SYSCTL_ULONG(_kern, OID_AUTO, dfldsiz, CTLFLAG_RW | CTLFLAG_TUN, &dfldsiz, 0,
@@ -133,7 +141,7 @@
     "Amount to grow stack on a stack fault");
 SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
     NULL, 0, sysctl_kern_vm_guest, "A",
-    "Virtual machine guest detected? (none|generic|xen)");
+    "Virtual machine guest detected?");
 
 /*
  * These have to be allocated somewhere; allocating
@@ -150,76 +158,26 @@
 	"none",
 	"generic",
 	"xen",
+	"hv",
+	"vmware",
 	NULL
 };
+CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST);
 
-#ifndef XEN
-static const char *const vm_bnames[] = {
-	"QEMU",				/* QEMU */
-	"Plex86",			/* Plex86 */
-	"Bochs",			/* Bochs */
-	"Xen",				/* Xen */
-	"Seabios",			/* KVM */
-	NULL
-};
-
-static const char *const vm_pnames[] = {
-	"VMware Virtual Platform",	/* VMWare VM */
-	"Virtual Machine",		/* Microsoft VirtualPC */
-	"VirtualBox",			/* Sun xVM VirtualBox */
-	"Parallels Virtual Platform",	/* Parallels VM */
-	"KVM",				/* KVM */
-	NULL
-};
-
-
 /*
- * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
- */
-static enum VM_GUEST
-detect_virtual(void)
-{
-	char *sysenv;
-	int i;
-
-	sysenv = getenv("smbios.bios.vendor");
-	if (sysenv != NULL) {
-		for (i = 0; vm_bnames[i] != NULL; i++)
-			if (strcmp(sysenv, vm_bnames[i]) == 0) {
-				freeenv(sysenv);
-				return (VM_GUEST_VM);
-			}
-		freeenv(sysenv);
-	}
-	sysenv = getenv("smbios.system.product");
-	if (sysenv != NULL) {
-		for (i = 0; vm_pnames[i] != NULL; i++)
-			if (strcmp(sysenv, vm_pnames[i]) == 0) {
-				freeenv(sysenv);
-				return (VM_GUEST_VM);
-			}
-		freeenv(sysenv);
-	}
-	return (VM_GUEST_NO);
-}
-#endif
-
-/*
  * Boot time overrides that are not scaled against main memory
  */
 void
 init_param1(void)
 {
-#ifndef XEN
-	vm_guest = detect_virtual();
-#else
-	vm_guest = VM_GUEST_XEN;
-#endif
+
 	hz = -1;
 	TUNABLE_INT_FETCH("kern.hz", &hz);
 	if (hz == -1)
 		hz = vm_guest > VM_GUEST_NO ? HZ_VM : HZ;
 	tick = 1000000 / hz;
+	tick_sbt = SBT_1S / hz;
+	tick_bt = sbttobt(tick_sbt);
 
 #ifdef VM_SWZONE_SIZE_MAX
 	maxswzone = VM_SWZONE_SIZE_MAX;
@@ -264,6 +222,8 @@
 		pid_max = PID_MAX;
 	else if (pid_max < 300)
 		pid_max = 300;
+
+	TUNABLE_INT_FETCH("vfs.unmapped_buf_allowed", &unmapped_buf_allowed);
 }
 
 /*
@@ -280,26 +240,42 @@
 		maxusers = physpages / (2 * 1024 * 1024 / PAGE_SIZE);
 		if (maxusers < 32)
 			maxusers = 32;
-		if (maxusers > 384)
-			maxusers = 384;
-	}
+#ifdef VM_MAX_AUTOTUNE_MAXUSERS
+                if (maxusers > VM_MAX_AUTOTUNE_MAXUSERS)
+                        maxusers = VM_MAX_AUTOTUNE_MAXUSERS;
+#endif
+                /*
+                 * Scales down the function in which maxusers grows once
+                 * we hit 384.
+                 */
+                if (maxusers > 384)
+                        maxusers = 384 + ((maxusers - 384) / 8);
+        }
 
 	/*
 	 * The following can be overridden after boot via sysctl.  Note:
 	 * unless overriden, these macros are ultimately based on maxusers.
+	 * Limit maxproc so that kmap entries cannot be exhausted by
+	 * processes.
 	 */
 	maxproc = NPROC;
 	TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
+	if (maxproc > (physpages / 12))
+		maxproc = physpages / 12;
+	if (maxproc > pid_max)
+		maxproc = pid_max;
+	maxprocperuid = (maxproc * 9) / 10;
+
 	/*
-	 * Limit maxproc so that kmap entries cannot be exhausted by
-	 * processes.
+	 * The default limit for maxfiles is 1/12 of the number of
+	 * physical page but not less than 16 times maxusers.
+	 * At most it can be 1/6 the number of physical pages.
 	 */
-	if (maxproc > (physpages / 12))
-		maxproc = physpages / 12;
-	maxfiles = MAXFILES;
+	maxfiles = imax(MAXFILES, physpages / 8);
 	TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
-	maxprocperuid = (maxproc * 9) / 10;
-	maxfilesperproc = (maxfiles * 9) / 10;
+	if (maxfiles > (physpages / 4))
+		maxfiles = physpages / 4;
+	maxfilesperproc = (maxfiles / 10) * 9;
 	
 	/*
 	 * Cannot be changed after boot.
@@ -306,25 +282,23 @@
 	 */
 	nbuf = NBUF;
 	TUNABLE_INT_FETCH("kern.nbuf", &nbuf);
+	TUNABLE_INT_FETCH("kern.bio_transient_maxcnt", &bio_transient_maxcnt);
 
-	ncallout = 16 + maxproc + maxfiles;
-	TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
-
 	/*
 	 * The default for maxpipekva is min(1/64 of the kernel address space,
 	 * max(1/64 of main memory, 512KB)).  See sys_pipe.c for more details.
 	 */
 	maxpipekva = (physpages / 64) * PAGE_SIZE;
+	TUNABLE_LONG_FETCH("kern.ipc.maxpipekva", &maxpipekva);
 	if (maxpipekva < 512 * 1024)
 		maxpipekva = 512 * 1024;
 	if (maxpipekva > (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 64)
 		maxpipekva = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) /
 		    64;
-	TUNABLE_LONG_FETCH("kern.ipc.maxpipekva", &maxpipekva);
 }
 
 /*
- * Sysctl stringiying handler for kern.vm_guest.
+ * Sysctl stringifying handler for kern.vm_guest.
  */
 static int
 sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS)

Modified: trunk/sys/kern/subr_pcpu.c
===================================================================
--- trunk/sys/kern/subr_pcpu.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_pcpu.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Wind River Systems, Inc.
  * All rights reserved.
@@ -46,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_pcpu.c 262739 2014-03-04 14:46:30Z glebius $");
 
 #include "opt_ddb.h"
 
@@ -59,6 +60,7 @@
 #include <sys/proc.h>
 #include <sys/smp.h>
 #include <sys/sx.h>
+#include <vm/uma.h>
 #include <ddb/ddb.h>
 
 static MALLOC_DEFINE(M_PCPU, "Per-cpu", "Per-cpu resource accouting.");
@@ -127,6 +129,30 @@
 SYSINIT(dpcpu, SI_SUB_KLD, SI_ORDER_FIRST, dpcpu_startup, 0);
 
 /*
+ * UMA_PCPU_ZONE zones, that are available for all kernel
+ * consumers. Right now 64 bit zone is used for counter(9)
+ * and pointer zone is used by flowtable.
+ */
+
+uma_zone_t pcpu_zone_64;
+uma_zone_t pcpu_zone_ptr;
+
+static void
+pcpu_zones_startup(void)
+{
+
+	pcpu_zone_64 = uma_zcreate("64 pcpu", sizeof(uint64_t),
+	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_PCPU);
+
+	if (sizeof(uint64_t) == sizeof(void *))
+		pcpu_zone_ptr = pcpu_zone_64;
+	else
+		pcpu_zone_ptr = uma_zcreate("ptr pcpu", sizeof(void *),
+		    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_PCPU);
+}
+SYSINIT(pcpu_zones, SI_SUB_KMEM, SI_ORDER_ANY, pcpu_zones_startup, NULL);
+
+/*
  * First-fit extent based allocator for allocating space in the per-cpu
  * region reserved for modules.  This is only intended for use by the
  * kernel linkers to place module linker sets.

Modified: trunk/sys/kern/subr_power.c
===================================================================
--- trunk/sys/kern/subr_power.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_power.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Mitsuru IWASAKI
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_power.c 152248 2005-11-09 16:22:56Z imp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/kern/subr_prf.c
===================================================================
--- trunk/sys/kern/subr_prf.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_prf.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1986, 1988, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,12 +36,15 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_prf.c 321108 2017-07-18 06:45:41Z ngie $");
 
+#ifdef _KERNEL
 #include "opt_ddb.h"
 #include "opt_printf.h"
+#endif  /* _KERNEL */
 
 #include <sys/param.h>
+#ifdef _KERNEL
 #include <sys/systm.h>
 #include <sys/lock.h>
 #include <sys/kdb.h>
@@ -57,7 +61,9 @@
 #include <sys/syslog.h>
 #include <sys/cons.h>
 #include <sys/uio.h>
+#endif
 #include <sys/ctype.h>
+#include <sys/sbuf.h>
 
 #ifdef DDB
 #include <ddb/ddb.h>
@@ -67,8 +73,22 @@
  * Note that stdarg.h and the ANSI style va_start macro is used for both
  * ANSI and traditional C compilers.
  */
+#ifdef _KERNEL
 #include <machine/stdarg.h>
+#else
+#include <stdarg.h>
+#endif
 
+/*
+ * This is needed for sbuf_putbuf() when compiled into userland.  Due to the
+ * shared nature of this file, it's the only place to put it.
+ */
+#ifndef _KERNEL
+#include <stdio.h>
+#endif
+
+#ifdef _KERNEL
+
 #define TOCONS	0x01
 #define TOTTY	0x02
 #define TOLOG	0x04
@@ -151,8 +171,8 @@
 	PROC_LOCK(p);
 	if ((p->p_flag & P_CONTROLT) == 0) {
 		PROC_UNLOCK(p);
-		retval = 0;
-		goto out;
+		sx_sunlock(&proctree_lock);
+		return (0);
 	}
 	SESS_LOCK(p->p_session);
 	pca.tty = p->p_session->s_ttyp;
@@ -159,31 +179,39 @@
 	SESS_UNLOCK(p->p_session);
 	PROC_UNLOCK(p);
 	if (pca.tty == NULL) {
-		retval = 0;
-		goto out;
+		sx_sunlock(&proctree_lock);
+		return (0);
 	}
 	pca.flags = TOTTY;
 	pca.p_bufr = NULL;
 	va_start(ap, fmt);
 	tty_lock(pca.tty);
+	sx_sunlock(&proctree_lock);
 	retval = kvprintf(fmt, putchar, &pca, 10, ap);
 	tty_unlock(pca.tty);
 	va_end(ap);
-out:
-	sx_sunlock(&proctree_lock);
 	return (retval);
 }
 
 /*
- * tprintf prints on the controlling terminal associated with the given
- * session, possibly to the log as well.
+ * tprintf and vtprintf print on the controlling terminal associated with the
+ * given session, possibly to the log as well.
  */
 void
 tprintf(struct proc *p, int pri, const char *fmt, ...)
 {
+	va_list ap;
+
+	va_start(ap, fmt);
+	vtprintf(p, pri, fmt, ap);
+	va_end(ap);
+}
+
+void
+vtprintf(struct proc *p, int pri, const char *fmt, va_list ap)
+{
 	struct tty *tp = NULL;
 	int flags = 0;
-	va_list ap;
 	struct putchar_arg pca;
 	struct session *sess = NULL;
 
@@ -208,17 +236,15 @@
 	pca.tty = tp;
 	pca.flags = flags;
 	pca.p_bufr = NULL;
-	va_start(ap, fmt);
 	if (pca.tty != NULL)
 		tty_lock(pca.tty);
+	sx_sunlock(&proctree_lock);
 	kvprintf(fmt, putchar, &pca, 10, ap);
 	if (pca.tty != NULL)
 		tty_unlock(pca.tty);
-	va_end(ap);
 	if (sess != NULL)
 		sess_release(sess);
 	msgbuftrigger = 1;
-	sx_sunlock(&proctree_lock);
 }
 
 /*
@@ -242,16 +268,11 @@
 	return (retval);
 }
 
-/*
- * Log writes to the log buffer, and guarantees not to sleep (so can be
- * called by interrupt routines).  If there is no process reading the
- * log yet, it writes to the console also.
- */
-void
-log(int level, const char *fmt, ...)
+static int
+_vprintf(int level, int flags, const char *fmt, va_list ap)
 {
-	va_list ap;
 	struct putchar_arg pca;
+	int retval;
 #ifdef PRINTF_BUFR_SIZE
 	char bufr[PRINTF_BUFR_SIZE];
 #endif
@@ -258,7 +279,7 @@
 
 	pca.tty = NULL;
 	pca.pri = level;
-	pca.flags = log_open ? TOLOG : TOCONS;
+	pca.flags = flags;
 #ifdef PRINTF_BUFR_SIZE
 	pca.p_bufr = bufr;
 	pca.p_next = pca.p_bufr;
@@ -266,12 +287,11 @@
 	pca.remain = sizeof(bufr);
 	*pca.p_next = '\0';
 #else
+	/* Don't buffer console output. */
 	pca.p_bufr = NULL;
 #endif
 
-	va_start(ap, fmt);
-	kvprintf(fmt, putchar, &pca, 10, ap);
-	va_end(ap);
+	retval = kvprintf(fmt, putchar, &pca, 10, ap);
 
 #ifdef PRINTF_BUFR_SIZE
 	/* Write any buffered console/log output: */
@@ -283,6 +303,24 @@
 			cnputs(pca.p_bufr);
 	}
 #endif
+
+	return (retval);
+}
+
+/*
+ * Log writes to the log buffer, and guarantees not to sleep (so can be
+ * called by interrupt routines).  If there is no process reading the
+ * log yet, it writes to the console also.
+ */
+void
+log(int level, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	(void)_vprintf(level, log_open ? TOLOG : TOCONS | TOLOG, fmt, ap);
+	va_end(ap);
+
 	msgbuftrigger = 1;
 }
 
@@ -349,7 +387,6 @@
 	msgbuftrigger = 1;
 	free(uio, M_IOV);
 	free(consbuffer, M_TEMP);
-	return;
 }
 
 int
@@ -368,36 +405,10 @@
 int
 vprintf(const char *fmt, va_list ap)
 {
-	struct putchar_arg pca;
 	int retval;
-#ifdef PRINTF_BUFR_SIZE
-	char bufr[PRINTF_BUFR_SIZE];
-#endif
 
-	pca.tty = NULL;
-	pca.flags = TOCONS | TOLOG;
-	pca.pri = -1;
-#ifdef PRINTF_BUFR_SIZE
-	pca.p_bufr = bufr;
-	pca.p_next = pca.p_bufr;
-	pca.n_bufr = sizeof(bufr);
-	pca.remain = sizeof(bufr);
-	*pca.p_next = '\0';
-#else
-	/* Don't buffer console output. */
-	pca.p_bufr = NULL;
-#endif
+	retval = _vprintf(-1, TOCONS | TOLOG, fmt, ap);
 
-	retval = kvprintf(fmt, putchar, &pca, 10, ap);
-
-#ifdef PRINTF_BUFR_SIZE
-	/* Write any buffered console/log output: */
-	if (*pca.p_bufr != '\0') {
-		cnputs(pca.p_bufr);
-		msglogstr(pca.p_bufr, pca.pri, /*filter_cr*/ 1);
-	}
-#endif
-
 	if (!panicstr)
 		msgbuftrigger = 1;
 
@@ -405,6 +416,23 @@
 }
 
 static void
+prf_putbuf(char *bufr, int flags, int pri)
+{
+
+	if (flags & TOLOG)
+		msglogstr(bufr, pri, /*filter_cr*/1);
+
+	if (flags & TOCONS) {
+		if ((panicstr == NULL) && (constty != NULL))
+			msgbuf_addstr(&consmsgbuf, -1,
+			    bufr, /*filter_cr*/ 0);
+
+		if ((constty == NULL) ||(always_console_output))
+			cnputs(bufr);
+	}
+}
+
+static void
 putbuf(int c, struct putchar_arg *ap)
 {
 	/* Check if no console output buffer was provided. */
@@ -425,19 +453,8 @@
 
 		/* Check if the buffer needs to be flushed. */
 		if (ap->remain == 2 || c == '\n') {
+			prf_putbuf(ap->p_bufr, ap->flags, ap->pri);
 
-			if (ap->flags & TOLOG)
-				msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1);
-
-			if (ap->flags & TOCONS) {
-				if ((panicstr == NULL) && (constty != NULL))
-					msgbuf_addstr(&consmsgbuf, -1,
-					    ap->p_bufr, /*filter_cr*/ 0);
-
-				if ((constty == NULL) ||(always_console_output))
-					cnputs(ap->p_bufr);
-			}
-
 			ap->p_next = ap->p_bufr;
 			ap->remain = ap->n_bufr;
 			*ap->p_next = '\0';
@@ -467,25 +484,19 @@
 	struct putchar_arg *ap = (struct putchar_arg*) arg;
 	struct tty *tp = ap->tty;
 	int flags = ap->flags;
-	int putbuf_done = 0;
 
 	/* Don't use the tty code after a panic or while in ddb. */
 	if (kdb_active) {
 		if (c != '\0')
 			cnputc(c);
-	} else {
-		if ((panicstr == NULL) && (flags & TOTTY) && (tp != NULL))
-			tty_putchar(tp, c);
+		return;
+	}
 
-		if (flags & TOCONS) {
-			putbuf(c, ap);
-			putbuf_done = 1;
-		}
-	}
-	if ((flags & TOLOG) && (putbuf_done == 0)) {
-		if (c != '\0')
-			putbuf(c, ap);
-	}
+	if ((flags & TOTTY) && tp != NULL && panicstr == NULL)
+		tty_putchar(tp, c);
+
+	if ((flags & (TOCONS | TOLOG)) && c != '\0')
+		putbuf(c, ap);
 }
 
 /*
@@ -928,7 +939,7 @@
 			while (percent < fmt)
 				PCHAR(*percent++);
 			/*
-			 * Since we ignore an formatting argument it is no 
+			 * Since we ignore a formatting argument it is no 
 			 * longer safe to obey the remaining formatting
 			 * arguments as the arguments will no longer match
 			 * the format specs.
@@ -1136,4 +1147,96 @@
 		printf("\n");
 	}
 }
+#endif /* _KERNEL */
 
+void
+sbuf_hexdump(struct sbuf *sb, const void *ptr, int length, const char *hdr,
+	     int flags)
+{
+	int i, j, k;
+	int cols;
+	const unsigned char *cp;
+	char delim;
+
+	if ((flags & HD_DELIM_MASK) != 0)
+		delim = (flags & HD_DELIM_MASK) >> 8;
+	else
+		delim = ' ';
+
+	if ((flags & HD_COLUMN_MASK) != 0)
+		cols = flags & HD_COLUMN_MASK;
+	else
+		cols = 16;
+
+	cp = ptr;
+	for (i = 0; i < length; i+= cols) {
+		if (hdr != NULL)
+			sbuf_printf(sb, "%s", hdr);
+
+		if ((flags & HD_OMIT_COUNT) == 0)
+			sbuf_printf(sb, "%04x  ", i);
+
+		if ((flags & HD_OMIT_HEX) == 0) {
+			for (j = 0; j < cols; j++) {
+				k = i + j;
+				if (k < length)
+					sbuf_printf(sb, "%c%02x", delim, cp[k]);
+				else
+					sbuf_printf(sb, "   ");
+			}
+		}
+
+		if ((flags & HD_OMIT_CHARS) == 0) {
+			sbuf_printf(sb, "  |");
+			for (j = 0; j < cols; j++) {
+				k = i + j;
+				if (k >= length)
+					sbuf_printf(sb, " ");
+				else if (cp[k] >= ' ' && cp[k] <= '~')
+					sbuf_printf(sb, "%c", cp[k]);
+				else
+					sbuf_printf(sb, ".");
+			}
+			sbuf_printf(sb, "|");
+		}
+		sbuf_printf(sb, "\n");
+	}
+}
+
+#ifdef _KERNEL
+void
+counted_warning(unsigned *counter, const char *msg)
+{
+	struct thread *td;
+	unsigned c;
+
+	for (;;) {
+		c = *counter;
+		if (c == 0)
+			break;
+		if (atomic_cmpset_int(counter, c, c - 1)) {
+			td = curthread;
+			log(LOG_INFO, "pid %d (%s) %s%s\n",
+			    td->td_proc->p_pid, td->td_name, msg,
+			    c > 1 ? "" : " - not logging anymore");
+			break;
+		}
+	}
+}
+#endif
+
+#ifdef _KERNEL
+void
+sbuf_putbuf(struct sbuf *sb)
+{
+
+	prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1);
+}
+#else
+void
+sbuf_putbuf(struct sbuf *sb)
+{
+
+	printf("%s", sbuf_data(sb));
+}
+#endif

Modified: trunk/sys/kern/subr_prof.c
===================================================================
--- trunk/sys/kern/subr_prof.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_prof.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1982, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_prof.c 302234 2016-06-27 21:50:30Z bdrewery $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -269,7 +270,7 @@
 	 * without much risk of reducing the profiling times below what they
 	 * would be when profiling is not configured.  Abbreviate:
 	 *	ab = minimum time between MC1 and MC3
-	 *	a  = minumum time between MC1 and MC2
+	 *	a  = minimum time between MC1 and MC2
 	 *	b  = minimum time between MC2 and MC3
 	 *	cd = minimum time between ME1 and ME3
 	 *	c  = minimum time between ME1 and ME2
@@ -421,12 +422,12 @@
 	}
 	PROC_LOCK(p);
 	upp = &td->td_proc->p_stats->p_prof;
-	PROC_SLOCK(p);
+	PROC_PROFLOCK(p);
 	upp->pr_off = uap->offset;
 	upp->pr_scale = uap->scale;
 	upp->pr_base = uap->samples;
 	upp->pr_size = uap->size;
-	PROC_SUNLOCK(p);
+	PROC_PROFUNLOCK(p);
 	startprofclock(p);
 	PROC_UNLOCK(p);
 
@@ -466,15 +467,15 @@
 	if (ticks == 0)
 		return;
 	prof = &td->td_proc->p_stats->p_prof;
-	PROC_SLOCK(td->td_proc);
+	PROC_PROFLOCK(td->td_proc);
 	if (pc < prof->pr_off ||
 	    (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) {
-		PROC_SUNLOCK(td->td_proc);
+		PROC_PROFUNLOCK(td->td_proc);
 		return;			/* out of range; ignore */
 	}
 
 	addr = prof->pr_base + i;
-	PROC_SUNLOCK(td->td_proc);
+	PROC_PROFUNLOCK(td->td_proc);
 	if ((v = fuswintr(addr)) == -1 || suswintr(addr, v + ticks) == -1) {
 		td->td_profil_addr = pc;
 		td->td_profil_ticks = ticks;
@@ -509,15 +510,15 @@
 	}
 	p->p_profthreads++;
 	prof = &p->p_stats->p_prof;
-	PROC_SLOCK(p);
+	PROC_PROFLOCK(p);
 	if (pc < prof->pr_off ||
 	    (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) {
-		PROC_SUNLOCK(p);
+		PROC_PROFUNLOCK(p);
 		goto out;
 	}
 
 	addr = prof->pr_base + i;
-	PROC_SUNLOCK(p);
+	PROC_PROFUNLOCK(p);
 	PROC_UNLOCK(p);
 	if (copyin(addr, &v, sizeof(v)) == 0) {
 		v += ticks;
@@ -533,6 +534,7 @@
 	if (--p->p_profthreads == 0) {
 		if (p->p_flag & P_STOPPROF) {
 			wakeup(&p->p_profthreads);
+			p->p_flag &= ~P_STOPPROF;
 			stop = 0;
 		}
 	}

Modified: trunk/sys/kern/subr_rman.c
===================================================================
--- trunk/sys/kern/subr_rman.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_rman.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright 1998 Massachusetts Institute of Technology
  *
@@ -58,7 +59,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_rman.c 292417 2015-12-18 00:40:19Z jhb $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -94,12 +95,12 @@
 	u_long	r_end;		/* index of the last entry (inclusive) */
 	u_int	r_flags;
 	void	*r_virtual;	/* virtual address of this resource */
-	struct	device *r_dev;	/* device which has allocated this resource */
-	struct	rman *r_rm;	/* resource manager from whence this came */
+	struct device *r_dev;	/* device which has allocated this resource */
+	struct rman *r_rm;	/* resource manager from whence this came */
 	int	r_rid;		/* optional rid for this resource. */
 };
 
-static int     rman_debug = 0;
+static int rman_debug = 0;
 TUNABLE_INT("debug.rman_debug", &rman_debug);
 SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RW,
     &rman_debug, 0, "rman debug");
@@ -108,12 +109,9 @@
 
 static MALLOC_DEFINE(M_RMAN, "rman", "Resource manager");
 
-struct	rman_head rman_head;
-static	struct mtx rman_mtx; /* mutex to protect rman_head */
-static	int int_rman_activate_resource(struct rman *rm, struct resource_i *r,
-				       struct resource_i **whohas);
-static	int int_rman_deactivate_resource(struct resource_i *r);
-static	int int_rman_release_resource(struct rman *rm, struct resource_i *r);
+struct rman_head rman_head;
+static struct mtx rman_mtx; /* mutex to protect rman_head */
+static int int_rman_release_resource(struct rman *rm, struct resource_i *r);
 
 static __inline struct resource_i *
 int_alloc_resource(int malloc_flag)
@@ -161,6 +159,7 @@
 rman_manage_region(struct rman *rm, u_long start, u_long end)
 {
 	struct resource_i *r, *s, *t;
+	int rv = 0;
 
 	DPRINTF(("rman_manage_region: <%s> request: start %#lx, end %#lx\n",
 	    rm->rm_descr, start, end));
@@ -188,13 +187,17 @@
 		TAILQ_INSERT_TAIL(&rm->rm_list, r, r_link);
 	} else {
 		/* Check for any overlap with the current region. */
-		if (r->r_start <= s->r_end && r->r_end >= s->r_start)
-			return EBUSY;
+		if (r->r_start <= s->r_end && r->r_end >= s->r_start) {
+			rv = EBUSY;
+			goto out;
+		}
 
 		/* Check for any overlap with the next region. */
 		t = TAILQ_NEXT(s, r_link);
-		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start)
-			return EBUSY;
+		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start) {
+			rv = EBUSY;
+			goto out;
+		}
 
 		/*
 		 * See if this region can be merged with the next region.  If
@@ -225,9 +228,9 @@
 			TAILQ_INSERT_BEFORE(s, r, r_link);
 		}
 	}
-
+out:
 	mtx_unlock(rm->rm_mtx);
-	return 0;
+	return rv;
 }
 
 int
@@ -312,12 +315,12 @@
 int
 rman_adjust_resource(struct resource *rr, u_long start, u_long end)
 {
-	struct	resource_i *r, *s, *t, *new;
-	struct	rman *rm;
+	struct resource_i *r, *s, *t, *new;
+	struct rman *rm;
 
 	/* Not supported for shared resources. */
 	r = rr->__r_i;
-	if (r->r_flags & (RF_TIMESHARE | RF_SHAREABLE))
+	if (r->r_flags & RF_SHAREABLE)
 		return (EINVAL);
 
 	/*
@@ -430,14 +433,16 @@
 	return (0);
 }
 
+#define	SHARE_TYPE(f)	(f & (RF_SHAREABLE | RF_PREFETCHABLE))
+
 struct resource *
 rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end,
-		      u_long count, u_long bound,  u_int flags,
-		      struct device *dev)
+			    u_long count, u_long bound, u_int flags,
+			    struct device *dev)
 {
-	u_int	want_activate;
-	struct	resource_i *r, *s, *rv;
-	u_long	rstart, rend, amask, bmask;
+	u_int new_rflags;
+	struct resource_i *r, *s, *rv;
+	u_long rstart, rend, amask, bmask;
 
 	rv = NULL;
 
@@ -445,13 +450,14 @@
 	       "length %#lx, flags %u, device %s\n", rm->rm_descr, start, end,
 	       count, flags,
 	       dev == NULL ? "<null>" : device_get_nameunit(dev)));
-	want_activate = (flags & RF_ACTIVE);
-	flags &= ~RF_ACTIVE;
+	KASSERT((flags & RF_FIRSTSHARE) == 0,
+	    ("invalid flags %#x", flags));
+	new_rflags = (flags & ~RF_FIRSTSHARE) | RF_ALLOCATED;
 
 	mtx_lock(rm->rm_mtx);
 
 	for (r = TAILQ_FIRST(&rm->rm_list);
-	     r && r->r_end < start;
+	     r && r->r_end < start + count - 1;
 	     r = TAILQ_NEXT(r, r_link))
 		;
 
@@ -461,6 +467,9 @@
 	}
 
 	amask = (1ul << RF_ALIGNMENT(flags)) - 1;
+	KASSERT(start <= ULONG_MAX - amask,
+	    ("start (%#lx) + amask (%#lx) would wrap around", start, amask));
+
 	/* If bound is 0, bmask will also be 0 */
 	bmask = ~(bound - 1);
 	/*
@@ -468,11 +477,20 @@
 	 */
 	for (s = r; s; s = TAILQ_NEXT(s, r_link)) {
 		DPRINTF(("considering [%#lx, %#lx]\n", s->r_start, s->r_end));
-		if (s->r_start + count - 1 > end) {
+		/*
+		 * The resource list is sorted, so there is no point in
+		 * searching further once r_start is too large.
+		 */
+		if (s->r_start > end - (count - 1)) {
 			DPRINTF(("s->r_start (%#lx) + count - 1> end (%#lx)\n",
 			    s->r_start, end));
 			break;
 		}
+		if (s->r_start > ULONG_MAX - amask) {
+			DPRINTF(("s->r_start (%#lx) + amask (%#lx) too large\n",
+			    s->r_start, amask));
+			break;
+		}
 		if (s->r_flags & RF_ALLOCATED) {
 			DPRINTF(("region is allocated\n"));
 			continue;
@@ -503,7 +521,7 @@
 			if ((s->r_end - s->r_start + 1) == count) {
 				DPRINTF(("candidate region is entire chunk\n"));
 				rv = s;
-				rv->r_flags |= RF_ALLOCATED | flags;
+				rv->r_flags = new_rflags;
 				rv->r_dev = dev;
 				goto out;
 			}
@@ -523,7 +541,7 @@
 				goto out;
 			rv->r_start = rstart;
 			rv->r_end = rstart + count - 1;
-			rv->r_flags = flags | RF_ALLOCATED;
+			rv->r_flags = new_rflags;
 			rv->r_dev = dev;
 			rv->r_rm = rm;
 
@@ -580,18 +598,13 @@
 	 * additional work, but this does not seem warranted.)
 	 */
 	DPRINTF(("no unshared regions found\n"));
-	if ((flags & (RF_SHAREABLE | RF_TIMESHARE)) == 0)
+	if ((flags & RF_SHAREABLE) == 0)
 		goto out;
 
-	for (s = r; s; s = TAILQ_NEXT(s, r_link)) {
-		if (s->r_start > end)
-			break;
-		if ((s->r_flags & flags) != flags)
-			continue;
-		rstart = ulmax(s->r_start, start);
-		rend = ulmin(s->r_end, ulmax(start + count - 1, end));
-		if (s->r_start >= start && s->r_end <= end
-		    && (s->r_end - s->r_start + 1) == count &&
+	for (s = r; s && s->r_end <= end; s = TAILQ_NEXT(s, r_link)) {
+		if (SHARE_TYPE(s->r_flags) == SHARE_TYPE(flags) &&
+		    s->r_start >= start &&
+		    (s->r_end - s->r_start + 1) == count &&
 		    (s->r_start & amask) == 0 &&
 		    ((s->r_start ^ s->r_end) & bmask) == 0) {
 			rv = int_alloc_resource(M_NOWAIT);
@@ -599,8 +612,7 @@
 				goto out;
 			rv->r_start = s->r_start;
 			rv->r_end = s->r_end;
-			rv->r_flags = s->r_flags &
-				(RF_ALLOCATED | RF_SHAREABLE | RF_TIMESHARE);
+			rv->r_flags = new_rflags;
 			rv->r_dev = dev;
 			rv->r_rm = rm;
 			if (s->r_sharehead == NULL) {
@@ -621,26 +633,11 @@
 			goto out;
 		}
 	}
-
 	/*
 	 * We couldn't find anything.
 	 */
+
 out:
-	/*
-	 * If the user specified RF_ACTIVE in the initial flags,
-	 * which is reflected in `want_activate', we attempt to atomically
-	 * activate the resource.  If this fails, we release the resource
-	 * and indicate overall failure.  (This behavior probably doesn't
-	 * make sense for RF_TIMESHARE-type resources.)
-	 */
-	if (rv && want_activate) {
-		struct resource_i *whohas;
-		if (int_rman_activate_resource(rm, rv, &whohas)) {
-			int_rman_release_resource(rm, rv);
-			rv = NULL;
-		}
-	}
-
 	mtx_unlock(rm->rm_mtx);
 	return (rv == NULL ? NULL : &rv->r_r);
 }
@@ -654,91 +651,17 @@
 	    dev));
 }
 
-static int
-int_rman_activate_resource(struct rman *rm, struct resource_i *r,
-			   struct resource_i **whohas)
-{
-	struct resource_i *s;
-	int ok;
-
-	/*
-	 * If we are not timesharing, then there is nothing much to do.
-	 * If we already have the resource, then there is nothing at all to do.
-	 * If we are not on a sharing list with anybody else, then there is
-	 * little to do.
-	 */
-	if ((r->r_flags & RF_TIMESHARE) == 0
-	    || (r->r_flags & RF_ACTIVE) != 0
-	    || r->r_sharehead == NULL) {
-		r->r_flags |= RF_ACTIVE;
-		return 0;
-	}
-
-	ok = 1;
-	for (s = LIST_FIRST(r->r_sharehead); s && ok;
-	     s = LIST_NEXT(s, r_sharelink)) {
-		if ((s->r_flags & RF_ACTIVE) != 0) {
-			ok = 0;
-			*whohas = s;
-		}
-	}
-	if (ok) {
-		r->r_flags |= RF_ACTIVE;
-		return 0;
-	}
-	return EBUSY;
-}
-
 int
 rman_activate_resource(struct resource *re)
 {
-	int rv;
-	struct resource_i *r, *whohas;
+	struct resource_i *r;
 	struct rman *rm;
 
 	r = re->__r_i;
 	rm = r->r_rm;
 	mtx_lock(rm->rm_mtx);
-	rv = int_rman_activate_resource(rm, r, &whohas);
+	r->r_flags |= RF_ACTIVE;
 	mtx_unlock(rm->rm_mtx);
-	return rv;
-}
-
-int
-rman_await_resource(struct resource *re, int pri, int timo)
-{
-	int	rv;
-	struct	resource_i *r, *whohas;
-	struct	rman *rm;
-
-	r = re->__r_i;
-	rm = r->r_rm;
-	mtx_lock(rm->rm_mtx);
-	for (;;) {
-		rv = int_rman_activate_resource(rm, r, &whohas);
-		if (rv != EBUSY)
-			return (rv);	/* returns with mutex held */
-
-		if (r->r_sharehead == NULL)
-			panic("rman_await_resource");
-		whohas->r_flags |= RF_WANTED;
-		rv = msleep(r->r_sharehead, rm->rm_mtx, pri, "rmwait", timo);
-		if (rv) {
-			mtx_unlock(rm->rm_mtx);
-			return (rv);
-		}
-	}
-}
-
-static int
-int_rman_deactivate_resource(struct resource_i *r)
-{
-
-	r->r_flags &= ~RF_ACTIVE;
-	if (r->r_flags & RF_WANTED) {
-		r->r_flags &= ~RF_WANTED;
-		wakeup(r->r_sharehead);
-	}
 	return 0;
 }
 
@@ -745,11 +668,11 @@
 int
 rman_deactivate_resource(struct resource *r)
 {
-	struct	rman *rm;
+	struct rman *rm;
 
 	rm = r->__r_i->r_rm;
 	mtx_lock(rm->rm_mtx);
-	int_rman_deactivate_resource(r->__r_i);
+	r->__r_i->r_flags &= ~RF_ACTIVE;
 	mtx_unlock(rm->rm_mtx);
 	return 0;
 }
@@ -757,10 +680,10 @@
 static int
 int_rman_release_resource(struct rman *rm, struct resource_i *r)
 {
-	struct	resource_i *s, *t;
+	struct resource_i *s, *t;
 
 	if (r->r_flags & RF_ACTIVE)
-		int_rman_deactivate_resource(r);
+		r->r_flags &= ~RF_ACTIVE;
 
 	/*
 	 * Check for a sharing list first.  If there is one, then we don't
@@ -851,9 +774,9 @@
 int
 rman_release_resource(struct resource *re)
 {
-	int	rv;
-	struct	resource_i *r;
-	struct	rman *rm;
+	int rv;
+	struct resource_i *r;
+	struct rman *rm;
 
 	r = re->__r_i;
 	rm = r->r_rm;
@@ -866,7 +789,7 @@
 uint32_t
 rman_make_alignment_flags(uint32_t size)
 {
-	int	i;
+	int i;
 
 	/*
 	 * Find the hightest bit set, and add one if more than one bit
@@ -884,6 +807,7 @@
 void
 rman_set_start(struct resource *r, u_long start)
 {
+
 	r->__r_i->r_start = start;
 }
 
@@ -890,6 +814,7 @@
 u_long
 rman_get_start(struct resource *r)
 {
+
 	return (r->__r_i->r_start);
 }
 
@@ -896,6 +821,7 @@
 void
 rman_set_end(struct resource *r, u_long end)
 {
+
 	r->__r_i->r_end = end;
 }
 
@@ -902,6 +828,7 @@
 u_long
 rman_get_end(struct resource *r)
 {
+
 	return (r->__r_i->r_end);
 }
 
@@ -908,6 +835,7 @@
 u_long
 rman_get_size(struct resource *r)
 {
+
 	return (r->__r_i->r_end - r->__r_i->r_start + 1);
 }
 
@@ -914,6 +842,7 @@
 u_int
 rman_get_flags(struct resource *r)
 {
+
 	return (r->__r_i->r_flags);
 }
 
@@ -920,6 +849,7 @@
 void
 rman_set_virtual(struct resource *r, void *v)
 {
+
 	r->__r_i->r_virtual = v;
 }
 
@@ -926,6 +856,7 @@
 void *
 rman_get_virtual(struct resource *r)
 {
+
 	return (r->__r_i->r_virtual);
 }
 
@@ -932,6 +863,7 @@
 void
 rman_set_bustag(struct resource *r, bus_space_tag_t t)
 {
+
 	r->r_bustag = t;
 }
 
@@ -938,6 +870,7 @@
 bus_space_tag_t
 rman_get_bustag(struct resource *r)
 {
+
 	return (r->r_bustag);
 }
 
@@ -944,6 +877,7 @@
 void
 rman_set_bushandle(struct resource *r, bus_space_handle_t h)
 {
+
 	r->r_bushandle = h;
 }
 
@@ -950,6 +884,7 @@
 bus_space_handle_t
 rman_get_bushandle(struct resource *r)
 {
+
 	return (r->r_bushandle);
 }
 
@@ -956,6 +891,7 @@
 void
 rman_set_rid(struct resource *r, int rid)
 {
+
 	r->__r_i->r_rid = rid;
 }
 
@@ -962,6 +898,7 @@
 int
 rman_get_rid(struct resource *r)
 {
+
 	return (r->__r_i->r_rid);
 }
 
@@ -968,6 +905,7 @@
 void
 rman_set_device(struct resource *r, struct device *dev)
 {
+
 	r->__r_i->r_dev = dev;
 }
 
@@ -974,6 +912,7 @@
 struct device *
 rman_get_device(struct resource *r)
 {
+
 	return (r->__r_i->r_dev);
 }
 
@@ -1114,7 +1053,8 @@
 				devname = "nomatch";
 		} else
 			devname = NULL;
-		db_printf("    0x%lx-0x%lx ", r->r_start, r->r_end);
+		db_printf("    0x%lx-0x%lx (RID=%d) ",
+		    r->r_start, r->r_end, r->r_rid);
 		if (devname != NULL)
 			db_printf("(%s)\n", devname);
 		else

Modified: trunk/sys/kern/subr_rtc.c
===================================================================
--- trunk/sys/kern/subr_rtc.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_rtc.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,12 +1,18 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1982, 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+ *	The Regents of the University of California.
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
+ * Portions of this software were developed by Julien Ridoux at the University
+ * of Melbourne under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -48,8 +54,10 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_rtc.c 306501 2016-09-30 13:49:50Z royger $");
 
+#include "opt_ffclock.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -56,6 +64,9 @@
 #include <sys/bus.h>
 #include <sys/clock.h>
 #include <sys/sysctl.h>
+#ifdef FFCLOCK
+#include <sys/timeffc.h>
+#endif
 #include <sys/timetc.h>
 
 #include "clock_if.h"
@@ -74,7 +85,7 @@
 {
 
 	if (clock_dev != NULL) {
-		if (clock_res > res) {
+		if (clock_res <= res) {
 			if (bootverbose)
 				device_printf(dev, "not installed as "
 				    "time-of-day clock: clock %s has higher "
@@ -133,6 +144,9 @@
 	ts.tv_sec += utc_offset();
 	timespecadd(&ts, &clock_adj);
 	tc_setclock(&ts);
+#ifdef FFCLOCK
+	ffclock_reset_clock(&ts);
+#endif
 	return;
 
 wrong_time:

Modified: trunk/sys/kern/subr_sbuf.c
===================================================================
--- trunk/sys/kern/subr_sbuf.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_sbuf.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000-2008 Poul-Henning Kamp
  * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_sbuf.c 321112 2017-07-18 08:15:02Z ngie $");
 
 #include <sys/param.h>
 
@@ -35,6 +36,7 @@
 #include <sys/ctype.h>
 #include <sys/errno.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/malloc.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
@@ -42,6 +44,7 @@
 #else /* _KERNEL */
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -52,11 +55,11 @@
 
 #ifdef _KERNEL
 static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
-#define	SBMALLOC(size)		malloc(size, M_SBUF, M_WAITOK)
+#define	SBMALLOC(size)		malloc(size, M_SBUF, M_WAITOK|M_ZERO)
 #define	SBFREE(buf)		free(buf, M_SBUF)
 #else /* _KERNEL */
 #define	KASSERT(e, m)
-#define	SBMALLOC(size)		malloc(size)
+#define	SBMALLOC(size)		calloc(1, size)
 #define	SBFREE(buf)		free(buf)
 #endif /* _KERNEL */
 
@@ -70,6 +73,7 @@
 #define	SBUF_FREESPACE(s)	((s)->s_size - ((s)->s_len + 1))
 #define	SBUF_CANEXTEND(s)	((s)->s_flags & SBUF_AUTOEXTEND)
 #define	SBUF_ISSECTION(s)	((s)->s_flags & SBUF_INSECTION)
+#define	SBUF_NULINCLUDED(s)	((s)->s_flags & SBUF_INCLUDENUL)
 
 /*
  * Set / clear flags
@@ -77,6 +81,7 @@
 #define	SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
 #define	SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
 
+#define	SBUF_MINSIZE		 2		/* Min is 1 byte + nulterm. */
 #define	SBUF_MINEXTENDSIZE	16		/* Should be power of 2. */
 
 #ifdef PAGE_SIZE
@@ -100,9 +105,15 @@
 	    ("%s called with a NULL sbuf pointer", fun));
 	KASSERT(s->s_buf != NULL,
 	    ("%s called with uninitialized or corrupt sbuf", fun));
-	KASSERT(s->s_len < s->s_size,
-	    ("wrote past end of sbuf (%jd >= %jd)",
-	    (intmax_t)s->s_len, (intmax_t)s->s_size));
+	if (SBUF_ISFINISHED(s) && SBUF_NULINCLUDED(s)) {
+		KASSERT(s->s_len <= s->s_size,
+		    ("wrote past end of sbuf (%jd >= %jd)",
+		    (intmax_t)s->s_len, (intmax_t)s->s_size));
+	} else {
+		KASSERT(s->s_len < s->s_size,
+		    ("wrote past end of sbuf (%jd >= %jd)",
+		    (intmax_t)s->s_len, (intmax_t)s->s_size));
+	}
 }
 
 static void
@@ -185,8 +196,9 @@
 	s->s_buf = buf;
 
 	if ((s->s_flags & SBUF_AUTOEXTEND) == 0) {
-		KASSERT(s->s_size >= 0,
-		    ("attempt to create a too small sbuf"));
+		KASSERT(s->s_size >= SBUF_MINSIZE,
+		    ("attempt to create an sbuf smaller than %d bytes",
+		    SBUF_MINSIZE));
 	}
 
 	if (s->s_buf != NULL)
@@ -262,6 +274,28 @@
 }
 #endif
 
+int
+sbuf_get_flags(struct sbuf *s)
+{
+
+	return (s->s_flags & SBUF_USRFLAGMSK);
+}
+
+void
+sbuf_clear_flags(struct sbuf *s, int flags)
+{
+
+	s->s_flags &= ~(flags & SBUF_USRFLAGMSK);
+}
+
+void
+sbuf_set_flags(struct sbuf *s, int flags)
+{
+
+
+	s->s_flags |= (flags & SBUF_USRFLAGMSK);
+}
+
 /*
  * Clear an sbuf and reset its position.
  */
@@ -352,13 +386,14 @@
 }
 
 /*
- * Append a byte to an sbuf.  This is the core function for appending
+ * Append bytes to an sbuf.  This is the core function for appending
  * to an sbuf and is the main place that deals with extending the
  * buffer and marking overflow.
  */
 static void
-sbuf_put_byte(struct sbuf *s, int c)
+sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
 {
+	size_t n;
 
 	assert_sbuf_integrity(s);
 	assert_sbuf_state(s, 0);
@@ -365,23 +400,39 @@
 
 	if (s->s_error != 0)
 		return;
-	if (SBUF_FREESPACE(s) <= 0) {
-		/*
-		 * If there is a drain, use it, otherwise extend the
-		 * buffer.
-		 */
-		if (s->s_drain_func != NULL)
-			(void)sbuf_drain(s);
-		else if (sbuf_extend(s, 1) < 0)
-			s->s_error = ENOMEM;
-		if (s->s_error != 0)
-			return;
+	while (len > 0) {
+		if (SBUF_FREESPACE(s) <= 0) {
+			/*
+			 * If there is a drain, use it, otherwise extend the
+			 * buffer.
+			 */
+			if (s->s_drain_func != NULL)
+				(void)sbuf_drain(s);
+			else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
+			    < 0)
+				s->s_error = ENOMEM;
+			if (s->s_error != 0)
+				return;
+		}
+		n = SBUF_FREESPACE(s);
+		if (len < n)
+			n = len;
+		memcpy(&s->s_buf[s->s_len], buf, n);
+		s->s_len += n;
+		if (SBUF_ISSECTION(s))
+			s->s_sect_len += n;
+		len -= n;
+		buf += n;
 	}
-	s->s_buf[s->s_len++] = c;
-	if (SBUF_ISSECTION(s))
-		s->s_sect_len++;
 }
 
+static void
+sbuf_put_byte(struct sbuf *s, char c)
+{
+
+	sbuf_put_bytes(s, &c, 1);
+}
+
 /*
  * Append a byte string to an sbuf.
  */
@@ -388,19 +439,10 @@
 int
 sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
 {
-	const char *str = buf;
-	const char *end = str + len;
 
-	assert_sbuf_integrity(s);
-	assert_sbuf_state(s, 0);
-
+	sbuf_put_bytes(s, buf, len);
 	if (s->s_error != 0)
 		return (-1);
-	for (; str < end; str++) {
-		sbuf_put_byte(s, *str);
-		if (s->s_error != 0)
-			return (-1);
-	}
 	return (0);
 }
 
@@ -454,18 +496,12 @@
 int
 sbuf_cat(struct sbuf *s, const char *str)
 {
+	size_t n;
 
-	assert_sbuf_integrity(s);
-	assert_sbuf_state(s, 0);
-
+	n = strlen(str);
+	sbuf_put_bytes(s, str, n);
 	if (s->s_error != 0)
 		return (-1);
-
-	while (*str != '\0') {
-		sbuf_put_byte(s, *str++);
-		if (s->s_error != 0)
-			return (-1);
-	}
 	return (0);
 }
 
@@ -588,6 +624,10 @@
 		va_copy(ap_copy, ap);
 		len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1,
 		    fmt, ap_copy);
+		if (len < 0) {
+			s->s_error = errno;
+			return (-1);
+		}
 		va_end(ap_copy);
 
 		if (SBUF_FREESPACE(s) >= len)
@@ -697,18 +737,21 @@
 	assert_sbuf_integrity(s);
 	assert_sbuf_state(s, 0);
 
+	s->s_buf[s->s_len] = '\0';
+	if (SBUF_NULINCLUDED(s))
+		s->s_len++;
 	if (s->s_drain_func != NULL) {
 		while (s->s_len > 0 && s->s_error == 0)
 			s->s_error = sbuf_drain(s);
 	}
-	s->s_buf[s->s_len] = '\0';
 	SBUF_SETFLAG(s, SBUF_FINISHED);
 #ifdef _KERNEL
 	return (s->s_error);
 #else
-	errno = s->s_error;
-	if (s->s_error)
+	if (s->s_error != 0) {
+		errno = s->s_error;
 		return (-1);
+	}
 	return (0);
 #endif
 }
@@ -742,6 +785,10 @@
 
 	if (s->s_error != 0)
 		return (-1);
+
+	/* If finished, nulterm is already in len, else add one. */
+	if (SBUF_NULINCLUDED(s) && !SBUF_ISFINISHED(s))
+		return (s->s_len + 1);
 	return (s->s_len);
 }
 

Modified: trunk/sys/kern/subr_scanf.c
===================================================================
--- trunk/sys/kern/subr_scanf.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_scanf.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_scanf.c 302234 2016-06-27 21:50:30Z bdrewery $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -603,7 +604,7 @@
 			 * z', but treats `a-a' as `the letter a, the
 			 * character -, and the letter a'.
 			 *
-			 * For compatibility, the `-' is not considerd
+			 * For compatibility, the `-' is not considered
 			 * to define a range if the character following
 			 * it is either a close bracket (required by ANSI)
 			 * or is not numerically greater than the character

Modified: trunk/sys/kern/subr_sglist.c
===================================================================
--- trunk/sys/kern/subr_sglist.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_sglist.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 Yahoo!, Inc.
  * All rights reserved.
@@ -29,10 +30,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_sglist.c 297059 2016-03-20 05:01:40Z np $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/bio.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
@@ -40,6 +42,7 @@
 #include <sys/uio.h>
 
 #include <vm/vm.h>
+#include <vm/vm_page.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
@@ -214,6 +217,9 @@
 sglist_free(struct sglist *sg)
 {
 
+	if (sg == NULL)
+		return;
+
 	if (refcount_release(&sg->sg_refs))
 		free(sg, M_SGLIST);
 }
@@ -239,6 +245,44 @@
 }
 
 /*
+ * Append the segments to describe a bio's data to a scatter/gather list.
+ * If there are insufficient segments, then this fails with EFBIG.
+ *
+ * NOTE: This function expects bio_bcount to be initialized.
+ */
+int
+sglist_append_bio(struct sglist *sg, struct bio *bp)
+{
+	struct sgsave save;
+	vm_paddr_t paddr;
+	size_t len, tlen;
+	int error, i, ma_offs;
+
+	if ((bp->bio_flags & BIO_UNMAPPED) == 0) {
+		error = sglist_append(sg, bp->bio_data, bp->bio_bcount);
+		return (error);
+	}
+
+	if (sg->sg_maxseg == 0)
+		return (EINVAL);
+
+	SGLIST_SAVE(sg, save);
+	tlen = bp->bio_bcount;
+	ma_offs = bp->bio_ma_offset;
+	for (i = 0; tlen > 0; i++, tlen -= len) {
+		len = min(PAGE_SIZE - ma_offs, tlen);
+		paddr = VM_PAGE_TO_PHYS(bp->bio_ma[i]) + ma_offs;
+		error = sglist_append_phys(sg, paddr, len);
+		if (error) {
+			SGLIST_RESTORE(sg, save);
+			return (error);
+		}
+		ma_offs = 0;
+	}
+	return (0);
+}
+
+/*
  * Append a single physical address range to a scatter/gather list.
  * If there are insufficient segments, then this fails with EFBIG.
  */

Modified: trunk/sys/kern/subr_sleepqueue.c
===================================================================
--- trunk/sys/kern/subr_sleepqueue.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_sleepqueue.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 John Baldwin <jhb at FreeBSD.org>
  * All rights reserved.
@@ -10,9 +11,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -29,7 +27,7 @@
 
 /*
  * Implementation of sleep queues used to hold queue of threads blocked on
- * a wait channel.  Sleep queues different from turnstiles in that wait
+ * a wait channel.  Sleep queues are different from turnstiles in that wait
  * channels are not owned by anyone, so there is no priority propagation.
  * Sleep queues can also provide a timeout and can also be interrupted by
  * signals.  That said, there are several similarities between the turnstile
@@ -39,7 +37,7 @@
  * a linked list of queues.  An individual queue is located by using a hash
  * to pick a chain, locking the chain, and then walking the chain searching
  * for the queue.  This means that a wait channel object does not need to
- * embed it's queue head just as locks do not embed their turnstile queue
+ * embed its queue head just as locks do not embed their turnstile queue
  * head.  Threads also carry around a sleep queue that they lend to the
  * wait channel when blocking.  Just as in turnstiles, the queue includes
  * a free list of the sleep queues of other threads blocked on the same
@@ -60,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_sleepqueue.c 324800 2017-10-20 10:06:02Z hselasky $");
 
 #include "opt_sleepqueue_profiling.h"
 #include "opt_ddb.h"
@@ -88,20 +86,18 @@
 #endif
 
 /*
- * Constants for the hash table of sleep queue chains.  These constants are
- * the same ones that 4BSD (and possibly earlier versions of BSD) used.
- * Basically, we ignore the lower 8 bits of the address since most wait
- * channel pointers are aligned and only look at the next 7 bits for the
- * hash.  SC_TABLESIZE must be a power of two for SC_MASK to work properly.
+ * Constants for the hash table of sleep queue chains.
+ * SC_TABLESIZE must be a power of two for SC_MASK to work properly.
  */
-#define	SC_TABLESIZE	128			/* Must be power of 2. */
+#define	SC_TABLESIZE	256			/* Must be power of 2. */
 #define	SC_MASK		(SC_TABLESIZE - 1)
 #define	SC_SHIFT	8
-#define	SC_HASH(wc)	(((uintptr_t)(wc) >> SC_SHIFT) & SC_MASK)
+#define	SC_HASH(wc)	((((uintptr_t)(wc) >> SC_SHIFT) ^ (uintptr_t)(wc)) & \
+			    SC_MASK)
 #define	SC_LOOKUP(wc)	&sleepq_chains[SC_HASH(wc)]
 #define NR_SLEEPQS      2
 /*
- * There two different lists of sleep queues.  Both lists are connected
+ * There are two different lists of sleep queues.  Both lists are connected
  * via the sq_hash entries.  The first list is the sleep queue chain list
  * that a sleep queue is on when it is attached to a wait channel.  The
  * second list is the free list hung off of a sleep queue that is attached
@@ -190,7 +186,7 @@
 		    MTX_SPIN | MTX_RECURSE);
 #ifdef SLEEPQUEUE_PROFILING
 		snprintf(chain_name, sizeof(chain_name), "%d", i);
-		chain_oid = SYSCTL_ADD_NODE(NULL, 
+		chain_oid = SYSCTL_ADD_NODE(NULL,
 		    SYSCTL_STATIC_CHILDREN(_debug_sleepq_chains), OID_AUTO,
 		    chain_name, CTLFLAG_RD, NULL, "sleepq chain stats");
 		SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(chain_oid), OID_AUTO,
@@ -206,7 +202,7 @@
 #else
 	    NULL, NULL, sleepq_init, NULL, UMA_ALIGN_CACHE, 0);
 #endif
-	
+
 	thread0.td_sleepqueue = sleepq_alloc();
 }
 
@@ -296,8 +292,9 @@
 	MPASS((queue >= 0) && (queue < NR_SLEEPQS));
 
 	/* If this thread is not allowed to sleep, die a horrible death. */
-	KASSERT(!(td->td_pflags & TDP_NOSLEEPING),
-	    ("Trying sleep, but thread marked as sleeping prohibited"));
+	KASSERT(td->td_no_sleeping == 0,
+	    ("%s: td %p to sleep on wchan %p with sleeping prohibited",
+	    __func__, td, wchan));
 
 	/* Look up the sleep queue associated with the wait channel 'wchan'. */
 	sq = sleepq_lookup(wchan);
@@ -360,10 +357,12 @@
  * sleep queue after timo ticks if the thread has not already been awakened.
  */
 void
-sleepq_set_timeout(void *wchan, int timo)
+sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt, sbintime_t pr,
+    int flags)
 {
 	struct sleepqueue_chain *sc;
 	struct thread *td;
+	sbintime_t pr1;
 
 	td = curthread;
 	sc = SC_LOOKUP(wchan);
@@ -371,7 +370,14 @@
 	MPASS(TD_ON_SLEEPQ(td));
 	MPASS(td->td_sleepqueue == NULL);
 	MPASS(wchan != NULL);
-	callout_reset_curcpu(&td->td_slpcallout, timo, sleepq_timeout, td);
+	KASSERT(td->td_sleeptimo == 0, ("td %d %p td_sleeptimo %jx",
+	    td->td_tid, td, (uintmax_t)td->td_sleeptimo));
+	thread_lock(td);
+	callout_when(sbt, pr, flags, &td->td_sleeptimo, &pr1);
+	thread_unlock(td);
+	callout_reset_sbt_on(&td->td_slpcallout, td->td_sleeptimo, pr1,
+	    sleepq_timeout, td, PCPU_GET(cpuid), flags | C_PRECALC |
+	    C_DIRECT_EXEC);
 }
 
 /*
@@ -404,8 +410,9 @@
 	struct thread *td;
 	struct proc *p;
 	struct sigacts *ps;
-	int sig, ret, stop_allowed;
+	int sig, ret;
 
+	ret = 0;
 	td = curthread;
 	p = curproc;
 	sc = SC_LOOKUP(wchan);
@@ -419,46 +426,51 @@
 	}
 
 	/*
-	 * See if there are any pending signals for this thread.  If not
-	 * we can switch immediately.  Otherwise do the signal processing
-	 * directly.
+	 * See if there are any pending signals or suspension requests for this
+	 * thread.  If not, we can switch immediately.
 	 */
 	thread_lock(td);
-	if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) == 0) {
-		sleepq_switch(wchan, pri);
-		return (0);
+	if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) != 0) {
+		thread_unlock(td);
+		mtx_unlock_spin(&sc->sc_lock);
+		CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)",
+			(void *)td, (long)p->p_pid, td->td_name);
+		PROC_LOCK(p);
+		/*
+		 * Check for suspension first. Checking for signals and then
+		 * suspending could result in a missed signal, since a signal
+		 * can be delivered while this thread is suspended.
+		 */
+		if ((td->td_flags & TDF_NEEDSUSPCHK) != 0) {
+			ret = thread_suspend_check(1);
+			MPASS(ret == 0 || ret == EINTR || ret == ERESTART);
+			if (ret != 0) {
+				PROC_UNLOCK(p);
+				mtx_lock_spin(&sc->sc_lock);
+				thread_lock(td);
+				goto out;
+			}
+		}
+		if ((td->td_flags & TDF_NEEDSIGCHK) != 0) {
+			ps = p->p_sigacts;
+			mtx_lock(&ps->ps_mtx);
+			sig = cursig(td);
+			if (sig != 0)
+				ret = SIGISMEMBER(ps->ps_sigintr, sig) ?
+				    EINTR : ERESTART;
+			mtx_unlock(&ps->ps_mtx);
+		}
+		/*
+		 * Lock the per-process spinlock prior to dropping the PROC_LOCK
+		 * to avoid a signal delivery race.  PROC_LOCK, PROC_SLOCK, and
+		 * thread_lock() are currently held in tdsendsignal().
+		 */
+		PROC_SLOCK(p);
+		mtx_lock_spin(&sc->sc_lock);
+		PROC_UNLOCK(p);
+		thread_lock(td);
+		PROC_SUNLOCK(p);
 	}
-	stop_allowed = (td->td_flags & TDF_SBDRY) ? SIG_STOP_NOT_ALLOWED :
-	    SIG_STOP_ALLOWED;
-	thread_unlock(td);
-	mtx_unlock_spin(&sc->sc_lock);
-	CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)",
-		(void *)td, (long)p->p_pid, td->td_name);
-	PROC_LOCK(p);
-	ps = p->p_sigacts;
-	mtx_lock(&ps->ps_mtx);
-	sig = cursig(td, stop_allowed);
-	if (sig == 0) {
-		mtx_unlock(&ps->ps_mtx);
-		ret = thread_suspend_check(1);
-		MPASS(ret == 0 || ret == EINTR || ret == ERESTART);
-	} else {
-		if (SIGISMEMBER(ps->ps_sigintr, sig))
-			ret = EINTR;
-		else
-			ret = ERESTART;
-		mtx_unlock(&ps->ps_mtx);
-	}
-	/*
-	 * Lock the per-process spinlock prior to dropping the PROC_LOCK
-	 * to avoid a signal delivery race.  PROC_LOCK, PROC_SLOCK, and
-	 * thread_lock() are currently held in tdsendsignal().
-	 */
-	PROC_SLOCK(p);
-	mtx_lock_spin(&sc->sc_lock);
-	PROC_UNLOCK(p);
-	thread_lock(td);
-	PROC_SUNLOCK(p);
 	if (ret == 0) {
 		sleepq_switch(wchan, pri);
 		return (0);
@@ -501,7 +513,7 @@
 	mtx_assert(&sc->sc_lock, MA_OWNED);
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 
-	/* 
+	/*
 	 * If we have a sleep queue, then we've already been woken up, so
 	 * just return.
 	 */
@@ -528,7 +540,7 @@
 #endif
 		}
 		mtx_unlock_spin(&sc->sc_lock);
-		return;		
+		return;
 	}
 #ifdef SLEEPQUEUE_PROFILING
 	if (prof_enabled)
@@ -552,36 +564,36 @@
 sleepq_check_timeout(void)
 {
 	struct thread *td;
+	int res;
 
 	td = curthread;
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 
 	/*
-	 * If TDF_TIMEOUT is set, we timed out.
+	 * If TDF_TIMEOUT is set, we timed out.  But recheck
+	 * td_sleeptimo anyway.
 	 */
-	if (td->td_flags & TDF_TIMEOUT) {
+	res = 0;
+	if (td->td_sleeptimo != 0) {
+		if (td->td_sleeptimo <= sbinuptime())
+			res = EWOULDBLOCK;
+		td->td_sleeptimo = 0;
+	}
+	if (td->td_flags & TDF_TIMEOUT)
 		td->td_flags &= ~TDF_TIMEOUT;
-		return (EWOULDBLOCK);
-	}
-
-	/*
-	 * If TDF_TIMOFAIL is set, the timeout ran after we had
-	 * already been woken up.
-	 */
-	if (td->td_flags & TDF_TIMOFAIL)
-		td->td_flags &= ~TDF_TIMOFAIL;
-
-	/*
-	 * If callout_stop() fails, then the timeout is running on
-	 * another CPU, so synchronize with it to avoid having it
-	 * accidentally wake up a subsequent sleep.
-	 */
-	else if (callout_stop(&td->td_slpcallout) == 0) {
-		td->td_flags |= TDF_TIMEOUT;
-		TD_SET_SLEEPING(td);
-		mi_switch(SW_INVOL | SWT_SLEEPQTIMO, NULL);
-	}
-	return (0);
+	else
+		/*
+		 * We ignore the situation where timeout subsystem was
+		 * unable to stop our callout.  The struct thread is
+		 * type-stable, the callout will use the correct
+		 * memory when running.  The checks of the
+		 * td_sleeptimo value in this function and in
+		 * sleepq_timeout() ensure that the thread does not
+		 * get spurious wakeups, even if the callout was reset
+		 * or thread reused.
+		 */
+		callout_stop(&td->td_slpcallout);
+	return (res);
 }
 
 /*
@@ -890,12 +902,17 @@
 	CTR3(KTR_PROC, "sleepq_timeout: thread %p (pid %ld, %s)",
 	    (void *)td, (long)td->td_proc->p_pid, (void *)td->td_name);
 
-	/*
-	 * First, see if the thread is asleep and get the wait channel if
-	 * it is.
-	 */
 	thread_lock(td);
-	if (TD_IS_SLEEPING(td) && TD_ON_SLEEPQ(td)) {
+
+	if (td->td_sleeptimo > sbinuptime() || td->td_sleeptimo == 0) {
+		/*
+		 * The thread does not want a timeout (yet).
+		 */
+	} else if (TD_IS_SLEEPING(td) && TD_ON_SLEEPQ(td)) {
+		/*
+		 * See if the thread is asleep and get the wait
+		 * channel if it is.
+		 */
 		wchan = td->td_wchan;
 		sc = SC_LOOKUP(wchan);
 		THREAD_LOCKPTR_ASSERT(td, &sc->sc_lock);
@@ -903,40 +920,16 @@
 		MPASS(sq != NULL);
 		td->td_flags |= TDF_TIMEOUT;
 		wakeup_swapper = sleepq_resume_thread(sq, td, 0);
-		thread_unlock(td);
-		if (wakeup_swapper)
-			kick_proc0();
-		return;
-	}
-
-	/*
-	 * If the thread is on the SLEEPQ but isn't sleeping yet, it
-	 * can either be on another CPU in between sleepq_add() and
-	 * one of the sleepq_*wait*() routines or it can be in
-	 * sleepq_catch_signals().
-	 */
-	if (TD_ON_SLEEPQ(td)) {
+	} else if (TD_ON_SLEEPQ(td)) {
+		/*
+		 * If the thread is on the SLEEPQ but isn't sleeping
+		 * yet, it can either be on another CPU in between
+		 * sleepq_add() and one of the sleepq_*wait*()
+		 * routines or it can be in sleepq_catch_signals().
+		 */
 		td->td_flags |= TDF_TIMEOUT;
-		thread_unlock(td);
-		return;
 	}
 
-	/*
-	 * Now check for the edge cases.  First, if TDF_TIMEOUT is set,
-	 * then the other thread has already yielded to us, so clear
-	 * the flag and resume it.  If TDF_TIMEOUT is not set, then the
-	 * we know that the other thread is not on a sleep queue, but it
-	 * hasn't resumed execution yet.  In that case, set TDF_TIMOFAIL
-	 * to let it know that the timeout has already run and doesn't
-	 * need to be canceled.
-	 */
-	if (td->td_flags & TDF_TIMEOUT) {
-		MPASS(TD_IS_SLEEPING(td));
-		td->td_flags &= ~TDF_TIMEOUT;
-		TD_CLR_SLEEPING(td);
-		wakeup_swapper = setrunnable(td);
-	} else
-		td->td_flags |= TDF_TIMOFAIL;
 	thread_unlock(td);
 	if (wakeup_swapper)
 		kick_proc0();
@@ -1222,7 +1215,7 @@
 		if (TAILQ_EMPTY(&sq->sq_blocked[i]))
 			db_printf("\tempty\n");
 		else
-			TAILQ_FOREACH(td, &sq->sq_blocked[0],
+			TAILQ_FOREACH(td, &sq->sq_blocked[i],
 				      td_slpq) {
 				db_printf("\t%p (tid %d, pid %d, \"%s\")\n", td,
 					  td->td_tid, td->td_proc->p_pid,

Modified: trunk/sys/kern/subr_smp.c
===================================================================
--- trunk/sys/kern/subr_smp.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_smp.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001, John Baldwin <jhb at FreeBSD.org>.
  * All rights reserved.
@@ -10,9 +11,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -33,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_smp.c 331910 2018-04-03 07:52:06Z avg $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -44,6 +42,7 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/pcpu.h>
+#include <sys/sched.h>
 #include <sys/smp.h>
 #include <sys/sysctl.h>
 
@@ -55,11 +54,15 @@
 #ifdef SMP
 volatile cpuset_t stopped_cpus;
 volatile cpuset_t started_cpus;
+volatile cpuset_t suspended_cpus;
 cpuset_t hlt_cpus_mask;
 cpuset_t logical_cpus_mask;
 
 void (*cpustop_restartfunc)(void);
 #endif
+
+static int sysctl_kern_smp_active(SYSCTL_HANDLER_ARGS);
+
 /* This is used in modules that need to work in both SMP and UP. */
 cpuset_t all_cpus;
 
@@ -79,9 +82,8 @@
 SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxcpus,
     0, "Max number of CPUs that the system was compiled for.");
 
-int smp_active = 0;	/* are the APs allowed to run? */
-SYSCTL_INT(_kern_smp, OID_AUTO, active, CTLFLAG_RW, &smp_active, 0,
-    "Number of Auxillary Processors (APs) that were successfully started");
+SYSCTL_PROC(_kern_smp, OID_AUTO, active, CTLFLAG_RD | CTLTYPE_INT, NULL, 0,
+    sysctl_kern_smp_active, "I", "Indicates system is running in SMP mode");
 
 int smp_disabled = 0;	/* has smp been disabled? */
 SYSCTL_INT(_kern_smp, OID_AUTO, disabled, CTLFLAG_RDTUN|CTLFLAG_CAPRD,
@@ -147,7 +149,7 @@
 	}
 
 	cpu_mp_start();
-	printf("MidnightBSD/SMP: Multiprocessor System Detected: %d CPUs\n",
+	printf("FreeBSD/SMP: Multiprocessor System Detected: %d CPUs\n",
 	    mp_ncpus);
 	cpu_mp_announce();
 }
@@ -207,6 +209,7 @@
 #endif
 	static volatile u_int stopping_cpu = NOCPU;
 	int i;
+	volatile cpuset_t *cpus;
 
 	KASSERT(
 #if defined(__amd64__) || defined(__i386__)
@@ -222,6 +225,18 @@
 	CTR2(KTR_SMP, "stop_cpus(%s) with %u type",
 	    cpusetobj_strprint(cpusetbuf, &map), type);
 
+#if defined(__amd64__) || defined(__i386__)
+	/*
+	 * When suspending, ensure there are are no IPIs in progress.
+	 * IPIs that have been issued, but not yet delivered (e.g.
+	 * not pending on a vCPU when running under virtualization)
+	 * will be lost, violating FreeBSD's assumption of reliable
+	 * IPI delivery.
+	 */
+	if (type == IPI_SUSPEND)
+		mtx_lock_spin(&smp_ipi_mtx);
+#endif
+
 	if (stopping_cpu != PCPU_GET(cpuid))
 		while (atomic_cmpset_int(&stopping_cpu, NOCPU,
 		    PCPU_GET(cpuid)) == 0)
@@ -231,8 +246,15 @@
 	/* send the stop IPI to all CPUs in map */
 	ipi_selected(map, type);
 
+#if defined(__amd64__) || defined(__i386__)
+	if (type == IPI_SUSPEND)
+		cpus = &suspended_cpus;
+	else
+#endif
+		cpus = &stopped_cpus;
+
 	i = 0;
-	while (!CPU_SUBSET(&stopped_cpus, &map)) {
+	while (!CPU_SUBSET(cpus, &map)) {
 		/* spin */
 		cpu_spinwait();
 		i++;
@@ -242,6 +264,11 @@
 		}
 	}
 
+#if defined(__amd64__) || defined(__i386__)
+	if (type == IPI_SUSPEND)
+		mtx_unlock_spin(&smp_ipi_mtx);
+#endif
+
 	stopping_cpu = NOCPU;
 	return (1);
 }
@@ -282,28 +309,65 @@
  *   0: NA
  *   1: ok
  */
-int
-restart_cpus(cpuset_t map)
+static int
+generic_restart_cpus(cpuset_t map, u_int type)
 {
 #ifdef KTR
 	char cpusetbuf[CPUSETBUFSIZ];
 #endif
+	volatile cpuset_t *cpus;
 
+	KASSERT(
+#if defined(__amd64__) || defined(__i386__)
+	    type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND,
+#else
+	    type == IPI_STOP || type == IPI_STOP_HARD,
+#endif
+	    ("%s: invalid stop type", __func__));
+
 	if (!smp_started)
 		return 0;
 
 	CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map));
 
+#if defined(__amd64__) || defined(__i386__)
+	if (type == IPI_SUSPEND)
+		cpus = &resuming_cpus;
+	else
+#endif
+		cpus = &stopped_cpus;
+
 	/* signal other cpus to restart */
-	CPU_COPY_STORE_REL(&map, &started_cpus);
+#if defined(__amd64__) || defined(__i386__)
+	if (type == IPI_SUSPEND)
+		CPU_COPY_STORE_REL(&map, &toresume_cpus);
+	else
+#endif
+		CPU_COPY_STORE_REL(&map, &started_cpus);
 
 	/* wait for each to clear its bit */
-	while (CPU_OVERLAP(&stopped_cpus, &map))
+	while (CPU_OVERLAP(cpus, &map))
 		cpu_spinwait();
 
 	return 1;
 }
 
+int
+restart_cpus(cpuset_t map)
+{
+
+	return (generic_restart_cpus(map, IPI_STOP));
+}
+
+#if defined(__amd64__) || defined(__i386__)
+int
+resume_cpus(cpuset_t map)
+{
+
+	return (generic_restart_cpus(map, IPI_SUSPEND));
+}
+#endif
+
 /*
  * All-CPU rendezvous.  CPUs are signalled, all execute the setup function 
  * (if specified), rendezvous, execute the action function (if specified),
@@ -725,3 +789,65 @@
 	KASSERT((!smp_started),("smp_no_rendevous called and smp is started"));
 #endif
 }
+
+/*
+ * Wait specified idle threads to switch once.  This ensures that even
+ * preempted threads have cycled through the switch function once,
+ * exiting their codepaths.  This allows us to change global pointers
+ * with no other synchronization.
+ */
+int
+quiesce_cpus(cpuset_t map, const char *wmesg, int prio)
+{
+	struct pcpu *pcpu;
+	u_int gen[MAXCPU];
+	int error;
+	int cpu;
+
+	error = 0;
+	for (cpu = 0; cpu <= mp_maxid; cpu++) {
+		if (!CPU_ISSET(cpu, &map) || CPU_ABSENT(cpu))
+			continue;
+		pcpu = pcpu_find(cpu);
+		gen[cpu] = pcpu->pc_idlethread->td_generation;
+	}
+	for (cpu = 0; cpu <= mp_maxid; cpu++) {
+		if (!CPU_ISSET(cpu, &map) || CPU_ABSENT(cpu))
+			continue;
+		pcpu = pcpu_find(cpu);
+		thread_lock(curthread);
+		sched_bind(curthread, cpu);
+		thread_unlock(curthread);
+		while (gen[cpu] == pcpu->pc_idlethread->td_generation) {
+			error = tsleep(quiesce_cpus, prio, wmesg, 1);
+			if (error != EWOULDBLOCK)
+				goto out;
+			error = 0;
+		}
+	}
+out:
+	thread_lock(curthread);
+	sched_unbind(curthread);
+	thread_unlock(curthread);
+
+	return (error);
+}
+
+int
+quiesce_all_cpus(const char *wmesg, int prio)
+{
+
+	return quiesce_cpus(all_cpus, wmesg, prio);
+}
+
+/* Extra care is taken with this sysctl because the data type is volatile */
+static int
+sysctl_kern_smp_active(SYSCTL_HANDLER_ARGS)
+{
+	int error, active;
+
+	active = smp_started;
+	error = SYSCTL_OUT(req, &active, sizeof(active));
+	return (error);
+}
+

Modified: trunk/sys/kern/subr_stack.c
===================================================================
--- trunk/sys/kern/subr_stack.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_stack.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005 Antoine Brodin
  * All rights reserved.
@@ -27,7 +28,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_stack.c 227581 2011-11-16 19:06:55Z pjd $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -77,7 +78,7 @@
 }
 
 void
-stack_copy(struct stack *src, struct stack *dst)
+stack_copy(const struct stack *src, struct stack *dst)
 {
 
 	*dst = *src;
@@ -91,7 +92,7 @@
 }
 
 void
-stack_print(struct stack *st)
+stack_print(const struct stack *st)
 {
 	char namebuf[64];
 	long offset;
@@ -107,7 +108,7 @@
 }
 
 void
-stack_print_short(struct stack *st)
+stack_print_short(const struct stack *st)
 {
 	char namebuf[64];
 	long offset;
@@ -127,7 +128,7 @@
 }
 
 void
-stack_print_ddb(struct stack *st)
+stack_print_ddb(const struct stack *st)
 {
 	const char *name;
 	long offset;
@@ -143,7 +144,7 @@
 
 #ifdef DDB
 void
-stack_print_short_ddb(struct stack *st)
+stack_print_short_ddb(const struct stack *st)
 {
 	const char *name;
 	long offset;
@@ -167,7 +168,7 @@
  * other for use in the live kernel.
  */
 void
-stack_sbuf_print(struct sbuf *sb, struct stack *st)
+stack_sbuf_print(struct sbuf *sb, const struct stack *st)
 {
 	char namebuf[64];
 	long offset;
@@ -184,7 +185,7 @@
 
 #ifdef DDB
 void
-stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st)
+stack_sbuf_print_ddb(struct sbuf *sb, const struct stack *st)
 {
 	const char *name;
 	long offset;
@@ -201,8 +202,8 @@
 
 #ifdef KTR
 void
-stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth,
-    int cheap)
+stack_ktr(u_int mask, const char *file, int line, const struct stack *st,
+    u_int depth, int cheap)
 {
 #ifdef DDB
 	const char *name;

Modified: trunk/sys/kern/subr_syscall.c
===================================================================
--- trunk/sys/kern/subr_syscall.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_syscall.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (C) 1994, David Greenman
  * Copyright (c) 1990, 1993
@@ -42,9 +43,9 @@
 #include "opt_ktrace.h"
 #include "opt_kdtrace.h"
 
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_syscall.c 315949 2017-03-25 13:33:23Z badger $");
 
-#include <sys/capability.h>
+#include <sys/capsicum.h>
 #include <sys/ktr.h>
 #ifdef KTRACE
 #include <sys/uio.h>
@@ -64,30 +65,32 @@
 	td->td_pticks = 0;
 	if (td->td_ucred != p->p_ucred)
 		cred_update_thread(td);
-	if (p->p_flag & P_TRACED) {
-		traced = 1;
+	traced = (p->p_flag & P_TRACED) != 0;
+	if (traced || td->td_dbgflags & TDB_USERWR) {
 		PROC_LOCK(p);
 		td->td_dbgflags &= ~TDB_USERWR;
-		td->td_dbgflags |= TDB_SCE;
+		if (traced)
+			td->td_dbgflags |= TDB_SCE;
 		PROC_UNLOCK(p);
-	} else
-		traced = 0;
+	}
 	error = (p->p_sysent->sv_fetch_syscall_args)(td, sa);
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_SYSCALL))
 		ktrsyscall(sa->code, sa->narg, sa->args);
 #endif
+	KTR_START4(KTR_SYSC, "syscall", syscallname(p, sa->code),
+	    (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "arg0:%p", sa->args[0],
+	    "arg1:%p", sa->args[1], "arg2:%p", sa->args[2]);
 
-	CTR6(KTR_SYSC,
-"syscall: td=%p pid %d %s (%#lx, %#lx, %#lx)",
-	    td, td->td_proc->p_pid, syscallname(p, sa->code),
-	    sa->args[0], sa->args[1], sa->args[2]);
+	if (error == 0) {
 
-	if (error == 0) {
 		STOPEVENT(p, S_SCE, sa->narg);
-		if (p->p_flag & P_TRACED && p->p_stops & S_PT_SCE) {
+		if (p->p_flag & P_TRACED) {
 			PROC_LOCK(p);
-			ptracestop((td), SIGTRAP);
+			td->td_dbg_sc_code = sa->code;
+			td->td_dbg_sc_narg = sa->narg;
+			if (p->p_ptevents & PTRACE_SCE)
+				ptracestop((td), SIGTRAP, NULL);
 			PROC_UNLOCK(p);
 		}
 		if (td->td_dbgflags & TDB_USERWR) {
@@ -96,6 +99,10 @@
 			 * debugger modified registers or memory.
 			 */
 			error = (p->p_sysent->sv_fetch_syscall_args)(td, sa);
+			PROC_LOCK(p);
+			td->td_dbg_sc_code = sa->code;
+			td->td_dbg_sc_narg = sa->narg;
+			PROC_UNLOCK(p);
 #ifdef KTRACE
 			if (KTRPOINT(td, KTR_SYSCALL))
 				ktrsyscall(sa->code, sa->narg, sa->args);
@@ -150,10 +157,12 @@
 			    sa->callp, NULL, (error) ? -1 : td->td_retval[0]);
 #endif
 		syscall_thread_exit(td, sa->callp);
-		CTR4(KTR_SYSC, "syscall: p=%p error=%d return %#lx %#lx",
-		    p, error, td->td_retval[0], td->td_retval[1]);
 	}
  retval:
+	KTR_STOP4(KTR_SYSC, "syscall", syscallname(p, sa->code),
+	    (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "error:%d", error,
+	    "retval0:%#lx", td->td_retval[0], "retval1:%#lx",
+	    td->td_retval[1]);
 	if (traced) {
 		PROC_LOCK(p);
 		td->td_dbgflags &= ~TDB_SCE;
@@ -172,31 +181,10 @@
 	p = td->td_proc;
 
 	/*
-	 * Check for misbehavior.
-	 */
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    syscallname(p, sa->code));
-	KASSERT(td->td_critnest == 0,
-	    ("System call %s returning in a critical section",
-	    syscallname(p, sa->code)));
-	KASSERT(td->td_locks == 0,
-	    ("System call %s returning with %d locks held",
-	     syscallname(p, sa->code), td->td_locks));
-	KASSERT((td->td_pflags & TDP_NOFAULTING) == 0,
-	    ("System call %s returning with pagefaults disabled",
-	     syscallname(p, sa->code)));
-	KASSERT((td->td_pflags & TDP_NOSLEEPING) == 0,
-	    ("System call %s returning with sleep disabled",
-	     syscallname(p, sa->code)));
-
-	/*
 	 * Handle reschedule and other end-of-syscall issues
 	 */
 	userret(td, td->td_frame);
 
-	CTR4(KTR_SYSC, "syscall %s exit thread %p pid %d proc %s",
-	    syscallname(p, sa->code), td, td->td_proc->p_pid, td->td_name);
-
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_SYSRET)) {
 		ktrsysret(sa->code, (td->td_pflags & TDP_NERRNO) == 0 ?
@@ -228,8 +216,8 @@
 		 */
 		if (traced &&
 		    ((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 ||
-		    (p->p_stops & S_PT_SCX) != 0))
-			ptracestop(td, SIGTRAP);
+		    (p->p_ptevents & PTRACE_SCX) != 0))
+			ptracestop(td, SIGTRAP, NULL);
 		td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK);
 		PROC_UNLOCK(p);
 	}
@@ -247,9 +235,28 @@
 		 */
 		td->td_pflags &= ~TDP_RFPPWAIT;
 		p2 = td->td_rfppwait_p;
+again:
 		PROC_LOCK(p2);
-		while (p2->p_flag & P_PPWAIT)
-			cv_wait(&p2->p_pwait, &p2->p_mtx);
+		while (p2->p_flag & P_PPWAIT) {
+			PROC_LOCK(p);
+			if (thread_suspend_check_needed()) {
+				PROC_UNLOCK(p2);
+				thread_suspend_check(0);
+				PROC_UNLOCK(p);
+				goto again;
+			} else {
+				PROC_UNLOCK(p);
+			}
+			cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz);
+		}
 		PROC_UNLOCK(p2);
+
+		if (td->td_dbgflags & TDB_VFORK) {
+			PROC_LOCK(p);
+			if (p->p_ptevents & PTRACE_VFORK)
+				ptracestop(td, SIGTRAP, NULL);
+			td->td_dbgflags &= ~TDB_VFORK;
+			PROC_UNLOCK(p);
+		}
 	}
 }

Modified: trunk/sys/kern/subr_taskqueue.c
===================================================================
--- trunk/sys/kern/subr_taskqueue.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_taskqueue.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 Doug Rabson
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_taskqueue.c 315268 2017-03-14 16:00:33Z hselasky $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,6 +47,9 @@
 static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues");
 static void	*taskqueue_giant_ih;
 static void	*taskqueue_ih;
+static void	 taskqueue_fast_enqueue(void *);
+static void	 taskqueue_swi_enqueue(void *);
+static void	 taskqueue_swi_giant_enqueue(void *);
 
 struct taskqueue_busy {
 	struct task	*tb_running;
@@ -63,13 +67,16 @@
 	int			tq_spin;
 	int			tq_flags;
 	int			tq_callouts;
+	taskqueue_callback_fn	tq_callbacks[TASKQUEUE_NUM_CALLBACKS];
+	void			*tq_cb_contexts[TASKQUEUE_NUM_CALLBACKS];
 };
 
 #define	TQ_FLAGS_ACTIVE		(1 << 0)
 #define	TQ_FLAGS_BLOCKED	(1 << 1)
-#define	TQ_FLAGS_PENDING	(1 << 2)
+#define	TQ_FLAGS_UNLOCKED_ENQUEUE	(1 << 2)
 
 #define	DT_CALLOUT_ARMED	(1 << 0)
+#define	DT_DRAIN_IN_PROGRESS	(1 << 1)
 
 #define	TQ_LOCK(tq)							\
 	do {								\
@@ -78,6 +85,7 @@
 		else							\
 			mtx_lock(&(tq)->tq_mutex);			\
 	} while (0)
+#define	TQ_ASSERT_LOCKED(tq)	mtx_assert(&(tq)->tq_mutex, MA_OWNED)
 
 #define	TQ_UNLOCK(tq)							\
 	do {								\
@@ -86,6 +94,7 @@
 		else							\
 			mtx_unlock(&(tq)->tq_mutex);			\
 	} while (0)
+#define	TQ_ASSERT_UNLOCKED(tq)	mtx_assert(&(tq)->tq_mutex, MA_NOTOWNED)
 
 void
 _timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task,
@@ -93,7 +102,8 @@
 {
 
 	TASK_INIT(&timeout_task->t, priority, func, context);
-	callout_init_mtx(&timeout_task->c, &queue->tq_mutex, 0);
+	callout_init_mtx(&timeout_task->c, &queue->tq_mutex,
+	    CALLOUT_RETURNUNLOCKED);
 	timeout_task->q = queue;
 	timeout_task->f = 0;
 }
@@ -124,6 +134,11 @@
 	queue->tq_context = context;
 	queue->tq_spin = (mtxflags & MTX_SPIN) != 0;
 	queue->tq_flags |= TQ_FLAGS_ACTIVE;
+	if (enqueue == taskqueue_fast_enqueue ||
+	    enqueue == taskqueue_swi_enqueue ||
+	    enqueue == taskqueue_swi_giant_enqueue ||
+	    enqueue == taskqueue_thread_enqueue)
+		queue->tq_flags |= TQ_FLAGS_UNLOCKED_ENQUEUE;
 	mtx_init(&queue->tq_mutex, mtxname, NULL, mtxflags);
 
 	return queue;
@@ -137,6 +152,23 @@
 			MTX_DEF, "taskqueue");
 }
 
+void
+taskqueue_set_callback(struct taskqueue *queue,
+    enum taskqueue_callback_type cb_type, taskqueue_callback_fn callback,
+    void *context)
+{
+
+	KASSERT(((cb_type >= TASKQUEUE_CALLBACK_TYPE_MIN) &&
+	    (cb_type <= TASKQUEUE_CALLBACK_TYPE_MAX)),
+	    ("Callback type %d not valid, must be %d-%d", cb_type,
+	    TASKQUEUE_CALLBACK_TYPE_MIN, TASKQUEUE_CALLBACK_TYPE_MAX));
+	KASSERT((queue->tq_callbacks[cb_type] == NULL),
+	    ("Re-initialization of taskqueue callback?"));
+
+	queue->tq_callbacks[cb_type] = callback;
+	queue->tq_cb_contexts[cb_type] = context;
+}
+
 /*
  * Signal a taskqueue thread to terminate.
  */
@@ -176,6 +208,7 @@
 	if (task->ta_pending) {
 		if (task->ta_pending < USHRT_MAX)
 			task->ta_pending++;
+		TQ_UNLOCK(queue);
 		return (0);
 	}
 
@@ -199,11 +232,14 @@
 	}
 
 	task->ta_pending = 1;
+	if ((queue->tq_flags & TQ_FLAGS_UNLOCKED_ENQUEUE) != 0)
+		TQ_UNLOCK(queue);
 	if ((queue->tq_flags & TQ_FLAGS_BLOCKED) == 0)
 		queue->tq_enqueue(queue->tq_context);
-	else
-		queue->tq_flags |= TQ_FLAGS_PENDING;
+	if ((queue->tq_flags & TQ_FLAGS_UNLOCKED_ENQUEUE) == 0)
+		TQ_UNLOCK(queue);
 
+	/* Return with lock released. */
 	return (0);
 }
 int
@@ -213,7 +249,7 @@
 
 	TQ_LOCK(queue);
 	res = taskqueue_enqueue_locked(queue, task);
-	TQ_UNLOCK(queue);
+	/* The lock is released inside. */
 
 	return (res);
 }
@@ -230,6 +266,7 @@
 	timeout_task->f &= ~DT_CALLOUT_ARMED;
 	queue->tq_callouts--;
 	taskqueue_enqueue_locked(timeout_task->q, &timeout_task->t);
+	/* The lock is released inside. */
 }
 
 int
@@ -244,8 +281,13 @@
 	KASSERT(!queue->tq_spin, ("Timeout for spin-queue"));
 	timeout_task->q = queue;
 	res = timeout_task->t.ta_pending;
-	if (ticks == 0) {
+	if (timeout_task->f & DT_DRAIN_IN_PROGRESS) {
+		/* Do nothing */
+		TQ_UNLOCK(queue);
+		res = -1;
+	} else if (ticks == 0) {
 		taskqueue_enqueue_locked(queue, &timeout_task->t);
+		/* The lock is released inside. */
 	} else {
 		if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) {
 			res++;
@@ -259,11 +301,20 @@
 			callout_reset(&timeout_task->c, ticks,
 			    taskqueue_timeout_func, timeout_task);
 		}
+		TQ_UNLOCK(queue);
 	}
-	TQ_UNLOCK(queue);
 	return (res);
 }
 
+static void
+taskqueue_drain_running(struct taskqueue *queue)
+{
+
+	while (!TAILQ_EMPTY(&queue->tq_active))
+		TQ_SLEEP(queue, &queue->tq_active, &queue->tq_mutex,
+		    PWAIT, "-", 0);
+}
+
 void
 taskqueue_block(struct taskqueue *queue)
 {
@@ -279,10 +330,8 @@
 
 	TQ_LOCK(queue);
 	queue->tq_flags &= ~TQ_FLAGS_BLOCKED;
-	if (queue->tq_flags & TQ_FLAGS_PENDING) {
-		queue->tq_flags &= ~TQ_FLAGS_PENDING;
+	if (!STAILQ_EMPTY(&queue->tq_queue))
 		queue->tq_enqueue(queue->tq_context);
-	}
 	TQ_UNLOCK(queue);
 }
 
@@ -293,7 +342,7 @@
 	struct task *task;
 	int pending;
 
-	mtx_assert(&queue->tq_mutex, MA_OWNED);
+	TQ_ASSERT_LOCKED(queue);
 	tb.tb_running = NULL;
 	TAILQ_INSERT_TAIL(&queue->tq_active, &tb, tb_link);
 
@@ -316,6 +365,8 @@
 		wakeup(task);
 	}
 	TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
+	if (TAILQ_EMPTY(&queue->tq_active))
+		wakeup(&queue->tq_active);
 }
 
 void
@@ -332,7 +383,7 @@
 {
 	struct taskqueue_busy *tb;
 
-	mtx_assert(&queue->tq_mutex, MA_OWNED);
+	TQ_ASSERT_LOCKED(queue);
 	TAILQ_FOREACH(tb, &queue->tq_active, tb_link) {
 		if (tb->tb_running == task)
 			return (1);
@@ -340,6 +391,23 @@
 	return (0);
 }
 
+/*
+ * Only use this function in single threaded contexts. It returns
+ * non-zero if the given task is either pending or running. Else the
+ * task is idle and can be queued again or freed.
+ */
+int
+taskqueue_poll_is_busy(struct taskqueue *queue, struct task *task)
+{
+	int retval;
+
+	TQ_LOCK(queue);
+	retval = task->ta_pending > 0 || task_is_running(queue, task);
+	TQ_UNLOCK(queue);
+
+	return (retval);
+}
+
 static int
 taskqueue_cancel_locked(struct taskqueue *queue, struct task *task,
     u_int *pendp)
@@ -356,11 +424,9 @@
 int
 taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp)
 {
-	u_int pending;
 	int error;
 
 	TQ_LOCK(queue);
-	pending = task->ta_pending;
 	error = taskqueue_cancel_locked(queue, task, pendp);
 	TQ_UNLOCK(queue);
 
@@ -402,12 +468,64 @@
 }
 
 void
+taskqueue_drain_all(struct taskqueue *queue)
+{
+	struct task *task;
+
+	if (!queue->tq_spin)
+		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__);
+
+	TQ_LOCK(queue);
+	task = STAILQ_LAST(&queue->tq_queue, task, ta_link);
+	while (task != NULL && task->ta_pending != 0) {
+		struct task *oldtask;
+		TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+		/*
+		 * While we were asleeep the last entry may have been freed.
+		 * We need to check if it's still even in the queue.
+		 * Not perfect, but it's better than referencing bad memory.
+		 * first guess is the current 'end of queue' but if a new
+		 * item has been added we need to take the expensive path
+		 * Better fix in 11.
+		 */
+		oldtask = task;
+		if (oldtask !=
+		    (task = STAILQ_LAST(&queue->tq_queue, task, ta_link))) {
+			STAILQ_FOREACH(task, &queue->tq_queue, ta_link) {
+				if (task == oldtask)
+					break;
+			}
+		}
+	}
+	taskqueue_drain_running(queue);
+	KASSERT(STAILQ_EMPTY(&queue->tq_queue),
+	    ("taskqueue queue is not empty after draining"));
+	TQ_UNLOCK(queue);
+}
+
+void
 taskqueue_drain_timeout(struct taskqueue *queue,
     struct timeout_task *timeout_task)
 {
 
+	/*
+	 * Set flag to prevent timer from re-starting during drain:
+	 */
+	TQ_LOCK(queue);
+	KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0,
+	    ("Drain already in progress"));
+	timeout_task->f |= DT_DRAIN_IN_PROGRESS;
+	TQ_UNLOCK(queue);
+
 	callout_drain(&timeout_task->c);
 	taskqueue_drain(queue, &timeout_task->t);
+
+	/*
+	 * Clear flag to allow timer to re-start:
+	 */
+	TQ_LOCK(queue);
+	timeout_task->f &= ~DT_DRAIN_IN_PROGRESS;
+	TQ_UNLOCK(queue);
 }
 
 static void
@@ -489,6 +607,18 @@
 	return (0);
 }
 
+static inline void
+taskqueue_run_callback(struct taskqueue *tq,
+    enum taskqueue_callback_type cb_type)
+{
+	taskqueue_callback_fn tq_callback;
+
+	TQ_ASSERT_UNLOCKED(tq);
+	tq_callback = tq->tq_callbacks[cb_type];
+	if (tq_callback != NULL)
+		tq_callback(tq->tq_cb_contexts[cb_type]);
+}
+
 void
 taskqueue_thread_loop(void *arg)
 {
@@ -496,6 +626,7 @@
 
 	tqp = arg;
 	tq = *tqp;
+	taskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_INIT);
 	TQ_LOCK(tq);
 	while ((tq->tq_flags & TQ_FLAGS_ACTIVE) != 0) {
 		taskqueue_run_locked(tq);
@@ -510,6 +641,15 @@
 	}
 	taskqueue_run_locked(tq);
 
+	/*
+	 * This thread is on its way out, so just drop the lock temporarily
+	 * in order to call the shutdown callback.  This allows the callback
+	 * to look at the taskqueue, even just before it dies.
+	 */
+	TQ_UNLOCK(tq);
+	taskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_SHUTDOWN);
+	TQ_LOCK(tq);
+
 	/* rendezvous with thread that asked us to terminate */
 	tq->tq_tcount--;
 	wakeup_one(tq->tq_threads);
@@ -525,7 +665,6 @@
 	tqp = context;
 	tq = *tqp;
 
-	mtx_assert(&tq->tq_mutex, MA_OWNED);
 	wakeup_one(tq);
 }
 
@@ -577,7 +716,6 @@
 {
 	int i, j, ret = 0;
 
-	TQ_LOCK(queue);
 	for (i = 0, j = 0; ; i++) {
 		if (queue->tq_threads[i] == NULL)
 			continue;
@@ -588,6 +726,5 @@
 		if (++j >= queue->tq_tcount)
 			break;
 	}
-	TQ_UNLOCK(queue);
 	return (ret);
 }

Added: trunk/sys/kern/subr_terminal.c
===================================================================
--- trunk/sys/kern/subr_terminal.c	                        (rev 0)
+++ trunk/sys/kern/subr_terminal.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -0,0 +1,632 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Ed Schouten under sponsorship from the
+ * FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_terminal.c 274860 2014-11-22 16:55:55Z dumbbell $");
+
+#include <sys/param.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/terminal.h>
+#include <sys/tty.h>
+
+#include <machine/stdarg.h>
+
+static MALLOC_DEFINE(M_TERMINAL, "terminal", "terminal device");
+
+/*
+ * Locking.
+ *
+ * Normally we don't need to lock down the terminal emulator, because
+ * the TTY lock is already held when calling teken_input().
+ * Unfortunately this is not the case when the terminal acts as a
+ * console device, because cnputc() can be called at the same time.
+ * This means terminals may need to be locked down using a spin lock.
+ */
+#define	TERMINAL_LOCK(tm)	do {					\
+	if ((tm)->tm_flags & TF_CONS)					\
+		mtx_lock_spin(&(tm)->tm_mtx);				\
+	else if ((tm)->tm_tty != NULL)					\
+		tty_lock((tm)->tm_tty);					\
+} while (0)
+#define	TERMINAL_UNLOCK(tm)	do {					\
+	if ((tm)->tm_flags & TF_CONS)					\
+		mtx_unlock_spin(&(tm)->tm_mtx);				\
+	else if ((tm)->tm_tty != NULL)					\
+		tty_unlock((tm)->tm_tty);				\
+} while (0)
+#define	TERMINAL_LOCK_TTY(tm)	do {					\
+	if ((tm)->tm_flags & TF_CONS)					\
+		mtx_lock_spin(&(tm)->tm_mtx);				\
+} while (0)
+#define	TERMINAL_UNLOCK_TTY(tm)	do {					\
+	if ((tm)->tm_flags & TF_CONS)					\
+		mtx_unlock_spin(&(tm)->tm_mtx);				\
+} while (0)
+#define	TERMINAL_LOCK_CONS(tm)		mtx_lock_spin(&(tm)->tm_mtx)
+#define	TERMINAL_UNLOCK_CONS(tm)	mtx_unlock_spin(&(tm)->tm_mtx)
+
+/*
+ * TTY routines.
+ */
+
+static tsw_open_t	termtty_open;
+static tsw_close_t	termtty_close;
+static tsw_outwakeup_t	termtty_outwakeup;
+static tsw_ioctl_t	termtty_ioctl;
+static tsw_mmap_t	termtty_mmap;
+
+static struct ttydevsw terminal_tty_class = {
+	.tsw_open	= termtty_open,
+	.tsw_close	= termtty_close,
+	.tsw_outwakeup	= termtty_outwakeup,
+	.tsw_ioctl	= termtty_ioctl,
+	.tsw_mmap	= termtty_mmap,
+};
+
+/*
+ * Terminal emulator routines.
+ */
+
+static tf_bell_t	termteken_bell;
+static tf_cursor_t	termteken_cursor;
+static tf_putchar_t	termteken_putchar;
+static tf_fill_t	termteken_fill;
+static tf_copy_t	termteken_copy;
+static tf_param_t	termteken_param;
+static tf_respond_t	termteken_respond;
+
+static teken_funcs_t terminal_drawmethods = {
+	.tf_bell	= termteken_bell,
+	.tf_cursor	= termteken_cursor,
+	.tf_putchar	= termteken_putchar,
+	.tf_fill	= termteken_fill,
+	.tf_copy	= termteken_copy,
+	.tf_param	= termteken_param,
+	.tf_respond	= termteken_respond,
+};
+
+/* Kernel message formatting. */
+static const teken_attr_t kernel_message = {
+	.ta_fgcolor	= TCHAR_FGCOLOR(TERMINAL_KERN_ATTR),
+	.ta_bgcolor	= TCHAR_BGCOLOR(TERMINAL_KERN_ATTR),
+	.ta_format	= TCHAR_FORMAT(TERMINAL_KERN_ATTR)
+};
+
+static const teken_attr_t default_message = {
+	.ta_fgcolor	= TCHAR_FGCOLOR(TERMINAL_NORM_ATTR),
+	.ta_bgcolor	= TCHAR_BGCOLOR(TERMINAL_NORM_ATTR),
+	.ta_format	= TCHAR_FORMAT(TERMINAL_NORM_ATTR)
+};
+
+#define	TCHAR_CREATE(c, a)	((c) | TFORMAT((a)->ta_format) |	\
+	TCOLOR_FG(teken_256to8((a)->ta_fgcolor)) |			\
+	TCOLOR_BG(teken_256to8((a)->ta_bgcolor)))
+
+static void
+terminal_init(struct terminal *tm)
+{
+
+	if (tm->tm_flags & TF_CONS)
+		mtx_init(&tm->tm_mtx, "trmlck", NULL, MTX_SPIN);
+	teken_init(&tm->tm_emulator, &terminal_drawmethods, tm);
+	teken_set_defattr(&tm->tm_emulator, &default_message);
+}
+
+struct terminal *
+terminal_alloc(const struct terminal_class *tc, void *softc)
+{
+	struct terminal *tm;
+
+	tm = malloc(sizeof(struct terminal), M_TERMINAL, M_WAITOK|M_ZERO);
+	terminal_init(tm);
+
+	tm->tm_class = tc;
+	tm->tm_softc = softc;
+
+	return (tm);
+}
+
+static void
+terminal_sync_ttysize(struct terminal *tm)
+{
+	struct tty *tp;
+
+	tp = tm->tm_tty;
+	if (tp == NULL)
+		return;
+
+	tty_lock(tp);
+	tty_set_winsize(tp, &tm->tm_winsize);
+	tty_unlock(tp);
+}
+
+void
+terminal_maketty(struct terminal *tm, const char *fmt, ...)
+{
+	struct tty *tp;
+	char name[8];
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnrprintf(name, sizeof name, 32, fmt, ap);
+	va_end(ap);
+
+	tp = tty_alloc(&terminal_tty_class, tm);
+	tty_makedev(tp, NULL, "%s", name);
+	tm->tm_tty = tp;
+	terminal_sync_ttysize(tm);
+}
+
+void
+terminal_set_cursor(struct terminal *tm, const term_pos_t *pos)
+{
+
+	teken_set_cursor(&tm->tm_emulator, pos);
+}
+
+void
+terminal_set_winsize_blank(struct terminal *tm, const struct winsize *size,
+    int blank, const term_attr_t *attr)
+{
+	term_rect_t r;
+
+	tm->tm_winsize = *size;
+
+	r.tr_begin.tp_row = r.tr_begin.tp_col = 0;
+	r.tr_end.tp_row = size->ws_row;
+	r.tr_end.tp_col = size->ws_col;
+
+	TERMINAL_LOCK(tm);
+	if (blank == 0)
+		teken_set_winsize_noreset(&tm->tm_emulator, &r.tr_end);
+	else
+		teken_set_winsize(&tm->tm_emulator, &r.tr_end);
+	TERMINAL_UNLOCK(tm);
+
+	if ((blank != 0) && !(tm->tm_flags & TF_MUTE))
+		tm->tm_class->tc_fill(tm, &r,
+		    TCHAR_CREATE((teken_char_t)' ', attr));
+
+	terminal_sync_ttysize(tm);
+}
+
+void
+terminal_set_winsize(struct terminal *tm, const struct winsize *size)
+{
+
+	terminal_set_winsize_blank(tm, size, 1,
+	    (const term_attr_t *)&default_message);
+}
+
+/*
+ * XXX: This function is a kludge.  Drivers like vt(4) need to
+ * temporarily stop input when resizing, etc.  This should ideally be
+ * handled within the driver.
+ */
+
+void
+terminal_mute(struct terminal *tm, int yes)
+{
+
+	TERMINAL_LOCK(tm);
+	if (yes)
+		tm->tm_flags |= TF_MUTE;
+	else
+		tm->tm_flags &= ~TF_MUTE;
+	TERMINAL_UNLOCK(tm);
+}
+
+void
+terminal_input_char(struct terminal *tm, term_char_t c)
+{
+	struct tty *tp;
+
+	tp = tm->tm_tty;
+	if (tp == NULL)
+		return;
+
+	/*
+	 * Strip off any attributes. Also ignore input of second part of
+	 * CJK fullwidth characters, as we don't want to return these
+	 * characters twice.
+	 */
+	if (TCHAR_FORMAT(c) & TF_CJK_RIGHT)
+		return;
+	c = TCHAR_CHARACTER(c);
+
+	tty_lock(tp);
+	/*
+	 * Conversion to UTF-8.
+	 */
+	if (c < 0x80) {
+		ttydisc_rint(tp, c, 0);
+	} else if (c < 0x800) {
+		char str[2] = {
+			0xc0 | (c >> 6),
+			0x80 | (c & 0x3f)
+		};
+
+		ttydisc_rint_simple(tp, str, sizeof str);
+	} else if (c < 0x10000) {
+		char str[3] = {
+			0xe0 | (c >> 12),
+			0x80 | ((c >> 6) & 0x3f),
+			0x80 | (c & 0x3f)
+		};
+
+		ttydisc_rint_simple(tp, str, sizeof str);
+	} else {
+		char str[4] = {
+			0xf0 | (c >> 18),
+			0x80 | ((c >> 12) & 0x3f),
+			0x80 | ((c >> 6) & 0x3f),
+			0x80 | (c & 0x3f)
+		};
+
+		ttydisc_rint_simple(tp, str, sizeof str);
+	}
+	ttydisc_rint_done(tp);
+	tty_unlock(tp);
+}
+
+void
+terminal_input_raw(struct terminal *tm, char c)
+{
+	struct tty *tp;
+
+	tp = tm->tm_tty;
+	if (tp == NULL)
+		return;
+
+	tty_lock(tp);
+	ttydisc_rint(tp, c, 0);
+	ttydisc_rint_done(tp);
+	tty_unlock(tp);
+}
+
+void
+terminal_input_special(struct terminal *tm, unsigned int k)
+{
+	struct tty *tp;
+	const char *str;
+
+	tp = tm->tm_tty;
+	if (tp == NULL)
+		return;
+
+	str = teken_get_sequence(&tm->tm_emulator, k);
+	if (str == NULL)
+		return;
+
+	tty_lock(tp);
+	ttydisc_rint_simple(tp, str, strlen(str));
+	ttydisc_rint_done(tp);
+	tty_unlock(tp);
+}
+
+/*
+ * Binding with the TTY layer.
+ */
+
+static int
+termtty_open(struct tty *tp)
+{
+	struct terminal *tm = tty_softc(tp);
+
+	tm->tm_class->tc_opened(tm, 1);
+	return (0);
+}
+
+static void
+termtty_close(struct tty *tp)
+{
+	struct terminal *tm = tty_softc(tp);
+
+	tm->tm_class->tc_opened(tm, 0);
+}
+
+static void
+termtty_outwakeup(struct tty *tp)
+{
+	struct terminal *tm = tty_softc(tp);
+	char obuf[128];
+	size_t olen;
+	unsigned int flags = 0;
+
+	while ((olen = ttydisc_getc(tp, obuf, sizeof obuf)) > 0) {
+		TERMINAL_LOCK_TTY(tm);
+		if (!(tm->tm_flags & TF_MUTE)) {
+			tm->tm_flags &= ~TF_BELL;
+			teken_input(&tm->tm_emulator, obuf, olen);
+			flags |= tm->tm_flags;
+		}
+		TERMINAL_UNLOCK_TTY(tm);
+	}
+
+	tm->tm_class->tc_done(tm);
+	if (flags & TF_BELL)
+		tm->tm_class->tc_bell(tm);
+}
+
+static int
+termtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+{
+	struct terminal *tm = tty_softc(tp);
+	int error;
+
+	switch (cmd) {
+	case CONS_GETINFO: {
+		vid_info_t *vi = (vid_info_t *)data;
+		const teken_pos_t *p;
+		int fg, bg;
+
+		if (vi->size != sizeof(vid_info_t))
+			return (EINVAL);
+
+		/* Already help the console driver by filling in some data. */
+		p = teken_get_cursor(&tm->tm_emulator);
+		vi->mv_row = p->tp_row;
+		vi->mv_col = p->tp_col;
+
+		p = teken_get_winsize(&tm->tm_emulator);
+		vi->mv_rsz = p->tp_row;
+		vi->mv_csz = p->tp_col;
+
+		teken_get_defattr_cons25(&tm->tm_emulator, &fg, &bg);
+		vi->mv_norm.fore = fg;
+		vi->mv_norm.back = bg;
+		/* XXX: keep vidcontrol happy; bold backgrounds. */
+		vi->mv_rev.fore = bg;
+		vi->mv_rev.back = fg & 0x7;
+		break;
+	}
+	}
+
+	/*
+	 * Unlike various other drivers, this driver will never
+	 * deallocate TTYs.  This means it's safe to temporarily unlock
+	 * the TTY when handling ioctls.
+	 */
+	tty_unlock(tp);
+	error = tm->tm_class->tc_ioctl(tm, cmd, data, td);
+	tty_lock(tp);
+	return (error);
+}
+
+static int
+termtty_mmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t * paddr,
+    int nprot, vm_memattr_t *memattr)
+{
+	struct terminal *tm = tty_softc(tp);
+
+	return (tm->tm_class->tc_mmap(tm, offset, paddr, nprot, memattr));
+}
+
+/*
+ * Binding with the kernel and debug console.
+ */
+
+static cn_probe_t	termcn_cnprobe;
+static cn_init_t	termcn_cninit;
+static cn_term_t	termcn_cnterm;
+static cn_getc_t	termcn_cngetc;
+static cn_putc_t	termcn_cnputc;
+static cn_grab_t	termcn_cngrab;
+static cn_ungrab_t	termcn_cnungrab;
+
+const struct consdev_ops termcn_cnops = {
+	.cn_probe	= termcn_cnprobe,
+	.cn_init	= termcn_cninit,
+	.cn_term	= termcn_cnterm,
+	.cn_getc	= termcn_cngetc,
+	.cn_putc	= termcn_cnputc,
+	.cn_grab	= termcn_cngrab,
+	.cn_ungrab	= termcn_cnungrab,
+};
+
+void
+termcn_cnregister(struct terminal *tm)
+{
+	struct consdev *cp;
+
+	cp = tm->consdev;
+	if (cp == NULL) {
+		cp = malloc(sizeof(struct consdev), M_TERMINAL,
+		    M_WAITOK|M_ZERO);
+		cp->cn_ops = &termcn_cnops;
+		cp->cn_arg = tm;
+		cp->cn_pri = CN_INTERNAL;
+		sprintf(cp->cn_name, "ttyv0");
+
+		tm->tm_flags = TF_CONS;
+		tm->consdev = cp;
+
+		terminal_init(tm);
+	}
+
+	/* Attach terminal as console. */
+	cnadd(cp);
+}
+
+static void
+termcn_cngrab(struct consdev *cp)
+{
+	struct terminal *tm = cp->cn_arg;
+
+	tm->tm_class->tc_cngrab(tm);
+}
+
+static void
+termcn_cnungrab(struct consdev *cp)
+{
+	struct terminal *tm = cp->cn_arg;
+
+	tm->tm_class->tc_cnungrab(tm);
+}
+
+static void
+termcn_cnprobe(struct consdev *cp)
+{
+	struct terminal *tm = cp->cn_arg;
+
+	if (tm == NULL) {
+		cp->cn_pri = CN_DEAD;
+		return;
+	}
+
+	tm->consdev = cp;
+	terminal_init(tm);
+
+	tm->tm_class->tc_cnprobe(tm, cp);
+}
+
+static void
+termcn_cninit(struct consdev *cp)
+{
+
+}
+
+static void
+termcn_cnterm(struct consdev *cp)
+{
+
+}
+
+static int
+termcn_cngetc(struct consdev *cp)
+{
+	struct terminal *tm = cp->cn_arg;
+
+	return (tm->tm_class->tc_cngetc(tm));
+}
+
+static void
+termcn_cnputc(struct consdev *cp, int c)
+{
+	struct terminal *tm = cp->cn_arg;
+	teken_attr_t backup;
+	char cv = c;
+
+	TERMINAL_LOCK_CONS(tm);
+	if (!(tm->tm_flags & TF_MUTE)) {
+		backup = *teken_get_curattr(&tm->tm_emulator);
+		teken_set_curattr(&tm->tm_emulator, &kernel_message);
+		teken_input(&tm->tm_emulator, &cv, 1);
+		teken_set_curattr(&tm->tm_emulator, &backup);
+	}
+	TERMINAL_UNLOCK_CONS(tm);
+
+	tm->tm_class->tc_done(tm);
+}
+
+/*
+ * Binding with the terminal emulator.
+ */
+
+static void
+termteken_bell(void *softc)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_flags |= TF_BELL;
+}
+
+static void
+termteken_cursor(void *softc, const teken_pos_t *p)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_class->tc_cursor(tm, p);
+}
+
+static void
+termteken_putchar(void *softc, const teken_pos_t *p, teken_char_t c,
+    const teken_attr_t *a)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_class->tc_putchar(tm, p, TCHAR_CREATE(c, a));
+}
+
+static void
+termteken_fill(void *softc, const teken_rect_t *r, teken_char_t c,
+    const teken_attr_t *a)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_class->tc_fill(tm, r, TCHAR_CREATE(c, a));
+}
+
+static void
+termteken_copy(void *softc, const teken_rect_t *r, const teken_pos_t *p)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_class->tc_copy(tm, r, p);
+}
+
+static void
+termteken_param(void *softc, int cmd, unsigned int arg)
+{
+	struct terminal *tm = softc;
+
+	tm->tm_class->tc_param(tm, cmd, arg);
+}
+
+static void
+termteken_respond(void *softc, const void *buf, size_t len)
+{
+#if 0
+	struct terminal *tm = softc;
+	struct tty *tp;
+
+	/*
+	 * Only inject a response into the TTY if the data actually
+	 * originated from the TTY.
+	 *
+	 * XXX: This cannot be done right now.  The TTY could pick up
+	 * other locks.  It could also in theory cause loops, when the
+	 * TTY performs echoing of a command that generates even more
+	 * input.
+	 */
+	tp = tm->tm_tty;
+	if (tp == NULL)
+		return;
+
+	ttydisc_rint_simple(tp, buf, len);
+	ttydisc_rint_done(tp);
+#endif
+}


Property changes on: trunk/sys/kern/subr_terminal.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/kern/subr_trap.c
===================================================================
--- trunk/sys/kern/subr_trap.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_trap.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (C) 1994, David Greenman
  * Copyright (c) 1990, 1993
@@ -42,9 +43,8 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_trap.c 303607 2016-08-01 06:35:35Z kib $");
 
-#include "opt_capsicum.h"
 #include "opt_hwpmc_hooks.h"
 #include "opt_ktrace.h"
 #include "opt_kdtrace.h"
@@ -52,7 +52,7 @@
 
 #include <sys/param.h>
 #include <sys/bus.h>
-#include <sys/capability.h>
+#include <sys/capsicum.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -61,6 +61,7 @@
 #include <sys/ktr.h>
 #include <sys/pioctl.h>
 #include <sys/ptrace.h>
+#include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/sched.h>
 #include <sys/signalvar.h>
@@ -93,6 +94,8 @@
 
 #include <security/mac/mac_framework.h>
 
+void (*softdep_ast_cleanup)(void);
+
 /*
  * Define the code needed before returning to user mode, for trap and
  * syscall.
@@ -106,21 +109,36 @@
             td->td_name);
 	KASSERT((p->p_flag & P_WEXIT) == 0,
 	    ("Exiting process returns to usermode"));
-#if 0
 #ifdef DIAGNOSTIC
-	/* Check that we called signotify() enough. */
-	PROC_LOCK(p);
-	thread_lock(td);
-	if (SIGPENDING(td) && ((td->td_flags & TDF_NEEDSIGCHK) == 0 ||
-	    (td->td_flags & TDF_ASTPENDING) == 0))
-		printf("failed to set signal flags properly for ast()\n");
-	thread_unlock(td);
-	PROC_UNLOCK(p);
+	/*
+	 * Check that we called signotify() enough.  For
+	 * multi-threaded processes, where signal distribution might
+	 * change due to other threads changing sigmask, the check is
+	 * racy and cannot be performed reliably.
+	 * If current process is vfork child, indicated by P_PPWAIT, then
+	 * issignal() ignores stops, so we block the check to avoid
+	 * classifying pending signals.
+	 */
+	if (p->p_numthreads == 1) {
+		PROC_LOCK(p);
+		thread_lock(td);
+		if ((p->p_flag & P_PPWAIT) == 0) {
+			KASSERT(!SIGPENDING(td) || (td->td_flags &
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING)) ==
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING),
+			    ("failed to set signal flags for ast p %p "
+			    "td %p fl %x", p, td, td->td_flags));
+		}
+		thread_unlock(td);
+		PROC_UNLOCK(p);
+	}
 #endif
-#endif
 #ifdef KTRACE
 	KTRUSERRET(td);
 #endif
+	if (softdep_ast_cleanup != NULL)
+		softdep_ast_cleanup();
+
 	/*
 	 * If this thread tickled GEOM, we need to wait for the giggling to
 	 * stop before we return to userland
@@ -137,12 +155,35 @@
 	 * Let the scheduler adjust our priority etc.
 	 */
 	sched_userret(td);
+#ifdef XEN
+	PT_UPDATES_FLUSH();
+#endif
+
+	/*
+	 * Check for misbehavior.
+	 *
+	 * In case there is a callchain tracing ongoing because of
+	 * hwpmc(4), skip the scheduler pinning check.
+	 * hwpmc(4) subsystem, infact, will collect callchain informations
+	 * at ast() checkpoint, which is past userret().
+	 */
+	WITNESS_WARN(WARN_PANIC, NULL, "userret: returning");
+	KASSERT(td->td_critnest == 0,
+	    ("userret: Returning in a critical section"));
 	KASSERT(td->td_locks == 0,
-	    ("userret: Returning with %d locks held.", td->td_locks));
+	    ("userret: Returning with %d locks held", td->td_locks));
+	KASSERT((td->td_pflags & TDP_NOFAULTING) == 0,
+	    ("userret: Returning with pagefaults disabled"));
+	KASSERT(td->td_no_sleeping == 0,
+	    ("userret: Returning with sleep disabled"));
+	KASSERT(td->td_pinned == 0 || (td->td_pflags & TDP_CALLCHAIN) != 0,
+	    ("userret: Returning with with pinned thread"));
 	KASSERT(td->td_vp_reserv == 0,
 	    ("userret: Returning while holding vnode reservation"));
 	KASSERT((td->td_flags & TDF_SBDRY) == 0,
 	    ("userret: Returning with stop signals deferred"));
+	KASSERT(td->td_su == NULL,
+	    ("userret: Returning with SU cleanup request not handled"));
 #ifdef VIMAGE
 	/* Unfortunately td_vnet_lpush needs VNET_DEBUG. */
 	VNET_ASSERT(curvnet == NULL,
@@ -150,15 +191,14 @@
 	    __func__, td, p->p_pid, td->td_name, curvnet,
 	    (td->td_vnet_lpush != NULL) ? td->td_vnet_lpush : "N/A"));
 #endif
-#ifdef XEN
-	PT_UPDATES_FLUSH();
+#ifdef RACCT
+	if (racct_enable) {
+		PROC_LOCK(p);
+		while (p->p_throttled == 1)
+			msleep(p->p_racct, &p->p_mtx, 0, "racct", 0);
+		PROC_UNLOCK(p);
+	}
 #endif
-#ifdef	RACCT
-	PROC_LOCK(p);
-	while (p->p_throttled == 1)
-		msleep(p->p_racct, &p->p_mtx, 0, "racct", 0);
-	PROC_UNLOCK(p);
-#endif
 }
 
 /*
@@ -241,6 +281,29 @@
 #endif
 	}
 
+#ifdef DIAGNOSTIC
+	if (p->p_numthreads == 1 && (flags & TDF_NEEDSIGCHK) == 0) {
+		PROC_LOCK(p);
+		thread_lock(td);
+		/*
+		 * Note that TDF_NEEDSIGCHK should be re-read from
+		 * td_flags, since signal might have been delivered
+		 * after we cleared td_flags above.  This is one of
+		 * the reason for looping check for AST condition.
+		 * See comment in userret() about P_PPWAIT.
+		 */
+		if ((p->p_flag & P_PPWAIT) == 0) {
+			KASSERT(!SIGPENDING(td) || (td->td_flags &
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING)) ==
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING),
+			    ("failed2 to set signal flags for ast p %p td %p "
+			    "fl %x %x", p, td, flags, td->td_flags));
+		}
+		thread_unlock(td);
+		PROC_UNLOCK(p);
+	}
+#endif
+
 	/*
 	 * Check for signals. Unlocked reads of p_pendingcnt or
 	 * p_siglist might cause process-directed signal to be handled
@@ -250,7 +313,7 @@
 	    !SIGISEMPTY(p->p_siglist)) {
 		PROC_LOCK(p);
 		mtx_lock(&p->p_sigacts->ps_mtx);
-		while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0)
+		while ((sig = cursig(td)) != 0)
 			postsig(sig);
 		mtx_unlock(&p->p_sigacts->ps_mtx);
 		PROC_UNLOCK(p);
@@ -271,7 +334,6 @@
 	}
 
 	userret(td, framep);
-	mtx_assert(&Giant, MA_NOTOWNED);
 }
 
 const char *

Modified: trunk/sys/kern/subr_turnstile.c
===================================================================
--- trunk/sys/kern/subr_turnstile.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_turnstile.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
  *
@@ -25,8 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	from BSDI $Id: subr_turnstile.c,v 1.4 2012-10-09 04:08:16 laffer1 Exp $
- *	and BSDI $Id: subr_turnstile.c,v 1.4 2012-10-09 04:08:16 laffer1 Exp $
+ *	from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
+ *	and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
  */
 
 /*
@@ -57,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_turnstile.c 296728 2016-03-12 17:17:34Z kib $");
 
 #include "opt_ddb.h"
 #include "opt_kdtrace.h"
@@ -170,8 +171,8 @@
 static void	turnstile_fini(void *mem, int size);
 
 SDT_PROVIDER_DECLARE(sched);
-SDT_PROBE_DEFINE(sched, , , sleep, sleep);
-SDT_PROBE_DEFINE2(sched, , , wakeup, wakeup, "struct thread *", 
+SDT_PROBE_DEFINE(sched, , , sleep);
+SDT_PROBE_DEFINE2(sched, , , wakeup, "struct thread *", 
     "struct proc *");
 
 /*
@@ -215,10 +216,9 @@
 
 		/*
 		 * If the thread is asleep, then we are probably about
-		 * to deadlock.  To make debugging this easier, just
-		 * panic and tell the user which thread misbehaved so
-		 * they can hopefully get a stack trace from the truly
-		 * misbehaving thread.
+		 * to deadlock.  To make debugging this easier, show
+		 * backtrace of misbehaving thread and panic to not
+		 * leave the kernel deadlocked.
 		 */
 		if (TD_IS_SLEEPING(td)) {
 			printf(
@@ -1028,8 +1028,7 @@
 {
 
 	db_printf("%s%p (tid %d, pid %d, \"%s\")\n", prefix, td, td->td_tid,
-	    td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name :
-	    td->td_name);
+	    td->td_proc->p_pid, td->td_name);
 }
 
 static void
@@ -1111,8 +1110,7 @@
 	 */
 	while (!db_pager_quit) {
 		db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
-		    td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name :
-		    td->td_name);
+		    td->td_proc->p_pid, td->td_name);
 		switch (td->td_state) {
 		case TDS_INACTIVE:
 			db_printf("is inactive\n");
@@ -1195,8 +1193,7 @@
 	 */
 	while (!db_pager_quit) {
 		db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
-		    td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name :
-		    td->td_name);
+		    td->td_proc->p_pid, td->td_name);
 		switch (td->td_state) {
 		case TDS_INACTIVE:
 			db_printf("is inactive\n");

Modified: trunk/sys/kern/subr_uio.c
===================================================================
--- trunk/sys/kern/subr_uio.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_uio.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1982, 1986, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -7,6 +8,11 @@
  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  * the permission of UNIX System Laboratories, Inc.
  *
+ * Copyright (c) 2014 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -35,10 +41,8 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_uio.c 308103 2016-10-30 11:45:01Z kib $");
 
-#include "opt_zero.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -45,9 +49,9 @@
 #include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/mman.h>
-#include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
+#include <sys/rwlock.h>
 #include <sys/sched.h>
 #include <sys/sysctl.h>
 #include <sys/vnode.h>
@@ -56,80 +60,16 @@
 #include <vm/vm_param.h>
 #include <vm/vm_extern.h>
 #include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
 #include <vm/vm_map.h>
-#ifdef ZERO_COPY_SOCKETS
-#include <vm/vm_object.h>
-#endif
 
-SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, NULL, UIO_MAXIOV,
+#include <machine/bus.h>
+
+SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, UIO_MAXIOV,
 	"Maximum number of elements in an I/O vector; sysconf(_SC_IOV_MAX)");
 
 static int uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault);
 
-#ifdef ZERO_COPY_SOCKETS
-/* Declared in uipc_socket.c */
-extern int so_zero_copy_receive;
-
-/*
- * Identify the physical page mapped at the given kernel virtual
- * address.  Insert this physical page into the given address space at
- * the given virtual address, replacing the physical page, if any,
- * that already exists there.
- */
-static int
-vm_pgmoveco(vm_map_t mapa, vm_offset_t kaddr, vm_offset_t uaddr)
-{
-	vm_map_t map = mapa;
-	vm_page_t kern_pg, user_pg;
-	vm_object_t uobject;
-	vm_map_entry_t entry;
-	vm_pindex_t upindex;
-	vm_prot_t prot;
-	boolean_t wired;
-
-	KASSERT((uaddr & PAGE_MASK) == 0,
-	    ("vm_pgmoveco: uaddr is not page aligned"));
-
-	/*
-	 * Herein the physical page is validated and dirtied.  It is
-	 * unwired in sf_buf_mext().
-	 */
-	kern_pg = PHYS_TO_VM_PAGE(vtophys(kaddr));
-	kern_pg->valid = VM_PAGE_BITS_ALL;
-	KASSERT(kern_pg->queue == PQ_NONE && kern_pg->wire_count == 1,
-	    ("vm_pgmoveco: kern_pg is not correctly wired"));
-
-	if ((vm_map_lookup(&map, uaddr,
-			   VM_PROT_WRITE, &entry, &uobject,
-			   &upindex, &prot, &wired)) != KERN_SUCCESS) {
-		return(EFAULT);
-	}
-	VM_OBJECT_LOCK(uobject);
-retry:
-	if ((user_pg = vm_page_lookup(uobject, upindex)) != NULL) {
-		if (vm_page_sleep_if_busy(user_pg, TRUE, "vm_pgmoveco"))
-			goto retry;
-		vm_page_lock(user_pg);
-		pmap_remove_all(user_pg);
-		vm_page_free(user_pg);
-		vm_page_unlock(user_pg);
-	} else {
-		/*
-		 * Even if a physical page does not exist in the
-		 * object chain's first object, a physical page from a
-		 * backing object may be mapped read only.
-		 */
-		if (uobject->backing_object != NULL)
-			pmap_remove(map->pmap, uaddr, uaddr + PAGE_SIZE);
-	}
-	vm_page_insert(kern_pg, uobject, upindex);
-	vm_page_dirty(kern_pg);
-	VM_OBJECT_UNLOCK(uobject);
-	vm_map_lookup_done(map, entry);
-	return(KERN_SUCCESS);
-}
-#endif /* ZERO_COPY_SOCKETS */
-
 int
 copyin_nofault(const void *udaddr, void *kaddr, size_t len)
 {
@@ -152,7 +92,105 @@
 	return (error);
 }
 
+#define	PHYS_PAGE_COUNT(len)	(howmany(len, PAGE_SIZE) + 1)
+
 int
+physcopyin(void *src, vm_paddr_t dst, size_t len)
+{
+	vm_page_t m[PHYS_PAGE_COUNT(len)];
+	struct iovec iov[1];
+	struct uio uio;
+	int i;
+
+	iov[0].iov_base = src;
+	iov[0].iov_len = len;
+	uio.uio_iov = iov;
+	uio.uio_iovcnt = 1;
+	uio.uio_offset = 0;
+	uio.uio_resid = len;
+	uio.uio_segflg = UIO_SYSSPACE;
+	uio.uio_rw = UIO_WRITE;
+	for (i = 0; i < PHYS_PAGE_COUNT(len); i++, dst += PAGE_SIZE)
+		m[i] = PHYS_TO_VM_PAGE(dst);
+	return (uiomove_fromphys(m, dst & PAGE_MASK, len, &uio));
+}
+
+int
+physcopyout(vm_paddr_t src, void *dst, size_t len)
+{
+	vm_page_t m[PHYS_PAGE_COUNT(len)];
+	struct iovec iov[1];
+	struct uio uio;
+	int i;
+
+	iov[0].iov_base = dst;
+	iov[0].iov_len = len;
+	uio.uio_iov = iov;
+	uio.uio_iovcnt = 1;
+	uio.uio_offset = 0;
+	uio.uio_resid = len;
+	uio.uio_segflg = UIO_SYSSPACE;
+	uio.uio_rw = UIO_READ;
+	for (i = 0; i < PHYS_PAGE_COUNT(len); i++, src += PAGE_SIZE)
+		m[i] = PHYS_TO_VM_PAGE(src);
+	return (uiomove_fromphys(m, src & PAGE_MASK, len, &uio));
+}
+
+#undef PHYS_PAGE_COUNT
+
+int
+physcopyin_vlist(bus_dma_segment_t *src, off_t offset, vm_paddr_t dst,
+    size_t len)
+{
+	size_t seg_len;
+	int error;
+
+	error = 0;
+	while (offset >= src->ds_len) {
+		offset -= src->ds_len;
+		src++;
+	}
+
+	while (len > 0 && error == 0) {
+		seg_len = MIN(src->ds_len - offset, len);
+		error = physcopyin((void *)(uintptr_t)(src->ds_addr + offset),
+		    dst, seg_len);
+		offset = 0;
+		src++;
+		len -= seg_len;
+		dst += seg_len;
+	}
+
+	return (error);
+}
+
+int
+physcopyout_vlist(vm_paddr_t src, bus_dma_segment_t *dst, off_t offset,
+    size_t len)
+{
+	size_t seg_len;
+	int error;
+
+	error = 0;
+	while (offset >= dst->ds_len) {
+		offset -= dst->ds_len;
+		dst++;
+	}
+
+	while (len > 0 && error == 0) {
+		seg_len = MIN(dst->ds_len - offset, len);
+		error = physcopyout(src, (void *)(uintptr_t)(dst->ds_addr +
+		    offset), seg_len);
+		offset = 0;
+		dst++;
+		len -= seg_len;
+		src += seg_len;
+	}
+
+	return (error);
+}
+
+int
 uiomove(void *cp, int n, struct uio *uio)
 {
 
@@ -261,104 +299,7 @@
 	return (uiomove((char *)buf + offset, n, uio));
 }
 
-#ifdef ZERO_COPY_SOCKETS
 /*
- * Experimental support for zero-copy I/O
- */
-static int
-userspaceco(void *cp, u_int cnt, struct uio *uio, int disposable)
-{
-	struct iovec *iov;
-	int error;
-
-	iov = uio->uio_iov;
-	if (uio->uio_rw == UIO_READ) {
-		if ((so_zero_copy_receive != 0)
-		 && ((cnt & PAGE_MASK) == 0)
-		 && ((((intptr_t) iov->iov_base) & PAGE_MASK) == 0)
-		 && ((uio->uio_offset & PAGE_MASK) == 0)
-		 && ((((intptr_t) cp) & PAGE_MASK) == 0)
-		 && (disposable != 0)) {
-			/* SOCKET: use page-trading */
-			/*
-			 * We only want to call vm_pgmoveco() on
-			 * disposeable pages, since it gives the
-			 * kernel page to the userland process.
-			 */
-			error =	vm_pgmoveco(&curproc->p_vmspace->vm_map,
-			    (vm_offset_t)cp, (vm_offset_t)iov->iov_base);
-
-			/*
-			 * If we get an error back, attempt
-			 * to use copyout() instead.  The
-			 * disposable page should be freed
-			 * automatically if we weren't able to move
-			 * it into userland.
-			 */
-			if (error != 0)
-				error = copyout(cp, iov->iov_base, cnt);
-		} else {
-			error = copyout(cp, iov->iov_base, cnt);
-		}
-	} else {
-		error = copyin(iov->iov_base, cp, cnt);
-	}
-	return (error);
-}
-
-int
-uiomoveco(void *cp, int n, struct uio *uio, int disposable)
-{
-	struct iovec *iov;
-	u_int cnt;
-	int error;
-
-	KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
-	    ("uiomoveco: mode"));
-	KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
-	    ("uiomoveco proc"));
-
-	while (n > 0 && uio->uio_resid) {
-		iov = uio->uio_iov;
-		cnt = iov->iov_len;
-		if (cnt == 0) {
-			uio->uio_iov++;
-			uio->uio_iovcnt--;
-			continue;
-		}
-		if (cnt > n)
-			cnt = n;
-
-		switch (uio->uio_segflg) {
-
-		case UIO_USERSPACE:
-			maybe_yield();
-			error = userspaceco(cp, cnt, uio, disposable);
-			if (error)
-				return (error);
-			break;
-
-		case UIO_SYSSPACE:
-			if (uio->uio_rw == UIO_READ)
-				bcopy(cp, iov->iov_base, cnt);
-			else
-				bcopy(iov->iov_base, cp, cnt);
-			break;
-		case UIO_NOCOPY:
-			break;
-		}
-		iov->iov_base = (char *)iov->iov_base + cnt;
-		iov->iov_len -= cnt;
-		uio->uio_resid -= cnt;
-		uio->uio_offset += cnt;
-		cp = (char *)cp + cnt;
-		n -= cnt;
-	}
-	return (0);
-}
-#endif /* ZERO_COPY_SOCKETS */
-
-/*
  * Give next character to user as result of read.
  */
 int
@@ -389,7 +330,6 @@
 	case UIO_SYSSPACE:
 		iov_base = iov->iov_base;
 		*iov_base = c;
-		iov->iov_base = iov_base;
 		break;
 
 	case UIO_NOCOPY:
@@ -441,7 +381,7 @@
 }
 
 int
-copyiniov(struct iovec *iovp, u_int iovcnt, struct iovec **iov, int error)
+copyiniov(const struct iovec *iovp, u_int iovcnt, struct iovec **iov, int error)
 {
 	u_int iovlen;
 
@@ -459,7 +399,7 @@
 }
 
 int
-copyinuio(struct iovec *iovp, u_int iovcnt, struct uio **uiop)
+copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop)
 {
 	struct iovec *iov;
 	struct uio *uio;
@@ -529,7 +469,7 @@
 	    lim_max(td->td_proc, RLIMIT_DATA));
 	PROC_UNLOCK(td->td_proc);
 
-	/* round size up to page boundry */
+	/* round size up to page boundary */
 	size = (vm_size_t)round_page(sz);
 
 	error = vm_mmap(&vms->vm_map, addr, size, PROT_READ | PROT_WRITE,
@@ -558,3 +498,128 @@
 
 	return (0);
 }
+
+#ifdef NO_FUEWORD
+/*
+ * XXXKIB The temporal implementation of fue*() functions which do not
+ * handle usermode -1 properly, mixing it with the fault code.  Keep
+ * this until MD code is written.  Currently sparc64, mips and arm do
+ * not have proper implementation.
+ */
+
+int
+fueword(volatile const void *base, long *val)
+{
+	long res;
+
+	res = fuword(base);
+	if (res == -1)
+		return (-1);
+	*val = res;
+	return (0);
+}
+
+int
+fueword32(volatile const void *base, int32_t *val)
+{
+	int32_t res;
+
+	res = fuword32(base);
+	if (res == -1)
+		return (-1);
+	*val = res;
+	return (0);
+}
+
+#ifdef _LP64
+int
+fueword64(volatile const void *base, int64_t *val)
+{
+	int64_t res;
+
+	res = fuword64(base);
+	if (res == -1)
+		return (-1);
+	*val = res;
+	return (0);
+}
+#endif
+
+int
+casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
+    uint32_t newval)
+{
+	int32_t ov;
+
+	ov = casuword32(base, oldval, newval);
+	if (ov == -1)
+		return (-1);
+	*oldvalp = ov;
+	return (0);
+}
+
+int
+casueword(volatile u_long *p, u_long oldval, u_long *oldvalp, u_long newval)
+{
+	u_long ov;
+
+	ov = casuword(p, oldval, newval);
+	if (ov == -1)
+		return (-1);
+	*oldvalp = ov;
+	return (0);
+}
+#else /* NO_FUEWORD */
+int32_t
+fuword32(volatile const void *addr)
+{
+	int rv;
+	int32_t val;
+
+	rv = fueword32(addr, &val);
+	return (rv == -1 ? -1 : val);
+}
+
+#ifdef _LP64
+int64_t
+fuword64(volatile const void *addr)
+{
+	int rv;
+	int64_t val;
+
+	rv = fueword64(addr, &val);
+	return (rv == -1 ? -1 : val);
+}
+#endif /* _LP64 */
+
+long
+fuword(volatile const void *addr)
+{
+	long val;
+	int rv;
+
+	rv = fueword(addr, &val);
+	return (rv == -1 ? -1 : val);
+}
+
+uint32_t
+casuword32(volatile uint32_t *addr, uint32_t old, uint32_t new)
+{
+	int rv;
+	uint32_t val;
+
+	rv = casueword32(addr, old, &val, new);
+	return (rv == -1 ? -1 : val);
+}
+
+u_long
+casuword(volatile u_long *addr, u_long old, u_long new)
+{
+	int rv;
+	u_long val;
+
+	rv = casueword(addr, old, &val, new);
+	return (rv == -1 ? -1 : val);
+}
+
+#endif /* NO_FUEWORD */

Modified: trunk/sys/kern/subr_unit.c
===================================================================
--- trunk/sys/kern/subr_unit.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_unit.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Poul-Henning Kamp
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/kern/subr_unit.c 312325 2017-01-17 01:58:50Z ngie $
  *
  *
  * Unit number allocation functions.
@@ -68,8 +69,8 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/bitstring.h>
+#include <sys/_unrhdr.h>
 
 #ifdef _KERNEL
 
@@ -187,28 +188,12 @@
 /* Number of bits in the bitmap */
 #define NBITS	((int)sizeof(((struct unrb *)NULL)->map) * 8)
 
-/* Header element for a unr number space. */
-
-struct unrhdr {
-	TAILQ_HEAD(unrhd,unr)	head;
-	u_int			low;	/* Lowest item */
-	u_int			high;	/* Highest item */
-	u_int			busy;	/* Count of allocated items */
-	u_int			alloc;	/* Count of memory allocations */
-	u_int			first;	/* items in allocated from start */
-	u_int			last;	/* items free at end */
-	struct mtx		*mtx;
-	TAILQ_HEAD(unrfr,unr)	ppfree;	/* Items to be freed after mtx
-					   lock dropped */
-};
-
-
 #if defined(DIAGNOSTIC) || !defined(_KERNEL)
 /*
  * Consistency check function.
  *
  * Checks the internal consistency as well as we can.
- * 
+ *
  * Called at all boundaries of this API.
  */
 static void
@@ -236,7 +221,7 @@
 			    ("UNR inconsistency: busy %u found %u (line %d)\n",
 			    ub->busy, w, line));
 			y += w;
-		} else if (up->ptr != NULL) 
+		} else if (up->ptr != NULL)
 			y += up->len;
 	}
 	KASSERT (y == uh->busy,
@@ -315,20 +300,12 @@
 	mtx_unlock(uh->mtx);
 }
 
-/*
- * Allocate a new unrheader set.
- *
- * Highest and lowest valid values given as parameters.
- */
-
-struct unrhdr *
-new_unrhdr(int low, int high, struct mtx *mutex)
+void
+init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex)
 {
-	struct unrhdr *uh;
 
 	KASSERT(low >= 0 && low <= high,
 	    ("UNR: use error: new_unrhdr(%d, %d)", low, high));
-	uh = Malloc(sizeof *uh);
 	if (mutex != NULL)
 		uh->mtx = mutex;
 	else
@@ -340,6 +317,21 @@
 	uh->first = 0;
 	uh->last = 1 + (high - low);
 	check_unrhdr(uh, __LINE__);
+}
+
+/*
+ * Allocate a new unrheader set.
+ *
+ * Highest and lowest valid values given as parameters.
+ */
+
+struct unrhdr *
+new_unrhdr(int low, int high, struct mtx *mutex)
+{
+	struct unrhdr *uh;
+
+	uh = Malloc(sizeof *uh);
+	init_unrhdr(uh, low, high, mutex);
 	return (uh);
 }
 
@@ -364,7 +356,7 @@
 /*
  * Look for sequence of items which can be combined into a bitmap, if
  * multiple are present, take the one which saves most memory.
- * 
+ *
  * Return (1) if a sequence was found to indicate that another call
  * might be able to do more.  Return (0) if we found no suitable sequence.
  *
@@ -591,7 +583,7 @@
 	}
 
 	/*
-	 * We can always allocate from the first list element, so if we have 
+	 * We can always allocate from the first list element, so if we have
 	 * nothing on the list, we must have run out of unit numbers.
 	 */
 	if (up == NULL)
@@ -806,7 +798,7 @@
 	/* Handle bitmap items */
 	if (is_bitmap(uh, up)) {
 		ub = up->ptr;
-		
+
 		KASSERT(bit_test(ub->map, item) != 0,
 		    ("UNR: Freeing free item %d (bitmap)\n", item));
 		bit_clear(ub->map, item);
@@ -909,7 +901,7 @@
 		for (x = 0; x < up->len; x++) {
 			if (bit_test(ub->map, x))
 				printf("#");
-			else 
+			else
 				printf(" ");
 		}
 		printf("]\n");

Modified: trunk/sys/kern/subr_witness.c
===================================================================
--- trunk/sys/kern/subr_witness.c	2018-05-26 14:26:33 UTC (rev 9955)
+++ trunk/sys/kern/subr_witness.c	2018-05-26 14:27:13 UTC (rev 9956)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 Isilon Systems, Inc.
  * Copyright (c) 2008 Ilya Maykov <ivmaykov at gmail.com>
@@ -28,8 +29,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	from BSDI $Id: subr_witness.c,v 1.9 2012-10-09 04:08:16 laffer1 Exp $
- *	and BSDI $Id: subr_witness.c,v 1.9 2012-10-09 04:08:16 laffer1 Exp $
+ *	from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
+ *	and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
  */
 
 /*
@@ -85,7 +86,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/kern/subr_witness.c 309871 2016-12-12 02:24:46Z markj $");
 
 #include "opt_ddb.h"
 #include "opt_hwpmc_hooks.h"
@@ -135,7 +136,7 @@
 #define	WITNESS_COUNT 		1024
 #define	WITNESS_CHILDCOUNT 	(WITNESS_COUNT * 4)
 #define	WITNESS_HASH_SIZE	251	/* Prime, gives load factor < 2 */
-#define	WITNESS_PENDLIST	768
+#define	WITNESS_PENDLIST	(1024 + MAXCPU)
 
 /* Allocate 256 KB of stack data space */
 #define	WITNESS_LO_DATA_COUNT	2048
@@ -305,13 +306,6 @@
 }
 
 static __inline int
-witness_lock_order_key_empty(const struct witness_lock_order_key *key)
-{
-
-	return (key->from == 0 && key->to == 0);
-}
-
-static __inline int
 witness_lock_order_key_equal(const struct witness_lock_order_key *a,
     const struct witness_lock_order_key *b)
 {
@@ -332,7 +326,7 @@
 static struct witness	*enroll(const char *description,
 			    struct lock_class *lock_class);
 static struct lock_instance	*find_instance(struct lock_list_entry *list,
-				    struct lock_object *lock);
+				    const struct lock_object *lock);
 static int	isitmychild(struct witness *parent, struct witness *child);
 static int	isitmydescendant(struct witness *parent, struct witness *child);
 static void	itismychild(struct witness *parent, struct witness *child);
@@ -498,6 +492,11 @@
 	{ "time lock", &lock_class_mtx_sleep },
 	{ NULL, NULL },
 	/*
+	 * umtx
+	 */
+	{ "umtx lock", &lock_class_mtx_sleep },
+	{ NULL, NULL },
+	/*
 	 * Sockets
 	 */
 	{ "accept", &lock_class_mtx_sleep },
@@ -520,7 +519,7 @@
 	{ "udpinp", &lock_class_rw },
 	{ "in_multi_mtx", &lock_class_mtx_sleep },
 	{ "igmp_mtx", &lock_class_mtx_sleep },
-	{ "if_addr_mtx", &lock_class_mtx_sleep },
+	{ "if_addr_lock", &lock_class_rw },
 	{ NULL, NULL },
 	/*
 	 * IPv6 multicast:
@@ -529,12 +528,12 @@
 	{ "udpinp", &lock_class_rw },
 	{ "in6_multi_mtx", &lock_class_mtx_sleep },
 	{ "mld_mtx", &lock_class_mtx_sleep },
-	{ "if_addr_mtx", &lock_class_mtx_sleep },
+	{ "if_addr_lock", &lock_class_rw },
 	{ NULL, NULL },
 	/*
 	 * UNIX Domain Sockets
 	 */
-	{ "unp_global_rwlock", &lock_class_rw },
+	{ "unp_link_rwlock", &lock_class_rw },
 	{ "unp_list_lock", &lock_class_mtx_sleep },
 	{ "unp", &lock_class_mtx_sleep },
 	{ "so_snd", &lock_class_mtx_sleep },
@@ -594,7 +593,7 @@
 	 * CDEV
 	 */
 	{ "vm map (system)", &lock_class_mtx_sleep },
-	{ "vm page queue", &lock_class_mtx_sleep },
+	{ "vm pagequeue", &lock_class_mtx_sleep },
 	{ "vnode interlock", &lock_class_mtx_sleep },
 	{ "cdev", &lock_class_mtx_sleep },
 	{ NULL, NULL },
@@ -602,9 +601,9 @@
 	 * VM
 	 */
 	{ "vm map (user)", &lock_class_sx },
-	{ "vm object", &lock_class_mtx_sleep },
+	{ "vm object", &lock_class_rw },
 	{ "vm page", &lock_class_mtx_sleep },
-	{ "vm page queue", &lock_class_mtx_sleep },
+	{ "vm pagequeue", &lock_class_mtx_sleep },
 	{ "pmap pv global", &lock_class_rw },
 	{ "pmap", &lock_class_mtx_sleep },
 	{ "pmap pv list", &lock_class_rw },
@@ -649,7 +648,6 @@
 #endif
 	{ "process slock", &lock_class_mtx_spin },
 	{ "sleepq chain", &lock_class_mtx_spin },
-	{ "umtx lock", &lock_class_mtx_spin },
 	{ "rm_spinlock", &lock_class_mtx_spin },
 	{ "turnstile chain", &lock_class_mtx_spin },
 	{ "turnstile lock", &lock_class_mtx_spin },
@@ -669,6 +667,9 @@
 	 */
 	{ "intrcnt", &lock_class_mtx_spin },
 	{ "icu", &lock_class_mtx_spin },
+#if defined(SMP) && defined(__sparc64__)
+	{ "ipi", &lock_class_mtx_spin },
+#endif
 #ifdef __i386__
 	{ "allpmaps", &lock_class_mtx_spin },
 	{ "descriptor tables", &lock_class_mtx_spin },
@@ -822,16 +823,16 @@
 	class = LOCK_CLASS(lock);
 	if ((lock->lo_flags & LO_RECURSABLE) != 0 &&
 	    (class->lc_flags & LC_RECURSABLE) == 0)
-		panic("%s: lock (%s) %s can not be recursable", __func__,
-		    class->lc_name, lock->lo_name);
+		kassert_panic("%s: lock (%s) %s can not be recursable",
+		    __func__, class->lc_name, lock->lo_name);
 	if ((lock->lo_flags & LO_SLEEPABLE) != 0 &&
 	    (class->lc_flags & LC_SLEEPABLE) == 0)
-		panic("%s: lock (%s) %s can not be sleepable", __func__,
-		    class->lc_name, lock->lo_name);
+		kassert_panic("%s: lock (%s) %s can not be sleepable",
+		    __func__, class->lc_name, lock->lo_name);
 	if ((lock->lo_flags & LO_UPGRADABLE) != 0 &&
 	    (class->lc_flags & LC_UPGRADABLE) == 0)
-		panic("%s: lock (%s) %s can not be upgradable", __func__,
-		    class->lc_name, lock->lo_name);
+		kassert_panic("%s: lock (%s) %s can not be upgradable",
+		    __func__, class->lc_name, lock->lo_name);
 
 	/*
 	 * If we shouldn't watch this lock, then just clear lo_witness.
@@ -847,7 +848,8 @@
 		pending_locks[pending_cnt].wh_lock = lock;
 		pending_locks[pending_cnt++].wh_type = type;
 		if (pending_cnt > WITNESS_PENDLIST)
-			panic("%s: pending locks list is too small, bump it\n",
+			panic("%s: pending locks list is too small, "
+			    "increase WITNESS_PENDLIST\n",
 			    __func__);
 	} else
 		lock->lo_witness = enroll(type, class);
@@ -1052,7 +1054,7 @@
 {
 	struct lock_list_entry *lock_list, *lle;
 	struct lock_instance *lock1, *lock2, *plock;
-	struct lock_class *class;
+	struct lock_class *class, *iclass;
 	struct witness *w, *w1;
 	struct thread *td;
 	int i, j;
@@ -1073,7 +1075,8 @@
 		 * all spin locks.
 		 */
 		if (td->td_critnest != 0 && !kdb_active)
-			panic("blockable sleep lock (%s) %s @ %s:%d",
+			kassert_panic("acquiring blockable sleep lock with "
+			    "spinlock or critical section held (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 
@@ -1117,7 +1120,7 @@
 			    fixup_filename(file), line);
 			printf("while exclusively locked from %s:%d\n",
 			    fixup_filename(lock1->li_file), lock1->li_line);
-			panic("share->excl");
+			kassert_panic("excl->share");
 		}
 		if ((lock1->li_flags & LI_EXCLUSIVE) == 0 &&
 		    (flags & LOP_EXCLUSIVE) != 0) {
@@ -1126,11 +1129,25 @@
 			    fixup_filename(file), line);
 			printf("while share locked from %s:%d\n",
 			    fixup_filename(lock1->li_file), lock1->li_line);
-			panic("excl->share");
+			kassert_panic("share->excl");
 		}
 		return;
 	}
 
+	/* Warn if the interlock is not locked exactly once. */
+	if (interlock != NULL) {
+		iclass = LOCK_CLASS(interlock);
+		lock1 = find_instance(lock_list, interlock);
+		if (lock1 == NULL)
+			kassert_panic("interlock (%s) %s not locked @ %s:%d",
+			    iclass->lc_name, interlock->lo_name,
+			    fixup_filename(file), line);
+		else if ((lock1->li_flags & LI_RECURSEMASK) != 0)
+			kassert_panic("interlock (%s) %s recursed @ %s:%d",
+			    iclass->lc_name, interlock->lo_name,
+			    fixup_filename(file), line);
+	}
+
 	/*
 	 * Find the previously acquired lock, but ignore interlocks.
 	 */
@@ -1154,19 +1171,25 @@
 	
 	/*
 	 * Try to perform most checks without a lock.  If this succeeds we
-	 * can skip acquiring the lock and return success.
+	 * can skip acquiring the lock and return success.  Otherwise we redo
+	 * the check with the lock held to handle races with concurrent updates.
 	 */
 	w1 = plock->li_lock->lo_witness;
 	if (witness_lock_order_check(w1, w))
 		return;
 
+	mtx_lock_spin(&w_mtx);
+	if (witness_lock_order_check(w1, w)) {
+		mtx_unlock_spin(&w_mtx);
+		return;
+	}
+	witness_lock_order_add(w1, w);
+
 	/*
 	 * Check for duplicate locks of the same type.  Note that we only
 	 * have to check for this on the last lock we just acquired.  Any
 	 * other cases will be caught as lock order violations.
 	 */
-	mtx_lock_spin(&w_mtx);
-	witness_lock_order_add(w1, w);
 	if (w1 == w) {
 		i = w->w_index;
 		if (!(lock->lo_flags & LO_DUPOK) && !(flags & LOP_DUPOK) &&
@@ -1199,16 +1222,14 @@
 	for (j = 0, lle = lock_list; lle != NULL; lle = lle->ll_next) {
 		for (i = lle->ll_count - 1; i >= 0; i--, j++) {
 
-			MPASS(j < WITNESS_COUNT);
+			MPASS(j < LOCK_CHILDCOUNT * LOCK_NCHILDREN);
 			lock1 = &lle->ll_children[i];
 
 			/*
-			 * Ignore the interlock the first time we see it.
+			 * Ignore the interlock.
 			 */
-			if (interlock != NULL && interlock == lock1->li_lock) {
-				interlock = NULL;
+			if (interlock == lock1->li_lock)
 				continue;
-			}
 
 			/*
 			 * If this lock doesn't undergo witness checking,
@@ -1287,8 +1308,20 @@
 			w->w_reversed = w1->w_reversed = 1;
 			witness_increment_graph_generation();
 			mtx_unlock_spin(&w_mtx);
-			
+
+#ifdef WITNESS_NO_VNODE
 			/*
+			 * There are known LORs between VNODE locks. They are
+			 * not an indication of a bug. VNODE locks are flagged
+			 * as such (LO_IS_VNODE) and we don't yell if the LOR
+			 * is between 2 VNODE locks.
+			 */
+			if ((lock->lo_flags & LO_IS_VNODE) != 0 &&
+			    (lock1->li_lock->lo_flags & LO_IS_VNODE) != 0)
+				return;
+#endif
+
+			/*
 			 * Ok, yell about it.
 			 */
 			if (((lock->lo_flags & LO_SLEEPABLE) != 0 &&
@@ -1433,26 +1466,32 @@
 	class = LOCK_CLASS(lock);
 	if (witness_watch) {
 		if ((lock->lo_flags & LO_UPGRADABLE) == 0)
-			panic("upgrade of non-upgradable lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "upgrade of non-upgradable lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((class->lc_flags & LC_SLEEPLOCK) == 0)
-			panic("upgrade of non-sleep lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "upgrade of non-sleep lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 	}
 	instance = find_instance(curthread->td_sleeplocks, lock);
-	if (instance == NULL)
-		panic("upgrade of unlocked lock (%s) %s @ %s:%d",
+	if (instance == NULL) {
+		kassert_panic("upgrade of unlocked lock (%s) %s @ %s:%d",
 		    class->lc_name, lock->lo_name,
 		    fixup_filename(file), line);
+		return;
+	}
 	if (witness_watch) {
 		if ((instance->li_flags & LI_EXCLUSIVE) != 0)
-			panic("upgrade of exclusive lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "upgrade of exclusive lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((instance->li_flags & LI_RECURSEMASK) != 0)
-			panic("upgrade of recursed lock (%s) %s r=%d @ %s:%d",
+			kassert_panic(
+			    "upgrade of recursed lock (%s) %s r=%d @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    instance->li_flags & LI_RECURSEMASK,
 			    fixup_filename(file), line);
@@ -1473,26 +1512,32 @@
 	class = LOCK_CLASS(lock);
 	if (witness_watch) {
 		if ((lock->lo_flags & LO_UPGRADABLE) == 0)
-		panic("downgrade of non-upgradable lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "downgrade of non-upgradable lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((class->lc_flags & LC_SLEEPLOCK) == 0)
-			panic("downgrade of non-sleep lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "downgrade of non-sleep lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 	}
 	instance = find_instance(curthread->td_sleeplocks, lock);
-	if (instance == NULL)
-		panic("downgrade of unlocked lock (%s) %s @ %s:%d",
+	if (instance == NULL) {
+		kassert_panic("downgrade of unlocked lock (%s) %s @ %s:%d",
 		    class->lc_name, lock->lo_name,
 		    fixup_filename(file), line);
+		return;
+	}
 	if (witness_watch) {
 		if ((instance->li_flags & LI_EXCLUSIVE) == 0)
-			panic("downgrade of shared lock (%s) %s @ %s:%d",
+			kassert_panic(
+			    "downgrade of shared lock (%s) %s @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((instance->li_flags & LI_RECURSEMASK) != 0)
-			panic("downgrade of recursed lock (%s) %s r=%d @ %s:%d",
+			kassert_panic(
+			    "downgrade of recursed lock (%s) %s r=%d @ %s:%d",
 			    class->lc_name, lock->lo_name,
 			    instance->li_flags & LI_RECURSEMASK,
 			    fixup_filename(file), line);
@@ -1534,11 +1579,13 @@
 	 * We have to make sure we flush these queues, so just search for
 	 * eventual register locks and remove them.
 	 */
-	if (witness_watch > 0)
-		panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
+	if (witness_watch > 0) {
+		kassert_panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
 		    lock->lo_name, fixup_filename(file), line);
-	else
 		return;
+	} else {
+		return;
+	}
 found:
 
 	/* First, check for shared/exclusive mismatches. */
@@ -1548,7 +1595,7 @@
 		    lock->lo_name, fixup_filename(file), line);
 		printf("while exclusively locked from %s:%d\n",
 		    fixup_filename(instance->li_file), instance->li_line);
-		panic("excl->ushare");
+		kassert_panic("excl->ushare");
 	}
 	if ((instance->li_flags & LI_EXCLUSIVE) == 0 && witness_watch > 0 &&
 	    (flags & LOP_EXCLUSIVE) != 0) {
@@ -1557,7 +1604,7 @@
 		printf("while share locked from %s:%d\n",
 		    fixup_filename(instance->li_file),
 		    instance->li_line);
-		panic("share->uexcl");
+		kassert_panic("share->uexcl");
 	}
 	/* If we are recursed, unrecurse. */
 	if ((instance->li_flags & LI_RECURSEMASK) > 0) {
@@ -1571,7 +1618,7 @@
 	if ((instance->li_flags & LI_NORELEASE) != 0 && witness_watch > 0) {
 		printf("forbidden unlock of (%s) %s @ %s:%d\n", class->lc_name,
 		    lock->lo_name, fixup_filename(file), line);
-		panic("lock marked norelease");
+		kassert_panic("lock marked norelease");
 	}
 
 	/* Otherwise, remove this item from the list. */
@@ -1626,7 +1673,8 @@
 				witness_list_lock(&lle->ll_children[i], printf);
 				
 			}
-		panic("Thread %p cannot exit while holding sleeplocks\n", td);
+		kassert_panic(
+		    "Thread %p cannot exit while holding sleeplocks\n", td);
 	}
 	witness_lock_list_free(lle);
 }
@@ -1707,7 +1755,7 @@
 	} else
 		sched_unpin();
 	if (flags & WARN_PANIC && n)
-		panic("%s", __func__);
+		kassert_panic("%s", __func__);
 	else
 		witness_debugger(n);
 	return (n);
@@ -1750,11 +1798,13 @@
 			return (NULL);
 		else
 			typelist = &w_spin;
-	} else if ((lock_class->lc_flags & LC_SLEEPLOCK))
+	} else if ((lock_class->lc_flags & LC_SLEEPLOCK)) {
 		typelist = &w_sleep;
-	else
-		panic("lock class %s is not sleep or spin",
+	} else {
+		kassert_panic("lock class %s is not sleep or spin",
 		    lock_class->lc_name);
+		return (NULL);
+	}
 
 	mtx_lock_spin(&w_mtx);
 	w = witness_hash_get(description);
@@ -1784,7 +1834,7 @@
 	w->w_refcount++;
 	mtx_unlock_spin(&w_mtx);
 	if (lock_class != w->w_class)
-		panic(
+		kassert_panic(
 			"lock (%s) %s does not match earlier (%s) lock",
 			description, lock_class->lc_name,
 			w->w_class->lc_name);
@@ -1910,6 +1960,7 @@
 static void
 itismychild(struct witness *parent, struct witness *child)
 {
+	int unlocked;
 
 	MPASS(child != NULL && parent != NULL);
 	if (witness_cold == 0)
@@ -1916,12 +1967,19 @@
 		mtx_assert(&w_mtx, MA_OWNED);
 
 	if (!witness_lock_type_equal(parent, child)) {
-		if (witness_cold == 0)
+		if (witness_cold == 0) {
+			unlocked = 1;
 			mtx_unlock_spin(&w_mtx);
-		panic("%s: parent \"%s\" (%s) and child \"%s\" (%s) are not "
+		} else {
+			unlocked = 0;
+		}
+		kassert_panic(
+		    "%s: parent \"%s\" (%s) and child \"%s\" (%s) are not "
 		    "the same lock type", __func__, parent->w_name,
 		    parent->w_class->lc_name, child->w_name,
 		    child->w_class->lc_name);
+		if (unlocked)
+			mtx_lock_spin(&w_mtx);
 	}
 	adopt(parent, child);
 }
@@ -1945,7 +2003,10 @@
 
 	/* The flags on one better be the inverse of the flags on the other */
 	if (!((WITNESS_ATOD(r1) == r2 && WITNESS_DTOA(r2) == r1) ||
-		(WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) {
+	    (WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) {
+		/* Don't squawk if we're potentially racing with an update. */
+		if (!mtx_owned(&w_mtx))
+			return (0);
 		printf("%s: rmatrix mismatch between %s (index %d) and %s "
 		    "(index %d): w_rmatrix[%d][%d] == %hhx but "
 		    "w_rmatrix[%d][%d] == %hhx\n",
@@ -2073,7 +2134,7 @@
 }
 
 static struct lock_instance *
-find_instance(struct lock_list_entry *list, struct lock_object *lock)
+find_instance(struct lock_list_entry *list, const struct lock_object *lock)
 {
 	struct lock_list_entry *lle;
 	struct lock_instance *instance;
@@ -2191,9 +2252,11 @@
 		lock_list = PCPU_GET(spinlocks);
 	}
 	instance = find_instance(lock_list, lock);
-	if (instance == NULL)
-		panic("%s: lock (%s) %s not locked", __func__,
+	if (instance == NULL) {
+		kassert_panic("%s: lock (%s) %s not locked", __func__,
 		    class->lc_name, lock->lo_name);
+		return;
+	}
 	*filep = instance->li_file;
 	*linep = instance->li_line;
 }
@@ -2225,16 +2288,19 @@
 	}
 	instance = find_instance(lock_list, lock);
 	if (instance == NULL)
-		panic("%s: lock (%s) %s not locked", __func__,
+		kassert_panic("%s: lock (%s) %s not locked", __func__,
 		    class->lc_name, lock->lo_name);
 	lock->lo_witness->w_file = file;
 	lock->lo_witness->w_line = line;
+	if (instance == NULL)
+		return;
 	instance->li_file = file;
 	instance->li_line = line;
 }
 
 void
-witness_assert(struct lock_object *lock, int flags, const char *file, int line)
+witness_assert(const struct lock_object *lock, int flags, const char *file,
+    int line)
 {
 #ifdef INVARIANT_SUPPORT
 	struct lock_instance *instance;
@@ -2248,13 +2314,14 @@
 	else if ((class->lc_flags & LC_SPINLOCK) != 0)
 		instance = find_instance(PCPU_GET(spinlocks), lock);
 	else {
-		panic("Lock (%s) %s is not sleep or spin!",
+		kassert_panic("Lock (%s) %s is not sleep or spin!",
 		    class->lc_name, lock->lo_name);
+		return;
 	}
 	switch (flags) {
 	case LA_UNLOCKED:
 		if (instance != NULL)
-			panic("Lock (%s) %s locked @ %s:%d.",
+			kassert_panic("Lock (%s) %s locked @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		break;
@@ -2268,7 +2335,7 @@
 	case LA_XLOCKED | LA_RECURSED:
 	case LA_XLOCKED | LA_NOTRECURSED:
 		if (instance == NULL) {
-			panic("Lock (%s) %s not locked @ %s:%d.",
+			kassert_panic("Lock (%s) %s not locked @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 			break;
@@ -2275,27 +2342,29 @@
 		}
 		if ((flags & LA_XLOCKED) != 0 &&
 		    (instance->li_flags & LI_EXCLUSIVE) == 0)
-			panic("Lock (%s) %s not exclusively locked @ %s:%d.",
+			kassert_panic(
+			    "Lock (%s) %s not exclusively locked @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((flags & LA_SLOCKED) != 0 &&
 		    (instance->li_flags & LI_EXCLUSIVE) != 0)
-			panic("Lock (%s) %s exclusively locked @ %s:%d.",
+			kassert_panic(
+			    "Lock (%s) %s exclusively locked @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((flags & LA_RECURSED) != 0 &&
 		    (instance->li_flags & LI_RECURSEMASK) == 0)
-			panic("Lock (%s) %s not recursed @ %s:%d.",
+			kassert_panic("Lock (%s) %s not recursed @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		if ((flags & LA_NOTRECURSED) != 0 &&
 		    (instance->li_flags & LI_RECURSEMASK) != 0)
-			panic("Lock (%s) %s recursed @ %s:%d.",
+			kassert_panic("Lock (%s) %s recursed @ %s:%d.",
 			    class->lc_name, lock->lo_name,
 			    fixup_filename(file), line);
 		break;
 	default:
-		panic("Invalid lock assertion at %s:%d.",
+		kassert_panic("Invalid lock assertion at %s:%d.",
 		    fixup_filename(file), line);
 
 	}
@@ -2320,9 +2389,11 @@
 		lock_list = PCPU_GET(spinlocks);
 	}
 	instance = find_instance(lock_list, lock);
-	if (instance == NULL)
-		panic("%s: lock (%s) %s not locked", __func__,
+	if (instance == NULL) {
+		kassert_panic("%s: lock (%s) %s not locked", __func__,
 		    class->lc_name, lock->lo_name);
+		return;
+	}
 
 	if (set)
 		instance->li_flags |= flag;
@@ -2828,7 +2899,7 @@
 	return (1);
 }
 
-/* Call this whenver the structure of the witness graph changes. */
+/* Call this whenever the structure of the witness graph changes. */
 static void
 witness_increment_graph_generation(void)
 {



More information about the Midnightbsd-cvs mailing list