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);
        }
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to