diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index a8d701bcbb25..d7e1b8e4fa0a 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -49,14 +49,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -690,8 +691,23 @@ inthand_remove(struct intrec *idesc) ih->next = ih->next->next; } - if (ithd->it_ih == NULL) /* no handlers left, */ + if (ithd->it_ih == NULL) { /* no handlers left, */ icu_unset(ithd->irq, idesc->handler); + ithds[ithd->irq] = NULL; + + mtx_enter(&sched_lock, MTX_SPIN); + if (ithd->it_proc->p_stat == SWAIT) { + ithd->it_proc->p_stat = SRUN; + setrunqueue(ithd->it_proc); + /* + * We don't do an ast here because we really + * don't care when it runs next. + * + * XXX: should we lower the threads priority? + */ + } + mtx_exit(&sched_lock, MTX_SPIN); + } free(idesc, M_DEVBUF); return (0); } diff --git a/sys/amd64/isa/ithread.c b/sys/amd64/isa/ithread.c index b2a98a214da3..735204eb14c0 100644 --- a/sys/amd64/isa/ithread.c +++ b/sys/amd64/isa/ithread.c @@ -44,14 +44,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include @@ -84,7 +85,6 @@ #endif #include -#include #include #include @@ -174,6 +174,19 @@ ithd_loop(void *dummy) * list of handlers, giving each one a go at it. */ for (;;) { + /* + * If we don't have any handlers, then we are an orphaned + * thread and just need to die. + */ + if (me->it_ih == NULL) { + CTR2(KTR_INTR, "ithd_loop pid %d(%s) exiting", + me->it_proc->p_pid, me->it_proc->p_comm); + curproc->p_ithd = NULL; + free(me, M_DEVBUF); + mtx_enter(&Giant, MTX_DEF); + kthread_exit(0); + } + CTR3(KTR_INTR, "ithd_loop pid %d(%s) need=%d", me->it_proc->p_pid, me->it_proc->p_comm, me->it_need); while (me->it_need) { diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index a8d701bcbb25..d7e1b8e4fa0a 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -49,14 +49,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -690,8 +691,23 @@ inthand_remove(struct intrec *idesc) ih->next = ih->next->next; } - if (ithd->it_ih == NULL) /* no handlers left, */ + if (ithd->it_ih == NULL) { /* no handlers left, */ icu_unset(ithd->irq, idesc->handler); + ithds[ithd->irq] = NULL; + + mtx_enter(&sched_lock, MTX_SPIN); + if (ithd->it_proc->p_stat == SWAIT) { + ithd->it_proc->p_stat = SRUN; + setrunqueue(ithd->it_proc); + /* + * We don't do an ast here because we really + * don't care when it runs next. + * + * XXX: should we lower the threads priority? + */ + } + mtx_exit(&sched_lock, MTX_SPIN); + } free(idesc, M_DEVBUF); return (0); } diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index a8d701bcbb25..d7e1b8e4fa0a 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -49,14 +49,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -690,8 +691,23 @@ inthand_remove(struct intrec *idesc) ih->next = ih->next->next; } - if (ithd->it_ih == NULL) /* no handlers left, */ + if (ithd->it_ih == NULL) { /* no handlers left, */ icu_unset(ithd->irq, idesc->handler); + ithds[ithd->irq] = NULL; + + mtx_enter(&sched_lock, MTX_SPIN); + if (ithd->it_proc->p_stat == SWAIT) { + ithd->it_proc->p_stat = SRUN; + setrunqueue(ithd->it_proc); + /* + * We don't do an ast here because we really + * don't care when it runs next. + * + * XXX: should we lower the threads priority? + */ + } + mtx_exit(&sched_lock, MTX_SPIN); + } free(idesc, M_DEVBUF); return (0); } diff --git a/sys/i386/isa/ithread.c b/sys/i386/isa/ithread.c index b2a98a214da3..735204eb14c0 100644 --- a/sys/i386/isa/ithread.c +++ b/sys/i386/isa/ithread.c @@ -44,14 +44,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include @@ -84,7 +85,6 @@ #endif #include -#include #include #include @@ -174,6 +174,19 @@ ithd_loop(void *dummy) * list of handlers, giving each one a go at it. */ for (;;) { + /* + * If we don't have any handlers, then we are an orphaned + * thread and just need to die. + */ + if (me->it_ih == NULL) { + CTR2(KTR_INTR, "ithd_loop pid %d(%s) exiting", + me->it_proc->p_pid, me->it_proc->p_comm); + curproc->p_ithd = NULL; + free(me, M_DEVBUF); + mtx_enter(&Giant, MTX_DEF); + kthread_exit(0); + } + CTR3(KTR_INTR, "ithd_loop pid %d(%s) need=%d", me->it_proc->p_pid, me->it_proc->p_comm, me->it_need); while (me->it_need) { diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index a8d701bcbb25..d7e1b8e4fa0a 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -49,14 +49,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -690,8 +691,23 @@ inthand_remove(struct intrec *idesc) ih->next = ih->next->next; } - if (ithd->it_ih == NULL) /* no handlers left, */ + if (ithd->it_ih == NULL) { /* no handlers left, */ icu_unset(ithd->irq, idesc->handler); + ithds[ithd->irq] = NULL; + + mtx_enter(&sched_lock, MTX_SPIN); + if (ithd->it_proc->p_stat == SWAIT) { + ithd->it_proc->p_stat = SRUN; + setrunqueue(ithd->it_proc); + /* + * We don't do an ast here because we really + * don't care when it runs next. + * + * XXX: should we lower the threads priority? + */ + } + mtx_exit(&sched_lock, MTX_SPIN); + } free(idesc, M_DEVBUF); return (0); }