Deleted Added
full compact
kern_intr.c (172836) kern_intr.c (173004)
1/*-
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/kern/kern_intr.c 172836 2007-10-20 23:23:23Z julian $");
28__FBSDID("$FreeBSD: head/sys/kern/kern_intr.c 173004 2007-10-26 08:00:41Z julian $");
29
30#include "opt_ddb.h"
31
32#include <sys/param.h>
33#include <sys/bus.h>
34#include <sys/conf.h>
35#include <sys/rtprio.h>
36#include <sys/systm.h>

--- 38 unchanged lines hidden (view full) ---

75 struct thread *td;
76 uintptr_t event;
77};
78
79struct intr_event *clk_intr_event;
80struct intr_event *tty_intr_event;
81void *softclock_ih;
82void *vm_ih;
29
30#include "opt_ddb.h"
31
32#include <sys/param.h>
33#include <sys/bus.h>
34#include <sys/conf.h>
35#include <sys/rtprio.h>
36#include <sys/systm.h>

--- 38 unchanged lines hidden (view full) ---

75 struct thread *td;
76 uintptr_t event;
77};
78
79struct intr_event *clk_intr_event;
80struct intr_event *tty_intr_event;
81void *softclock_ih;
82void *vm_ih;
83struct proc *intrproc;
83
84static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads");
85
86static int intr_storm_threshold = 1000;
87TUNABLE_INT("hw.intr_storm_threshold", &intr_storm_threshold);
88SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RW,
89 &intr_storm_threshold, 0,
90 "Number of consecutive interrupts before storm protection is enabled");

--- 75 unchanged lines hidden (view full) ---

166
167 /* Determine the overall priority of this event. */
168 if (TAILQ_EMPTY(&ie->ie_handlers))
169 pri = PRI_MAX_ITHD;
170 else
171 pri = TAILQ_FIRST(&ie->ie_handlers)->ih_pri;
172
173 /* Update name and priority. */
84
85static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads");
86
87static int intr_storm_threshold = 1000;
88TUNABLE_INT("hw.intr_storm_threshold", &intr_storm_threshold);
89SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RW,
90 &intr_storm_threshold, 0,
91 "Number of consecutive interrupts before storm protection is enabled");

--- 75 unchanged lines hidden (view full) ---

167
168 /* Determine the overall priority of this event. */
169 if (TAILQ_EMPTY(&ie->ie_handlers))
170 pri = PRI_MAX_ITHD;
171 else
172 pri = TAILQ_FIRST(&ie->ie_handlers)->ih_pri;
173
174 /* Update name and priority. */
174 strlcpy(td->td_proc->p_comm, ie->ie_fullname,
175 sizeof(td->td_proc->p_comm));
175 strlcpy(td->td_name, ie->ie_fullname, sizeof(td->td_name));
176 thread_lock(td);
177 sched_prio(td, pri);
178 thread_unlock(td);
179}
180
181/*
182 * Regenerate the full name of an interrupt event and update its priority.
183 */

--- 143 unchanged lines hidden (view full) ---

327}
328
329#ifndef INTR_FILTER
330static struct intr_thread *
331ithread_create(const char *name)
332{
333 struct intr_thread *ithd;
334 struct thread *td;
176 thread_lock(td);
177 sched_prio(td, pri);
178 thread_unlock(td);
179}
180
181/*
182 * Regenerate the full name of an interrupt event and update its priority.
183 */

--- 143 unchanged lines hidden (view full) ---

