Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Jul 2004 20:28:19 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 56333 for review
Message-ID:  <200407022028.i62KSJN6042063@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=56333

Change 56333 by jhb@jhb_slimer on 2004/07/02 20:28:06

	IFC @56332.  Loop back kernel preemption.

Affected files ...

.. //depot/projects/smpng/sys/alpha/alpha/interrupt.c#28 integrate
.. //depot/projects/smpng/sys/alpha/include/param.h#9 integrate
.. //depot/projects/smpng/sys/amd64/amd64/intr_machdep.c#3 integrate
.. //depot/projects/smpng/sys/amd64/include/param.h#9 integrate
.. //depot/projects/smpng/sys/conf/NOTES#72 integrate
.. //depot/projects/smpng/sys/conf/files#113 integrate
.. //depot/projects/smpng/sys/conf/options#79 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_ec.c#31 integrate
.. //depot/projects/smpng/sys/geom/label/g_label.c#1 branch
.. //depot/projects/smpng/sys/geom/label/g_label.h#1 branch
.. //depot/projects/smpng/sys/geom/label/g_label_iso9660.c#1 branch
.. //depot/projects/smpng/sys/geom/label/g_label_msdosfs.c#1 branch
.. //depot/projects/smpng/sys/geom/label/g_label_ufs.c#1 branch
.. //depot/projects/smpng/sys/i386/i386/intr_machdep.c#6 integrate
.. //depot/projects/smpng/sys/i386/include/param.h#12 integrate
.. //depot/projects/smpng/sys/ia64/ia64/interrupt.c#26 integrate
.. //depot/projects/smpng/sys/kern/kern_intr.c#48 integrate
.. //depot/projects/smpng/sys/kern/kern_mutex.c#79 integrate
.. //depot/projects/smpng/sys/kern/kern_shutdown.c#42 integrate
.. //depot/projects/smpng/sys/kern/kern_switch.c#36 integrate
.. //depot/projects/smpng/sys/kern/kern_synch.c#72 integrate
.. //depot/projects/smpng/sys/kern/sched_4bsd.c#28 integrate
.. //depot/projects/smpng/sys/kern/sched_ule.c#32 integrate
.. //depot/projects/smpng/sys/modules/geom/Makefile#8 integrate
.. //depot/projects/smpng/sys/modules/geom/geom_label/Makefile#1 branch
.. //depot/projects/smpng/sys/net/if_ethersubr.c#50 integrate
.. //depot/projects/smpng/sys/powerpc/powerpc/intr_machdep.c#6 integrate
.. //depot/projects/smpng/sys/sparc64/sparc64/intr_machdep.c#21 integrate
.. //depot/projects/smpng/sys/sys/interrupt.h#13 integrate
.. //depot/projects/smpng/sys/sys/proc.h#118 integrate
.. //depot/projects/smpng/sys/vm/vm_zeroidle.c#17 integrate

Differences ...

==== //depot/projects/smpng/sys/alpha/alpha/interrupt.c#28 (text+ko) ====

@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 /* __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $");*/
-__FBSDID("$FreeBSD: src/sys/alpha/alpha/interrupt.c,v 1.78 2004/04/16 20:09:53 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/alpha/alpha/interrupt.c,v 1.79 2004/07/02 20:21:41 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -455,7 +455,7 @@
 	 * thread to the current CPU until we return from the interrupt.
 	 */
 	sched_pin();
-	error = ithread_schedule(ithd, !cold);
+	error = ithread_schedule(ithd);
 	KASSERT(error == 0, ("got an impossible stray interrupt"));
 	sched_unpin();
 }

==== //depot/projects/smpng/sys/alpha/include/param.h#9 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/alpha/include/param.h,v 1.33 2004/04/05 21:00:50 imp Exp $ */
+/* $FreeBSD: src/sys/alpha/include/param.h,v 1.34 2004/07/02 20:21:41 jhb Exp $ */
 /* From: NetBSD: param.h,v 1.20 1997/09/19 13:52:53 leo Exp */
 
 /*
@@ -113,6 +113,8 @@
 #define	SSIZE		1		/* initial stack size/NBPG */
 #define	SINCR		1		/* increment of stack/NBPG */
 
