In some particular cases (like in pccard and pccbb), the real device
handler is wrapped in a couple of functions - a filter wrapper and an ithread wrapper. In this case (and just in this case), the filter wrapper could ask the system to schedule the ithread and mask the interrupt source if the wrapped handler is composed of just an ithread handler: modify the "old" interrupt code to make it support this situation, while the "new" interrupt code is already ok. Discussed with: jhb
This commit is contained in:
parent
bba4862c64
commit
3401f2c1df
@ -310,7 +310,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
struct thread *td;
|
||||
struct intr_event *ie;
|
||||
struct intr_handler *ih;
|
||||
int error, vector, thread;
|
||||
int error, vector, thread, ret;
|
||||
|
||||
td = curthread;
|
||||
|
||||
@ -356,6 +356,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
* a trapframe as its argument.
|
||||
*/
|
||||
td->td_intr_nesting_level++;
|
||||
ret = 0;
|
||||
thread = 0;
|
||||
critical_enter();
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
@ -367,9 +368,17 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
ih->ih_filter, ih->ih_argument == NULL ? frame :
|
||||
ih->ih_argument, ih->ih_name);
|
||||
if (ih->ih_argument == NULL)
|
||||
ih->ih_filter(frame);
|
||||
ret = ih->ih_filter(frame);
|
||||
else
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,7 +104,7 @@ arm_handler_execute(struct trapframe *frame, int irqnb)
|
||||
struct intr_event *event;
|
||||
struct intr_handler *ih;
|
||||
struct thread *td = curthread;
|
||||
int i, thread;
|
||||
int i, thread, ret;
|
||||
|
||||
PCPU_LAZY_INC(cnt.v_intr);
|
||||
td->td_intr_nesting_level++;
|
||||
@ -116,13 +116,22 @@ arm_handler_execute(struct trapframe *frame, int irqnb)
|
||||
continue;
|
||||
|
||||
/* Execute fast handlers. */
|
||||
ret = 0;
|
||||
thread = 0;
|
||||
TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
|
||||
if (ih->ih_filter == NULL)
|
||||
thread = 1;
|
||||
else
|
||||
ih->ih_filter(ih->ih_argument ?
|
||||
ret = ih->ih_filter(ih->ih_argument ?
|
||||
ih->ih_argument : frame);
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Schedule thread if needed. */
|
||||
|
@ -301,7 +301,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
struct thread *td;
|
||||
struct intr_event *ie;
|
||||
struct intr_handler *ih;
|
||||
int error, vector, thread;
|
||||
int error, vector, thread, ret;
|
||||
|
||||
td = curthread;
|
||||
|
||||
@ -347,6 +347,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
* a trapframe as its argument.
|
||||
*/
|
||||
td->td_intr_nesting_level++;
|
||||
ret = 0;
|
||||
thread = 0;
|
||||
critical_enter();
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
@ -358,9 +359,27 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
|
||||
ih->ih_filter, ih->ih_argument == NULL ? frame :
|
||||
ih->ih_argument, ih->ih_name);
|
||||
if (ih->ih_argument == NULL)
|
||||
ih->ih_filter(frame);
|
||||
ret = ih->ih_filter(frame);
|
||||
else
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
/*
|
||||
* Wrapper handler special handling:
|
||||
*
|
||||
* in some particular cases (like pccard and pccbb),
|
||||
* the _real_ device handler is wrapped in a couple of
|
||||
* functions - a filter wrapper and an ithread wrapper.
|
||||
* In this case (and just in this case), the filter wrapper
|
||||
* could ask the system to schedule the ithread and mask
|
||||
* the interrupt source if the wrapped handler is composed
|
||||
* of just an ithread handler.
|
||||
*
|
||||
* TODO: write a generic wrapper to avoid people rolling
|
||||
* their own
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -353,7 +353,7 @@ ia64_dispatch_intr(void *frame, unsigned long vector)
|
||||
struct ia64_intr *i;
|
||||
struct intr_event *ie; /* our interrupt event */
|
||||
struct intr_handler *ih;
|
||||
int error, thread;
|
||||
int error, thread, ret;
|
||||
|
||||
/*
|
||||
* Find the interrupt thread for this vector.
|
||||
@ -379,6 +379,7 @@ ia64_dispatch_intr(void *frame, unsigned long vector)
|
||||
* Execute all fast interrupt handlers directly without Giant. Note
|
||||
* that this means that any fast interrupt handler must be MP safe.
|
||||
*/
|
||||
ret = 0;
|
||||
thread = 0;
|
||||
critical_enter();
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
@ -388,7 +389,15 @@ ia64_dispatch_intr(void *frame, unsigned long vector)
|
||||
}
|
||||
CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
|
||||
ih->ih_filter, ih->ih_argument, ih->ih_name);
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
critical_exit();
|
||||
|
||||
|
@ -1264,9 +1264,6 @@ intr_filter_loop(struct intr_event *ie, struct trapframe *frame,
|
||||
continue;
|
||||
}
|
||||
|
||||
KASSERT(ret != FILTER_SCHEDULE_THREAD,
|
||||
("intr_filter_loop: FILTER_SCHEDULE_THREAD from filter"));
|
||||
|
||||
if (ret & FILTER_STRAY)
|
||||
continue;
|
||||
else {
|
||||
|
@ -198,7 +198,7 @@ intr_handle(u_int irq)
|
||||
struct ppc_intr *i;
|
||||
struct intr_event *ie;
|
||||
struct intr_handler *ih;
|
||||
int error, sched;
|
||||
int error, sched, ret;
|
||||
|
||||
i = ppc_intrs[irq];
|
||||
if (i == NULL)
|
||||
@ -216,6 +216,7 @@ intr_handle(u_int irq)
|
||||
* Execute all fast interrupt handlers directly without Giant. Note
|
||||
* that this means that any fast interrupt handler must be MP safe.
|
||||
*/
|
||||
ret = 0;
|
||||
sched = 0;
|
||||
critical_enter();
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
@ -225,7 +226,15 @@ intr_handle(u_int irq)
|
||||
}
|
||||
CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
|
||||
ih->ih_filter, ih->ih_argument, ih->ih_name);
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!sched) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
sched = 1;
|
||||
}
|
||||
}
|
||||
critical_exit();
|
||||
|
||||
|
@ -236,7 +236,7 @@ intr_execute_handlers(void *cookie)
|
||||
struct intr_vector *iv;
|
||||
struct intr_event *ie;
|
||||
struct intr_handler *ih;
|
||||
int error, thread;
|
||||
int error, thread, ret;
|
||||
|
||||
iv = cookie;
|
||||
ie = iv->iv_event;
|
||||
@ -246,6 +246,7 @@ intr_execute_handlers(void *cookie)
|
||||
}
|
||||
|
||||
/* Execute fast interrupt handlers directly. */
|
||||
ret = 0;
|
||||
thread = 0;
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
if (ih->ih_filter == NULL) {
|
||||
@ -255,7 +256,15 @@ intr_execute_handlers(void *cookie)
|
||||
MPASS(ih->ih_filter != NULL && ih->ih_argument != NULL);
|
||||
CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
|
||||
ih->ih_filter, ih->ih_argument);
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Schedule a heavyweight interrupt process. */
|
||||
|
@ -283,7 +283,7 @@ intr_execute_handlers(void *cookie)
|
||||
struct intr_vector *iv;
|
||||
struct intr_event *ie;
|
||||
struct intr_handler *ih;
|
||||
int fast, thread;
|
||||
int fast, thread, ret;
|
||||
|
||||
iv = cookie;
|
||||
ie = iv->iv_event;
|
||||
@ -292,6 +292,7 @@ intr_execute_handlers(void *cookie)
|
||||
return;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
fast = thread = 0;
|
||||
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
|
||||
if (ih->ih_filter == NULL) {
|
||||
@ -301,8 +302,16 @@ intr_execute_handlers(void *cookie)
|
||||
MPASS(ih->ih_filter != NULL && ih->ih_argument != NULL);
|
||||
CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
|
||||
ih->ih_filter, ih->ih_argument);
|
||||
ih->ih_filter(ih->ih_argument);
|
||||
ret = ih->ih_filter(ih->ih_argument);
|
||||
fast = 1;
|
||||
/*
|
||||
* Wrapper handler special case: see
|
||||
* i386/intr_machdep.c::intr_execute_handlers()
|
||||
*/
|
||||
if (!thread) {
|
||||
if (ret == FILTER_SCHEDULE_THREAD)
|
||||
thread = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Schedule a heavyweight interrupt process. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user