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
This commit is contained in:
parent
78aeba26e8
commit
2cce9aa078
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user