+#define	PREEMPTION
+
 #ifndef	KSTACK_PAGES
 #define	KSTACK_PAGES	2		/* pages of kstack (with pcb) */
 #endif

==== //depot/projects/smpng/sys/amd64/amd64/intr_machdep.c#3 (text+ko) ====

@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.6 2004/05/30 04:49:39 alc Exp $
+ * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.7 2004/07/02 20:21:41 jhb Exp $
  */
 
 /*
@@ -215,7 +215,7 @@
 		if (ih == NULL)
 			error = EINVAL;
 		else
-			error = ithread_schedule(it, !cold);
+			error = ithread_schedule(it);
 	}
 	if (error == EINVAL) {
 		atomic_add_long(isrc->is_straycount, 1);

==== //depot/projects/smpng/sys/amd64/include/param.h#9 (text+ko) ====

@@ -36,7 +36,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)param.h	8.1 (Berkeley) 6/10/93
- * $FreeBSD: src/sys/amd64/include/param.h,v 1.11 2004/06/07 23:47:59 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/param.h,v 1.12 2004/07/02 20:21:41 jhb Exp $
  */
 
 /*
@@ -119,6 +119,8 @@
 #define	NBPML4		(1ul<<PML4SHIFT)/* bytes/page map lev4 table */
 #define	PML4MASK	(NBPML4-1)
 
+#define	PREEMPTION
+
 #define IOPAGES	2		/* pages of i/o permission bitmap */
 
 #ifndef	KSTACK_PAGES

==== //depot/projects/smpng/sys/conf/NOTES#72 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/NOTES,v 1.1238 2004/06/30 01:00:59 jhb Exp $
+# $FreeBSD: src/sys/conf/NOTES,v 1.1240 2004/07/02 20:21:41 jhb Exp $
 #
 # NOTES -- Lines that can be cut/pasted into kernel and hints configs.
 #
@@ -125,6 +125,7 @@
 options 	GEOM_FOX		# Redundant path mitigation
 options 	GEOM_GATE		# Userland services.
 options 	GEOM_GPT		# GPT partitioning
+options 	GEOM_LABEL		# Providers labelization.
 options 	GEOM_MBR		# DOS/MBR partitioning
 options 	GEOM_NOP		# Test class.
 options 	GEOM_PC98		# NEC PC9800 partitioning
@@ -185,6 +186,11 @@
 
 # SMP Debugging Options:
 #
+# FULL_PREEMPTION instructs the kernel to preempt non-realtime kernel
+#	  threads.  It sole use is to expose race conditions and other
+#	  bugs during development.  Enabling this option will reduce
+#	  performance and increase the frequency of kernel panics by
+#	  design.  If you aren't sure that you need it then you don't.
 # MUTEX_DEBUG enables various extra assertions in the mutex code.
 # SLEEPQUEUE_PROFILING enables rudimentary profiling of the hash table
 #	  used to hold active sleep queues.
@@ -196,6 +202,7 @@
 #	  a lock hierarchy violation occurs or if locks are held when going to
 #	  sleep.
 # WITNESS_SKIPSPIN disables the witness checks on spin mutexes.
+options 	FULL_PREEMPTION
 options 	MUTEX_DEBUG
 options 	WITNESS
 options 	WITNESS_DDB

==== //depot/projects/smpng/sys/conf/files#113 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files,v 1.921 2004/06/30 14:52:49 imp Exp $
+# $FreeBSD: src/sys/conf/files,v 1.922 2004/07/02 19:40:36 pjd Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -940,6 +940,10 @@
 crypto/sha2/sha2.c		optional geom_bde
 geom/concat/g_concat.c	optional geom_concat
 geom/gate/g_gate.c	optional geom_gate
+geom/label/g_label.c	optional geom_label
+geom/label/g_label_iso9660.c	optional geom_label
+geom/label/g_label_msdosfs.c	optional geom_label
+geom/label/g_label_ufs.c	optional geom_label
 geom/nop/g_nop.c	optional geom_nop
 geom/stripe/g_stripe.c	optional geom_stripe
 geom/geom_aes.c		optional geom_aes

