git: 2cce9aa0785c - main - vt(4): Make sure vt_switch_timer() has a sleepable context.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Tue, 27 Sep 2022 14:08:31 UTC
The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=2cce9aa0785c438fa8b66bd230824f7460df14ac

commit 2cce9aa0785c438fa8b66bd230824f7460df14ac
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-09-26 15:10:50 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-09-27 14:07:54 +0000

    vt(4): Make sure vt_switch_timer() has a sleepable context.
    
    Fixes the following panic backtrace:
    
    panic()
    usbhid_sync_xfer()
    usbhid_set_report()
    hid_set_report()
    hidbus_write()
    hid_write()
    hkbd_set_leds()
    hkbd_ioctl_locked()
    hkbd_ioctl_locked()
    hkbd_ioctl()
    kbdmux_ioctl()
    vt_window_switch()
    vt_switch_timer()
    
    Differential Revision:  https://reviews.freebsd.org/D36715
    MFC after:      1 week
    Sponsored by:   NVIDIA Networking
---
 sys/dev/vt/vt.h          |  3 ++-
 sys/dev/vt/vt_core.c     | 13 ++++++-------
 sys/dev/vt/vt_cpulogos.c |  1 -
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index b4361f77317c..7305727804cf 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -48,6 +48,7 @@
 #include <sys/terminal.h>
 #include <sys/sysctl.h>
 #include <sys/font.h>
+#include <sys/taskqueue.h>
 
 #include "opt_syscons.h"
 #include "opt_splash.h"
@@ -306,7 +307,7 @@ struct vt_window {
 	pid_t			 vw_pid;	/* Terminal holding process */
 	struct proc		*vw_proc;
 	struct vt_mode		 vw_smode;	/* switch mode */
-	struct callout		 vw_proc_dead_timer;
+	struct timeout_task	 vw_timeout_task_dead;
 	struct vt_window	*vw_switch_to;
 	int			 vw_bell_pitch;	/* (?) Bell pitch */
 	sbintime_t		 vw_bell_duration; /* (?) Bell duration */
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index b95ff1ef677e..8f9e1cf6d2b2 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -338,7 +338,7 @@ vt_suspend_flush_timer(struct vt_device *vd)
 }
 
 static void
-vt_switch_timer(void *arg)
+vt_switch_timer(void *arg, int pending)
 {
 
 	(void)vt_late_window_switch((struct vt_window *)arg);
@@ -442,8 +442,7 @@ vt_window_preswitch(struct vt_window *vw, struct vt_window *curvw)
 	DPRINTF(40, "%s\n", __func__);
 	curvw->vw_switch_to = vw;
 	/* Set timer to allow switch in case when process hang. */
-	callout_reset(&vw->vw_proc_dead_timer, hz * vt_deadtimer,
-	    vt_switch_timer, (void *)vw);
+	taskqueue_enqueue_timeout(taskqueue_thread, &vw->vw_timeout_task_dead, hz * vt_deadtimer);
 	/* Notify process about vt switch attempt. */
 	DPRINTF(30, "%s: Notify process.\n", __func__);
 	signal_vt_rel(curvw);
@@ -466,7 +465,7 @@ vt_late_window_switch(struct vt_window *vw)
 	struct vt_window *curvw;
 	int ret;
 
-	callout_stop(&vw->vw_proc_dead_timer);
+	taskqueue_cancel_timeout(taskqueue_thread, &vw->vw_timeout_task_dead, NULL);
 
 	ret = vt_window_switch(vw);
 	if (ret != 0) {
@@ -2045,7 +2044,7 @@ finish_vt_rel(struct vt_window *vw, int release, int *s)
 	if (vw->vw_flags & VWF_SWWAIT_REL) {
 		vw->vw_flags &= ~VWF_SWWAIT_REL;
 		if (release) {
-			callout_drain(&vw->vw_proc_dead_timer);
+			taskqueue_drain_timeout(taskqueue_thread, &vw->vw_timeout_task_dead);
 			(void)vt_late_window_switch(vw->vw_switch_to);
 		}
 		return (0);
@@ -2929,7 +2928,7 @@ vt_allocate_window(struct vt_device *vd, unsigned int window)
 
 	terminal_set_winsize(tm, &wsz);
 	vd->vd_windows[window] = vw;
-	callout_init(&vw->vw_proc_dead_timer, 1);
+	TIMEOUT_TASK_INIT(taskqueue_thread, &vw->vw_timeout_task_dead, 0, &vt_switch_timer, vw);
 
 	return (vw);
 }
@@ -2953,7 +2952,7 @@ vt_upgrade(struct vt_device *vd)
 			vw = vt_allocate_window(vd, i);
 		}
 		if (!(vw->vw_flags & VWF_READY)) {
-			callout_init(&vw->vw_proc_dead_timer, 1);
+			TIMEOUT_TASK_INIT(taskqueue_thread, &vw->vw_timeout_task_dead, 0, &vt_switch_timer, vw);
 			terminal_maketty(vw->vw_terminal, "v%r", VT_UNIT(vw));
 			vw->vw_flags |= VWF_READY;
 			if (vw->vw_flags & VWF_CONSOLE) {
diff --git a/sys/dev/vt/vt_cpulogos.c b/sys/dev/vt/vt_cpulogos.c
index 7e0be12b3adb..4337c31e0054 100644
--- a/sys/dev/vt/vt_cpulogos.c
+++ b/sys/dev/vt/vt_cpulogos.c
@@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/smp.h>
 #include <sys/systm.h>
-#include <sys/taskqueue.h>
 #include <sys/terminal.h>
 
 #include <dev/vt/vt.h>