Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Mar 2018 15:12:03 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r331736 - stable/11/sys/kern
Message-ID:  <201803291512.w2TFC3Id050052@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Mar 29 15:12:03 2018
New Revision: 331736
URL: https://svnweb.freebsd.org/changeset/base/331736

Log:
  MFC r331375:
  Do not send signals to init directly from shutdown_nice(9), do it from
  the task context.

Modified:
  stable/11/sys/kern/kern_shutdown.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/kern_shutdown.c
==============================================================================
--- stable/11/sys/kern/kern_shutdown.c	Thu Mar 29 15:08:40 2018	(r331735)
+++ stable/11/sys/kern/kern_shutdown.c	Thu Mar 29 15:12:03 2018	(r331736)
@@ -68,6 +68,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>
 
@@ -232,6 +233,26 @@ 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_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
  */
@@ -239,18 +260,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_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?201803291512.w2TFC3Id050052>