==== //depot/projects/smpng/sys/conf/options#79 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/options,v 1.457 2004/06/29 02:30:12 jhb Exp $
+# $FreeBSD: src/sys/conf/options,v 1.459 2004/07/02 20:21:42 jhb Exp $
 #
 #        On the handling of kernel options
 #
@@ -61,6 +61,7 @@
 DDB_TRACE
 DDB_UNATTENDED
 DIRECTIO	opt_directio.h
+FULL_PREEMPTION
 GDB_REMOTE_CHAT	opt_ddb.h
 GDBSPEED	opt_ddb.h
 GEOM_AES	opt_geom.h
@@ -71,6 +72,7 @@
 GEOM_FOX	opt_geom.h
 GEOM_GATE	opt_geom.h
 GEOM_GPT	opt_geom.h
+GEOM_LABEL	opt_geom.h
 GEOM_MBR	opt_geom.h
 GEOM_MIRROR	opt_geom.h
 GEOM_NOP	opt_geom.h

==== //depot/projects/smpng/sys/dev/acpica/acpi_ec.c#31 (text+ko) ====

@@ -24,8 +24,6 @@
  * 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.
- *
- *	$FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.56 2004/07/01 00:51:31 njl Exp $
  */
 /******************************************************************************
  *
@@ -137,7 +135,7 @@
  *****************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.56 2004/07/01 00:51:31 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.58 2004/07/02 20:15:53 njl Exp $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -367,6 +365,7 @@
 acpi_ec_ecdt_probe(device_t parent)
 {
     ACPI_TABLE_ECDT *ecdt;
+    ACPI_TABLE_HEADER *hdr;
     ACPI_STATUS	     status;
     device_t	     child;
     ACPI_HANDLE	     h;
@@ -375,8 +374,8 @@
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
     /* Find and validate the ECDT. */
-    status = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
-		(ACPI_TABLE_HEADER **)&ecdt);
+    status = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING, &hdr);
+    ecdt = (ACPI_TABLE_ECDT *)hdr;
     if (ACPI_FAILURE(status) ||
 	ecdt->control.RegisterBitWidth != 8 ||
 	ecdt->data.RegisterBitWidth != 8) {

==== //depot/projects/smpng/sys/i386/i386/intr_machdep.c#6 (text+ko) ====

@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/i386/i386/intr_machdep.c,v 1.6 2004/05/28 17:50:07 jhb Exp $
+ * $FreeBSD: src/sys/i386/i386/intr_machdep.c,v 1.7 2004/07/02 20:21:42 jhb Exp $
  */
 
 /*
@@ -215,7 +215,7 @@
 		if (ih == NULL)
 			error = EINVAL;
 		else
-			error = ithread_schedule(it, !cold);
+			error = ithread_schedule(it);
 	}
 	if (error == EINVAL) {
 		atomic_add_long(isrc->is_straycount, 1);

==== //depot/projects/smpng/sys/i386/include/param.h#12 (text+ko) ====

@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
- * $FreeBSD: src/sys/i386/include/param.h,v 1.70 2004/04/07 20:46:05 imp Exp $
+ * $FreeBSD: src/sys/i386/include/param.h,v 1.71 2004/07/02 20:21:42 jhb Exp $
  */
 
 /*
@@ -97,6 +97,8 @@
 #define NBPDR		(1<<PDRSHIFT)	/* bytes/page dir */
 #define PDRMASK		(NBPDR-1)
 
+#define	PREEMPTION
+
 #define IOPAGES	2		/* pages of i/o permission bitmap */
 
 #ifndef KSTACK_PAGES

==== //depot/projects/smpng/sys/ia64/ia64/interrupt.c#26 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/ia64/ia64/interrupt.c,v 1.45 2004/05/07 05:29:12 marcel Exp $ */
+/* $FreeBSD: src/sys/ia64/ia64/interrupt.c,v 1.46 2004/07/02 20:21:42 jhb Exp $ */
 /* $NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $ */
 
 /*
@@ -384,7 +384,7 @@
 		return;
 	}
 
-	error = ithread_schedule(ithd, 0);	/* XXX:no preemption for now */
+	error = ithread_schedule(ithd);
 	KASSERT(error == 0, ("got an impossible stray interrupt"));
 }
 

