cvs commit: src/sys/dev/fxp if_fxp.c if_fxpvar.h
John Baldwin
jhb at FreeBSD.org
Tue Apr 29 11:44:28 PDT 2003
On 29-Apr-2003 Nate Lawson wrote:
> On Mon, 28 Apr 2003, Warner Losh wrote:
>> Modified files:
>> sys/dev/fxp if_fxp.c if_fxpvar.h
>> Log:
>> Fix 5 bugs:
>> 1) always call fxp_stop in fxp_detach. Since we don't read from
>> the card, there's no need to carefully look at things with
>> bus_child_present.
>
> However, we do write to the card registers (i.e. to disable interrupt
> generation). Since you were the one who suggested I should add these
> calls, can you give more information about when bus_child_present should
> be used (and update the man page if anything changed)?
>
>> 2) Call FXP_UNLOCK() before calling bus_teardown_intr to avoid
>> a possible deadlock reported by jhb.
>
> This adds a race since fxp_intr could occur after the unlock but before
> the bus_teardown_intr call. The reason why I tore down the intr while
> holding the lock is so fxp_intr would be prevented from accessing the
> device until it has been disabled. Then the normal checks in fxp_intr
> (IFF_OACTIVE or whatever) would show the card is gone and return without
> accessing it. I guess this is ok since ether_ifdetach is still called
> with the lock held (since it is what clears IFF_OACTIVE) but I'm
> interested in your thoughts.
>
>> 3) add gone to the softc. Set it to true in detach.
>> 4) Return immediately if gone is true in fxp_ioctl
>> 5) Return immediately if gone is true in fxp_intr
>
> Not sure this approach is necessary.
It is quite necessary:
/*
* If the interrupt thread is already running, then just mark this
* handler as being dead and let the ithread do the actual removal.
*/
mtx_lock_spin(&sched_lock);
if (!TD_AWAITING_INTR(ithread->it_td)) {
handler->ih_flags |= IH_DEAD;
...
mtx_unlock_spin(&sched_lock);
if ((handler->ih_flags & IH_DEAD) != 0)
msleep(handler, &ithread->it_lock, PUSER, "itrmh", 0);
and in ithread_loop():
if ((ih->ih_flags & IH_DEAD) != 0) {
mtx_lock(&ithd->it_lock);
TAILQ_REMOVE(&ithd->it_handlers, ih,
ih_next);
wakeup(ih);
mtx_unlock(&ithd->it_lock);
goto restart;
}
This is how we ensure that the interrupt handler is never executed
once bus_teardown_intr() returns.
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!" - http://www.FreeBSD.org/
More information about the cvs-src
mailing list