Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Mar 2018 13:42:13 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Warner Losh <imp@bsdimp.com>, Warner Losh <imp@freebsd.org>, src-committers <src-committers@freebsd.org>, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r331298 - head/sys/dev/syscons
Message-ID:  <20180322114213.GR76926@kib.kiev.ua>
In-Reply-To: <20180322174025.Q1053@besplex.bde.org>
References:  <201803211447.w2LElDcK091988@repo.freebsd.org> <20180322024846.S4293@besplex.bde.org> <20180321202752.GO76926@kib.kiev.ua> <CANCZdfrY9PQ-FUApReGeFqwH%2BdoSUN5AtvF0ag1rD09sKYq6gg@mail.gmail.com> <20180322174025.Q1053@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 22, 2018 at 05:50:57PM +1100, Bruce Evans wrote:
> On Wed, 21 Mar 2018, Warner Losh wrote:
> 
> > On Wed, Mar 21, 2018 at 2:27 PM, Konstantin Belousov <kostikbel@gmail.com>
> > wrote:
> >> ...
> >> Are you saying that fast interrupt handlers call shutdown_nice() ?  This
> >> is the quite serious bug on its own.  To fix it, shutdown_nice() should
> >> use a fast taskqueue to schedule the task which would lock the process
> >> and send the signal.
> >
> > Is there some way we know we're in a fast interrupt handler? If so, it
> > should be simple to fix. If not, then there's an API change ahead of us...
> 
> There is a td_intr_nesting_level flag that might work.  (I invented this,
> but don't like its current use.)
But why do we need to know this ?  We can always schedule a task in the
fast taskqueue if init is present and can be scheduled.

> 
> > But bde is right: the system has to be in good enough shape to cope. I
> > wonder if we should put that coping into kdb_reboot() instead. It's only an
> > issue for <CR> TILDE ^R, which is a fairly edge case.
> 
> shutdown_nice() is also called directly from syscons and vt for the reboot,
> halt and poweroff keys.  This happens in normal interrupt handler context,
> so there is only a problem when init is not running.

diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index e5ea9644ad3..e7c6d4c92b2 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/smp.h>
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
+#include <sys/taskqueue.h>
 #include <sys/vnode.h>
 #include <sys/watchdog.h>
 
@@ -276,6 +277,28 @@ sys_reboot(struct thread *td, struct reboot_args *uap)
 	return (error);
 }
 
+static void
+shutdown_nice_task_fn(void *arg, int pending __unused)
+{
+	int howto;
+
+	howto = (uintptr_t)arg;
+	/* Send a signal to init(8) and have it shutdown the world. */
+	PROC_LOCK(initproc);
+	if (howto & RB_POWEROFF)
+		kern_psignal(initproc, SIGUSR2);
+	else if (howto & RB_POWERCYCLE)
+		kern_psignal(initproc, SIGWINCH);
+	else if (howto & RB_HALT)
+		kern_psignal(initproc, SIGUSR1);
+	else
+		kern_psignal(initproc, SIGINT);
+	PROC_UNLOCK(initproc);
+}
+
+static struct task shutdown_nice_task = TASK_INITIALIZER(0,
+    &shutdown_nice_task_fn, NULL);
+
 /*
  * Called by events that want to shut down.. e.g  <CTL><ALT><DEL> on a PC
  */
@@ -283,20 +306,14 @@ void
 shutdown_nice(int howto)
 {
 
-	if (initproc != NULL) {
-		/* Send a signal to init(8) and have it shutdown the world. */
-		PROC_LOCK(initproc);
-		if (howto & RB_POWEROFF)
-			kern_psignal(initproc, SIGUSR2);
-		else if (howto & RB_POWERCYCLE)
-			kern_psignal(initproc, SIGWINCH);
-		else if (howto & RB_HALT)
-			kern_psignal(initproc, SIGUSR1);
-		else
-			kern_psignal(initproc, SIGINT);
-		PROC_UNLOCK(initproc);
+	if (initproc != NULL && !SCHEDULER_STOPPED()) {
+		shutdown_nice_task.ta_context = (void *)(uintptr_t)howto;
+		taskqueue_enqueue(taskqueue_fast, &shutdown_nice_task);
 	} else {
-		/* No init(8) running, so simply reboot. */
+		/*
+		 * No init(8) running, or scheduler would not allow it
+		 * to run, so simply reboot.
+		 */
 		kern_reboot(howto | RB_NOSYNC);
 	}
 }



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