==== //depot/projects/smpng/sys/kern/kern_intr.c#48 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_intr.c,v 1.110 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_intr.c,v 1.111 2004/07/02 20:21:43 jhb Exp $");
 
 #include "opt_ddb.h"
 
@@ -365,7 +365,7 @@
 }
 
 int
-ithread_schedule(struct ithd *ithread, int do_switch)
+ithread_schedule(struct ithd *ithread)
 {
 	struct int_entropy entropy;
 	struct thread *td;
@@ -399,10 +399,7 @@
 	/*
 	 * Set it_need to tell the thread to keep running if it is already
 	 * running.  Then, grab sched_lock and see if we actually need to
-	 * put this thread on the runqueue.  If so and the do_switch flag is
-	 * true and it is safe to switch, then switch to the ithread
-	 * immediately.  Otherwise, set the needresched flag to guarantee
-	 * that this ithread will run before any userland processes.
+	 * put this thread on the runqueue.
 	 */
 	ithread->it_need = 1;
 	mtx_lock_spin(&sched_lock);
@@ -410,16 +407,6 @@
 		CTR2(KTR_INTR, "%s: setrunqueue %d", __func__, p->p_pid);
 		TD_CLR_IWAIT(td);
 		setrunqueue(td);
-		if (do_switch &&
-		    (ctd->td_critnest == 1) ) {
-			KASSERT((TD_IS_RUNNING(ctd)),
-			    ("ithread_schedule: Bad state for curthread."));
-			if (ctd->td_flags & TDF_IDLETD)
-				ctd->td_state = TDS_CAN_RUN; /* XXXKSE */
-			mi_switch(SW_INVOL, NULL);
-		} else {
-			curthread->td_flags |= TDF_NEEDRESCHED;
-		}
 	} else {
 		CTR4(KTR_INTR, "%s: pid %d: it_need %d, state %d",
 		    __func__, p->p_pid, ithread->it_need, td->td_state);
@@ -480,7 +467,7 @@
 	 */
 	atomic_store_rel_int(&ih->ih_need, 1);
 	if (!(flags & SWI_DELAY)) {
-		error = ithread_schedule(it, !cold && !dumping);
+		error = ithread_schedule(it);
 		KASSERT(error == 0, ("stray software interrupt"));
 	}
 }

==== //depot/projects/smpng/sys/kern/kern_mutex.c#79 (text+ko) ====

@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_mutex.c,v 1.139 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_mutex.c,v 1.140 2004/07/02 20:21:43 jhb Exp $");
 
 #include "opt_adaptive_mutexes.h"
 #include "opt_ddb.h"
@@ -621,7 +621,9 @@
 _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line)
 {
 	struct turnstile *ts;
+#ifndef PREEMPTION
 	struct thread *td, *td1;
+#endif
 
 	if (mtx_recursed(m)) {
 		if (--(m->mtx_recurse) == 0)
@@ -646,8 +648,10 @@
 #else
 	MPASS(ts != NULL);
 #endif
+#ifndef PREEMPTION
 	/* XXX */
 	td1 = turnstile_head(ts);
+#endif
 #ifdef MUTEX_WAKE_ALL
 	turnstile_broadcast(ts);
 	_release_lock_quick(m);
@@ -665,6 +669,7 @@
 #endif
 	turnstile_unpend(ts);
 
+#ifndef PREEMPTION
 	/*
 	 * XXX: This is just a hack until preemption is done.  However,
 	 * once preemption is done we need to either wrap the
@@ -701,6 +706,7 @@
 			    m, (void *)m->mtx_lock);
 	}
 	mtx_unlock_spin(&sched_lock);
+#endif
 
 	return;
 }

==== //depot/projects/smpng/sys/kern/kern_shutdown.c#42 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_shutdown.c,v 1.152 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_shutdown.c,v 1.153 2004/07/02 20:21:43 jhb Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ddb_trace.h"
@@ -269,7 +269,9 @@
 	if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) {
 		register struct buf *bp;
 		int iter, nbusy, pbusy;
+#ifndef PREEMPTION
 		int subiter;
+#endif
 
 		waittime = 0;
 		printf("\nsyncing disks, buffers remaining... ");
@@ -300,20 +302,29 @@
 				iter = 0;
 			pbusy = nbusy;
 			sync(&thread0, NULL);
- 			if (curthread != NULL) {
-				DROP_GIANT();
-   				for (subiter = 0; subiter < 50 * iter; subiter++) {
-     					mtx_lock_spin(&sched_lock);
-					/*
-					 * Allow interrupt threads to run
-					 */
-     					mi_switch(SW_VOL, NULL);
-     					mtx_unlock_spin(&sched_lock);
-     					DELAY(1000);
-   				}
-				PICKUP_GIANT();
- 			} else
+
+#ifdef PREEMPTION
+			/*
+			 * Drop Giant and spin for a while to allow
+			 * interrupt threads to run.
+			 */
+			DROP_GIANT();
 			DELAY(50000 * iter);