327}
328
329#ifndef INTR_FILTER
330static struct intr_thread *
331ithread_create(const char *name)
332{
333 struct intr_thread *ithd;
334 struct thread *td;
335 struct proc *p;
336 int error;
337
338 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO);
339
335 int error;
336
337 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO);
338
340 error = kproc_create(ithread_loop, ithd, &p, RFSTOPPED | RFHIGHPID,
341 0, "%s", name);
339 error = kproc_kthread_add(ithread_loop, ithd, &intrproc,
340 &td, RFSTOPPED | RFHIGHPID,
341 0, "interd", "%s", name);
342 if (error)
343 panic("kproc_create() failed with %d", error);
342 if (error)
343 panic("kproc_create() failed with %d", error);
344 td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
345 thread_lock(td);
346 sched_class(td, PRI_ITHD);
347 TD_SET_IWAIT(td);
348 thread_unlock(td);
349 td->td_pflags |= TDP_ITHREAD;
350 ithd->it_thread = td;
351 CTR2(KTR_INTR, "%s: created %s", __func__, name);
352 return (ithd);
353}
354#else
355static struct intr_thread *
356ithread_create(const char *name, struct intr_handler *ih)
357{
358 struct intr_thread *ithd;
359 struct thread *td;
344 thread_lock(td);
345 sched_class(td, PRI_ITHD);
346 TD_SET_IWAIT(td);
347 thread_unlock(td);
348 td->td_pflags |= TDP_ITHREAD;
349 ithd->it_thread = td;
350 CTR2(KTR_INTR, "%s: created %s", __func__, name);
351 return (ithd);
352}
353#else
354static struct intr_thread *
355ithread_create(const char *name, struct intr_handler *ih)
356{
357 struct intr_thread *ithd;
358 struct thread *td;
360 struct proc *p;
361 int error;
362
363 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO);
364
359 int error;
360
361 ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO);
362
365 error = kproc_create(ithread_loop, ih, &p, RFSTOPPED | RFHIGHPID,
366 0, "%s", name);
363 error = kproc_kthread_create(ithread_loop, ih, &intrproc,
364 &td, RFSTOPPED | RFHIGHPID,
365 0, "interd", "%s", name);
367 if (error)
368 panic("kproc_create() failed with %d", error);
366 if (error)
367 panic("kproc_create() failed with %d", error);
369 td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
370 thread_lock(td);
371 sched_class(td, PRI_ITHD);
372 TD_SET_IWAIT(td);
373 thread_unlock(td);
374 td->td_pflags |= TDP_ITHREAD;
375 ithd->it_thread = td;
376 CTR2(KTR_INTR, "%s: created %s", __func__, name);
377 return (ithd);

--- 305 unchanged lines hidden (view full) ---

683 p = td->td_proc;
684
685 /*
686 * If any of the handlers for this ithread claim to be good
687 * sources of entropy, then gather some.
688 */
689 if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) {
690 CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__,
368 thread_lock(td);
369 sched_class(td, PRI_ITHD);
370 TD_SET_IWAIT(td);
371 thread_unlock(td);
372 td->td_pflags |= TDP_ITHREAD;
373 ithd->it_thread = td;
374 CTR2(KTR_INTR, "%s: created %s", __func__, name);
375 return (ithd);

--- 305 unchanged lines hidden (view full) ---

681 p = td->td_proc;
682
683 /*
684 * If any of the handlers for this ithread claim to be good
685 * sources of entropy, then gather some.
686 */
687 if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) {
688 CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__,
691 p->p_pid, p->p_comm);
689 p->p_pid, td->td_name);
692 entropy.event = (uintptr_t)ie;
693 entropy.td = ctd;
694 random_harvest(&entropy, sizeof(entropy), 2, 0,
695 RANDOM_INTERRUPT);
696 }
697
698 KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
699
700 /*
701 * Set it_need to tell the thread to keep running if it is already
702 * running. Then, lock the thread and see if we actually need to
703 * put it on the runqueue.
704 */
705 it->it_need = 1;
706 thread_lock(td);
707 if (TD_AWAITING_INTR(td)) {
708 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
690 entropy.event = (uintptr_t)ie;
691 entropy.td = ctd;
692 random_harvest(&entropy, sizeof(entropy), 2, 0,
693 RANDOM_INTERRUPT);
694 }
695
696 KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
697
698 /*
699 * Set it_need to tell the thread to keep running if it is already
700 * running. Then, lock the thread and see if we actually need to
701 * put it on the runqueue.
702 */
703 it->it_need = 1;
704 thread_lock(td);
705 if (TD_AWAITING_INTR(td)) {
706 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
709 p->p_comm);
707 td->td_name);
710 TD_CLR_IWAIT(td);
711 sched_add(td, SRQ_INTR);
712 } else {
713 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
708 TD_CLR_IWAIT(td);
709 sched_add(td, SRQ_INTR);
710 } else {
711 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
714 __func__, p->p_pid, p->p_comm, it->it_need, td->td_state);
712 __func__, p->p_pid, td->td_name, it->it_need, td->td_state);
715 }
716 thread_unlock(td);
717
718 return (0);
719}
720#else
721int
722intr_event_remove_handler(void *cookie)

--- 114 unchanged lines hidden (view full) ---

837 p = td->td_proc;
838
839 /*
840 * If any of the handlers for this ithread claim to be good
841 * sources of entropy, then gather some.
842 */
843 if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) {
844 CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__,
713 }
714 thread_unlock(td);
715
716 return (0);
717}
718#else
719int
720intr_event_remove_handler(void *cookie)

--- 114 unchanged lines hidden (view full) ---

