summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2000-10-20 07:46:12 +0000
committerjhb <jhb@FreeBSD.org>2000-10-20 07:46:12 +0000
commitd24b54adc770857a36d2f8957eac8c99f18bfed1 (patch)
tree48fd4e01a334c04974932f01601882c4e93c8f4a /sys/i386/isa
parentab2c7bf24831714b92f839ddaf0043e2b85e8d96 (diff)
downloadFreeBSD-src-d24b54adc770857a36d2f8957eac8c99f18bfed1.zip
FreeBSD-src-d24b54adc770857a36d2f8957eac8c99f18bfed1.tar.gz
Actually harvest interrupt threads when the last handler is removed from a
thread.
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/intr_machdep.c20
-rw-r--r--sys/i386/isa/ithread.c17
-rw-r--r--sys/i386/isa/nmi.c20
3 files changed, 51 insertions, 6 deletions
diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c
index a8d701b..d7e1b8e 100644
--- a/sys/i386/isa/intr_machdep.c
+++ b/sys/i386/isa/intr_machdep.c
@@ -49,14 +49,15 @@
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/syslog.h>
+#include <sys/ipl.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/unistd.h>
#include <sys/errno.h>
#include <sys/interrupt.h>
-#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/segments.h>
#include <sys/bus.h>
@@ -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 b2a98a2..735204e 100644
--- a/sys/i386/isa/ithread.c
+++ b/sys/i386/isa/ithread.c
@@ -44,14 +44,15 @@
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/syslog.h>
+#include <sys/ipl.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/unistd.h>
#include <sys/errno.h>
#include <sys/interrupt.h>
-#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/segments.h>
@@ -84,7 +85,6 @@
#endif
#include <sys/vmmeter.h>
-#include <machine/mutex.h>
#include <sys/ktr.h>
#include <machine/cpu.h>
@@ -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 a8d701b..d7e1b8e 100644
--- a/sys/i386/isa/nmi.c
+++ b/sys/i386/isa/nmi.c
@@ -49,14 +49,15 @@
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/syslog.h>
+#include <sys/ipl.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/unistd.h>
#include <sys/errno.h>
#include <sys/interrupt.h>
-#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/segments.h>
#include <sys/bus.h>
@@ -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);
}
OpenPOWER on IntegriCloud