+			PICKUP_GIANT();
+#else
+			/*
+			 * Drop Giant and context switch several times to
+			 * allow interrupt threads to run.
+			 */
+			DROP_GIANT();
+			for (subiter = 0; subiter < 50 * iter; subiter++) {
+				mtx_lock_spin(&sched_lock);
+				mi_switch(SW_VOL, NULL);
+				mtx_unlock_spin(&sched_lock);
+				DELAY(1000);
+			}
+			PICKUP_GIANT();
+#endif
 		}
 		printf("\n");
 		/*

==== //depot/projects/smpng/sys/kern/kern_switch.c#36 (text+ko) ====

@@ -86,7 +86,9 @@
 ***/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_switch.c,v 1.67 2004/02/02 08:13:27 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_switch.c,v 1.68 2004/07/02 20:21:43 jhb Exp $");
+
+#include "opt_full_preemption.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -423,10 +425,10 @@
 	}
 }
 
-/************************************************************************
- * Critical section marker functions					*
- ************************************************************************/
-/* Critical sections that prevent preemption. */
+/*
+ * Kernel thread preemption implementation.  Critical sections mark
+ * regions of code in which preemptions are not allowed.
+ */
 void
 critical_enter(void)
 {
@@ -447,6 +449,13 @@
 	KASSERT(td->td_critnest != 0,
 	    ("critical_exit: td_critnest == 0"));
 	if (td->td_critnest == 1) {
+#ifdef PREEMPTION
+		if (td->td_flags & TDF_OWEPREEMPT) {
+			mtx_lock_spin(&sched_lock);
+			mi_switch(SW_INVOL, NULL);
+			mtx_unlock_spin(&sched_lock);
+		}
+#endif
 		td->td_critnest = 0;
 		cpu_critical_exit();
 	} else {
@@ -454,6 +463,86 @@
 	}
 }
 
