Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 May 2009 13:52:17 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r193170 - projects/pnet/sys/kern
Message-ID:  <200905311352.n4VDqH8V044973@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Sun May 31 13:52:17 2009
New Revision: 193170
URL: http://svn.freebsd.org/changeset/base/193170

Log:
  Add a shutdown handler for device polling -- don't issue wakeups to the
  netisr once file systems are done syncing, otherwise the scheduler may
  generate IPIs to CPUs that have already been shutdown, leading to a
  panic.
  
  As similar panics (spin lock 0xc0d8e500 (sched lock 1) held by
  0xc4d546c0 (tid 100005) too long) have been reported on both 7.x and 8.x
  in other code, we might want to think about whether there's some missing
  scheduler shutdown logic to handle this case for unpinned/unbound
  threads by migrating them to the CPU managing the shutdown and allowing
  them to preempt.

Modified:
  projects/pnet/sys/kern/kern_poll.c

Modified: projects/pnet/sys/kern/kern_poll.c
==============================================================================
--- projects/pnet/sys/kern/kern_poll.c	Sun May 31 12:36:14 2009	(r193169)
+++ projects/pnet/sys/kern/kern_poll.c	Sun May 31 13:52:17 2009	(r193170)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/kthread.h>
 #include <sys/proc.h>
+#include <sys/eventhandler.h>
 #include <sys/resourcevar.h>
 #include <sys/socket.h>			/* needed by net/if.h		*/
 #include <sys/sockio.h>
@@ -110,6 +111,7 @@ SYSCTL_UINT(_kern_polling, OID_AUTO, bur
 
 static int	netisr_poll_scheduled;
 static int	netisr_pollmore_scheduled;
+static int	poll_shutting_down;
 
 static int poll_burst_max_sysctl(SYSCTL_HANDLER_ARGS)
 {
@@ -261,10 +263,19 @@ struct pollrec {
 static struct pollrec pr[POLL_LIST_LEN];
 
 static void
+poll_shutdown(void *arg, int howto)
+{
+
+	poll_shutting_down = 1;
+}
+
+static void
 init_device_poll(void)
 {
 
 	mtx_init(&poll_mtx, "polling", NULL, MTX_DEF);
+	EVENTHANDLER_REGISTER(shutdown_post_sync, poll_shutdown, NULL,
+	    SHUTDOWN_PRI_LAST);
 }
 SYSINIT(device_poll, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, init_device_poll, NULL);
 
@@ -288,7 +299,7 @@ hardclock_device_poll(void)
 	static struct timeval prev_t, t;
 	int delta;
 
-	if (poll_handlers == 0)
+	if (poll_handlers == 0 || poll_shutting_down)
 		return;
 
 	microuptime(&t);



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