835 p = td->td_proc;
836
837 /*
838 * If any of the handlers for this ithread claim to be good
839 * sources of entropy, then gather some.
840 */
841 if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) {
842 CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__,
845 p->p_pid, p->p_comm);
843 p->p_pid, td->td_name);
846 entropy.event = (uintptr_t)ie;
847 entropy.td = ctd;
848 random_harvest(&entropy, sizeof(entropy), 2, 0,
849 RANDOM_INTERRUPT);
850 }
851
852 KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
853
854 /*
855 * Set it_need to tell the thread to keep running if it is already
856 * running. Then, lock the thread and see if we actually need to
857 * put it on the runqueue.
858 */
859 it->it_need = 1;
860 thread_lock(td);
861 if (TD_AWAITING_INTR(td)) {
862 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
844 entropy.event = (uintptr_t)ie;
845 entropy.td = ctd;
846 random_harvest(&entropy, sizeof(entropy), 2, 0,
847 RANDOM_INTERRUPT);
848 }
849
850 KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
851
852 /*
853 * Set it_need to tell the thread to keep running if it is already
854 * running. Then, lock the thread and see if we actually need to
855 * put it on the runqueue.
856 */
857 it->it_need = 1;
858 thread_lock(td);
859 if (TD_AWAITING_INTR(td)) {
860 CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
863 p->p_comm);
861 th->th_name);
864 TD_CLR_IWAIT(td);
865 sched_add(td, SRQ_INTR);
866 } else {
867 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
862 TD_CLR_IWAIT(td);
863 sched_add(td, SRQ_INTR);
864 } else {
865 CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
868 __func__, p->p_pid, p->p_comm, it->it_need, td->td_state);
866 __func__, p->p_pid, td->td_name, it->it_need, td->td_state);
869 }
870 thread_unlock(td);
871
872 return (0);
873}
874#endif
875
876/*

--- 218 unchanged lines hidden (view full) ---

1095 * list of handlers, giving each one a go at it.
1096 */
1097 for (;;) {
1098 /*
1099 * If we are an orphaned thread, then just die.
1100 */
1101 if (ithd->it_flags & IT_DEAD) {
1102 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
867 }
868 thread_unlock(td);
869
870 return (0);
871}
872#endif
873
874/*

--- 218 unchanged lines hidden (view full) ---

1093 * list of handlers, giving each one a go at it.
1094 */
1095 for (;;) {
1096 /*
1097 * If we are an orphaned thread, then just die.
1098 */
1099 if (ithd->it_flags & IT_DEAD) {
1100 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
1103 p->p_pid, p->p_comm);
1101 p->p_pid, td->td_name);
1104 free(ithd, M_ITHREAD);
1102 free(ithd, M_ITHREAD);
1105 kproc_exit(0);
1103 kthread_exit(0);
1106 }
1107
1108 /*
1109 * Service interrupts. If another interrupt arrives while
1110 * we are running, it will set it_need to note that we
1111 * should make another pass.
1112 */
1113 while (ithd->it_need) {

--- 52 unchanged lines hidden (view full) ---

1166 * list of handlers, giving each one a go at it.
1167 */
1168 for (;;) {
1169 /*
1170 * If we are an orphaned thread, then just die.
1171 */
1172 if (ithd->it_flags & IT_DEAD) {
1173 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
1104 }
1105
1106 /*
1107 * Service interrupts. If another interrupt arrives while
1108 * we are running, it will set it_need to note that we
1109 * should make another pass.
1110 */
1111 while (ithd->it_need) {

--- 52 unchanged lines hidden (view full) ---

1164 * list of handlers, giving each one a go at it.
1165 */
1166 for (;;) {
1167 /*
1168 * If we are an orphaned thread, then just die.
1169 */
1170 if (ithd->it_flags & IT_DEAD) {
1171 CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
1174 p->p_pid, p->p_comm);
1172 p->p_pid, td->td_name);
1175 free(ithd, M_ITHREAD);
1173 free(ithd, M_ITHREAD);
1176 kproc_exit(0);
1174 kthread_exit(0);
1177 }
1178
1179 /*
1180 * Service interrupts. If another interrupt arrives while
1181 * we are running, it will set it_need to note that we
1182 * should make another pass.
1183 */
1184 while (ithd->it_need) {

--- 383 unchanged lines hidden ---
1175 }
1176
1177 /*
1178 * Service interrupts. If another interrupt arrives while
1179 * we are running, it will set it_need to note that we
1180 * should make another pass.
1181 */
1182 while (ithd->it_need) {

--- 383 unchanged lines hidden ---