+/*
+ * This function is called when a thread is about to be put on run queue
+ * because it has been made runnable or its priority has been adjusted.  It
+ * determines if the new thread should be immediately preempted to.  If so,
+ * it switches to it and eventually returns true.  If not, it returns false
+ * so that the caller may place the thread on an appropriate run queue.
+ */
+int
+maybe_preempt(struct thread *td)
+{
+	struct thread *ctd;
+	int cpri, pri;
+
+	mtx_assert(&sched_lock, MA_OWNED);
+#ifdef PREEMPTION
+	/*
+	 * The new thread should not preempt the current thread if any of the
+	 * following conditions are true:
+	 *
+	 *  - The current thread has a higher (numerically lower) priority.
+	 *  - It is too early in the boot for context switches (cold is set).
+	 *  - The current thread has an inhibitor set or is in the process of
+	 *    exiting.  In this case, the current thread is about to switch
+	 *    out anyways, so there's no point in preempting.  If we did,
+	 *    the current thread would not be properly resumed as well, so
+	 *    just avoid that whole landmine.
+	 *  - If the new thread's priority is not a realtime priority and
+	 *    the current thread's priority is not an idle priority and
+	 *    FULL_PREEMPTION is disabled.
+	 *
+	 * If all of these conditions are false, but the current thread is in
+	 * a nested critical section, then we have to defer the preemption
+	 * until we exit the critical section.  Otherwise, switch immediately
+	 * to the new thread.
+	 */
+	ctd = curthread;
+	pri = td->td_priority;
+	cpri = ctd->td_priority;
+	if (pri >= cpri || cold /* || dumping */ || TD_IS_INHIBITED(ctd) ||
+	    td->td_kse->ke_state != KES_THREAD)
+		return (0);
+#ifndef FULL_PREEMPTION
+	if (!(pri >= PRI_MIN_ITHD && pri <= PRI_MAX_ITHD) &&
+	    !(cpri >= PRI_MIN_IDLE))
+		return (0);
+#endif
+	if (ctd->td_critnest > 1) {
+		CTR1(KTR_PROC, "maybe_preempt: in critical section %d",
+		    ctd->td_critnest);
+		ctd->td_flags |= TDF_OWEPREEMPT;
+		return (0);
+	}
+
+	/*
+	 * Our thread state says that we are already on a run queue, so
+	 * update our state as if we had been dequeued by choosethread().
+	 */
+	MPASS(TD_ON_RUNQ(td));
+	TD_SET_RUNNING(td);
+	CTR3(KTR_PROC, "preempting to thread %p (pid %d, %s)\n", td,
+	    td->td_proc->p_pid, td->td_proc->p_comm);
+	mi_switch(SW_INVOL, td);
+	return (1);
+#else
+	return (0);
+#endif
+}
+
+#ifndef PREEMPTION
+/* XXX: There should be a non-static version of this. */
+static void
+printf_caddr_t(void *data)
+{
+	printf("%s", (char *)data);
+}
+static char preempt_warning[] =
+    "WARNING: Kernel preemption is disabled, expect reduced performance.\n";
+SYSINIT(preempt_warning, SI_SUB_COPYRIGHT, SI_ORDER_ANY, printf_caddr_t,
+    preempt_warning)
+#endif
 
 /************************************************************************
  * SYSTEM RUN QUEUE manipulations and tests				*

==== //depot/projects/smpng/sys/kern/kern_synch.c#72 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_synch.c,v 1.251 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_synch.c,v 1.252 2004/07/02 20:21:43 jhb Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
@@ -299,7 +299,9 @@
 	if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
 		mtx_assert(&Giant, MA_NOTOWNED);
 #endif
-	KASSERT(td->td_critnest == 1,
+	KASSERT(td->td_critnest == 1 || (td->td_critnest == 2 &&
+	    (td->td_flags & TDF_OWEPREEMPT) != 0 && (flags & SW_INVOL) != 0 &&
+	    newtd == NULL),
 	    ("mi_switch: switch in a critical section"));
 	KASSERT((flags & (SW_INVOL | SW_VOL)) != 0,
 	    ("mi_switch: switch must be voluntary or involuntary"));
@@ -308,6 +310,7 @@
 		p->p_stats->p_ru.ru_nvcsw++;
 	else
 		p->p_stats->p_ru.ru_nivcsw++;
+
 	/*
 	 * Compute the amount of time during which the current
 	 * process was running, and add that to its total so far.

==== //depot/projects/smpng/sys/kern/sched_4bsd.c#28 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/sched_4bsd.c,v 1.42 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/sched_4bsd.c,v 1.43 2004/07/02 20:21:43 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -654,7 +654,7 @@
 		sched_tdcnt++;
 	td->td_lastcpu = td->td_oncpu;
 	td->td_last_kse = ke;
-	td->td_flags &= ~TDF_NEEDRESCHED;
+	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_OWEPREEMPT);
 	td->td_oncpu = NOCPU;
 	/*
 	 * At the last moment, if this thread is still marked RUNNING,
@@ -712,6 +712,16 @@
 	    ke->ke_proc->p_comm));
 	KASSERT(ke->ke_proc->p_sflag & PS_INMEM,
 	    ("sched_add: process swapped out"));
+
+#ifdef SMP
+	/*
+	 * Only try to preempt if the thread is unpinned or pinned to the
+	 * current CPU.
+	 */
+	if (KSE_CAN_MIGRATE(ke) || ke->ke_runq == &runq_pcpu[PCPU_GET(cpuid)])
+#endif
+	if (maybe_preempt(td))
+		return;
 	ke->ke_ksegrp->kg_runq_kses++;
 	ke->ke_state = KES_ONRUNQ;
 

==== //depot/projects/smpng/sys/kern/sched_ule.c#32 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/sched_ule.c,v 1.109 2004/07/02 19:09:49 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/sched_ule.c,v 1.110 2004/07/02 20:21:43 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1139,7 +1139,7 @@
 	td->td_last_kse = ke;
         td->td_lastcpu = td->td_oncpu;
 	td->td_oncpu = NOCPU;
-        td->td_flags &= ~TDF_NEEDRESCHED;
+	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_OWEPREEMPT);
 
 	/*
 	 * If the KSE has been assigned it may be in the process of switching
@@ -1623,6 +1623,15 @@
         if (td->td_priority < curthread->td_priority)
                 curthread->td_flags |= TDF_NEEDRESCHED;
 
+#ifdef SMP
+	/*
+	 * Only try to preempt if the thread is unpinned or pinned to the
+	 * current CPU.
+	 */
+	if (KSE_CAN_MIGRATE(ke) || ke->ke_cpu == PCPU_GET(cpuid))
+#endif
+	if (maybe_preempt(td))
+		return;
 	ke->ke_ksegrp->kg_runq_kses++;
 	ke->ke_state = KES_ONRUNQ;
 

==== //depot/projects/smpng/sys/modules/geom/Makefile#8 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/modules/geom/Makefile,v 1.7 2004/05/20 10:37:13 pjd Exp $
+# $FreeBSD: src/sys/modules/geom/Makefile,v 1.8 2004/07/02 19:40:35 pjd Exp $
 
 SUBDIR=	geom_apple \
 	geom_bde \
@@ -8,6 +8,7 @@
 	geom_fox \
 	geom_gate \
 	geom_gpt \
+	geom_label \
 	geom_mbr \
 	geom_nop \
 	geom_pc98 \

==== //depot/projects/smpng/sys/net/if_ethersubr.c#50 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
- * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.174 2004/06/24 12:31:44 joerg Exp $
+ * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.175 2004/07/02 19:44:59 brooks Exp $
  */
 
 #include "opt_atalk.h"
@@ -847,6 +847,7 @@
 void
 ether_ifattach(struct ifnet *ifp, const u_int8_t *llc)
 {
+	int i;
 	struct ifaddr *ifa;
 	struct sockaddr_dl *sdl;
 
@@ -881,8 +882,12 @@
 	if (BDG_LOADED)
 		bdgtakeifaces_ptr();
 
-	/* Announce Ethernet MAC address. */
-	if_printf(ifp, "Ethernet address: %6D\n", llc, ":");
+	/* Announce Ethernet MAC address if non-zero. */
+	for (i = 0; i < ifp->if_addrlen; i++)
+		if (llc[i] != 0)
+			break; 
+	if (i != ifp->if_addrlen)
+		if_printf(ifp, "Ethernet address: %6D\n", llc, ":");
 }
 
 /*

==== //depot/projects/smpng/sys/powerpc/powerpc/intr_machdep.c#6 (text+ko) ====

@@ -57,7 +57,7 @@
  *	from: @(#)isa.c	7.2 (Berkeley) 5/13/91
  *	form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
  *
- * $FreeBSD: src/sys/powerpc/powerpc/intr_machdep.c,v 1.5 2004/04/07 04:59:59 imp Exp $
+ * $FreeBSD: src/sys/powerpc/powerpc/intr_machdep.c,v 1.6 2004/07/02 20:21:43 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -308,7 +308,7 @@
 
 	ih = (struct intr_handler *)cookie;
 
-	error = ithread_schedule(ih->ih_ithd, 0);
+	error = ithread_schedule(ih->ih_ithd);
 
 	if (error == EINVAL)
 		intr_stray_handler(ih);

==== //depot/projects/smpng/sys/sparc64/sparc64/intr_machdep.c#21 (text+ko) ====

@@ -57,7 +57,7 @@
  *	from: @(#)isa.c	7.2 (Berkeley) 5/13/91
  *	form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
  *
- * $FreeBSD: src/sys/sparc64/sparc64/intr_machdep.c,v 1.18 2004/04/07 05:00:01 imp Exp $
+ * $FreeBSD: src/sys/sparc64/sparc64/intr_machdep.c,v 1.19 2004/07/02 20:21:43 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -230,11 +230,7 @@
 	int error;
 
 	iv = cookie;
-#ifdef notyet
 	error = ithread_schedule(iv->iv_ithd);
-#else
-	error = ithread_schedule(iv->iv_ithd, 0);
-#endif
 	if (error == EINVAL)
 		intr_stray_vector(iv);
 }

==== //depot/projects/smpng/sys/sys/interrupt.h#13 (text+ko) ====

@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/sys/interrupt.h,v 1.27 2004/06/28 16:21:51 jhb Exp $
+ * $FreeBSD: src/sys/sys/interrupt.h,v 1.28 2004/07/02 20:21:43 jhb Exp $
  */
 
 #ifndef _SYS_INTERRUPT_H_
@@ -122,7 +122,7 @@
 	    driver_intr_t handler, void *arg, u_char pri, enum intr_type flags,
 	    void **cookiep);
 int	ithread_remove_handler(void *cookie);
-int	ithread_schedule(struct ithd *ithread, int do_switch);
+int	ithread_schedule(struct ithd *ithread);
 int     swi_add(struct ithd **ithdp, const char *name,
 	    driver_intr_t handler, void *arg, int pri, enum intr_type flags,
 	    void **cookiep);

==== //depot/projects/smpng/sys/sys/proc.h#118 (text+ko) ====

@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)proc.h	8.15 (Berkeley) 5/19/95
- * $FreeBSD: src/sys/sys/proc.h,v 1.383 2004/07/02 19:09:50 jhb Exp $
+ * $FreeBSD: src/sys/sys/proc.h,v 1.384 2004/07/02 20:21:43 jhb Exp $
  */
 
 #ifndef _SYS_PROC_H_
@@ -346,6 +346,7 @@
 #define	TDF_IDLETD	0x000020 /* This is one of the per-CPU idle threads. */
 #define	TDF_SELECT	0x000040 /* Selecting; wakeup/waiting danger. */
 #define	TDF_TSNOBLOCK	0x000100 /* Don't block on a turnstile due to race. */
+#define	TDF_OWEPREEMPT	0x000200 /* Thread has a pending preemption. */
 #define	TDF_ASTPENDING	0x000800 /* Thread has some asynchronous events. */
 #define	TDF_TIMOFAIL	0x001000 /* Timeout from sleep after we were awake. */
 #define	TDF_INTERRUPT	0x002000 /* Thread is marked as interrupted. */
@@ -850,6 +851,7 @@
 void	fork_return(struct thread *, struct trapframe *);
 int	inferior(struct proc *p);
 int	leavepgrp(struct proc *p);
+int	maybe_preempt(struct thread *td);
 void	mi_switch(int flags, struct thread *newtd);
 int	p_candebug(struct thread *td, struct proc *p);
 int	p_cansee(struct thread *td, struct proc *p);

==== //depot/projects/smpng/sys/vm/vm_zeroidle.c#17 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/vm/vm_zeroidle.c,v 1.25 2004/07/02 19:09:50 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/vm/vm_zeroidle.c,v 1.26 2004/07/02 20:21:44 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -151,12 +151,14 @@
 	for (;;) {
 		if (vm_page_zero_check()) {
 			pages += vm_page_zero_idle();
+#ifndef PREEMPTION
 			if (pages > idlezero_maxrun || sched_runnable()) {
 				mtx_lock_spin(&sched_lock);
 				mi_switch(SW_VOL, NULL);
 				mtx_unlock_spin(&sched_lock);
 				pages = 0;
 			}
+#endif
 		} else {
 			tsleep(&zero_state, pri, "pgzero", hz * 300);
 			pages = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407022028.i62KSJN6042063>