cvs commit: src/sys/dev/re if_re.c
Ruslan Ermilov
ru at freebsd.org
Thu Sep 15 13:56:37 PDT 2005
On Thu, Sep 15, 2005 at 03:21:12PM -0400, John Baldwin wrote:
> On Thursday 15 September 2005 02:59 pm, Ruslan Ermilov wrote:
> > ru 2005-09-15 18:59:34 UTC
> >
> > FreeBSD src repository
> >
> > Modified files:
> > sys/dev/re if_re.c
> > Log:
> > re_detach() fixes:
> >
> > - Fixed if_free() logic screw-up that can either result
> > in freeing a NULL pointer or leaking "struct ifnet".
> > - Move if_free() after re_stop(); the latter accesses
> > "struct ifnet". This bug was masked by a previous bug.
> > - Restore the fix for a panic on detach caused by racing
> > with BPF detach code by Bill by moving ether_ifdetach()
> > after re_stop() and resetting IFF_UP; this got screwed
> > up in revs. 1.30 and 1.36.
>
> Device drivers should not modify IFF_UP. Instead, the interrupt handler
> should be checking IFF_DRV_RUNNING rather than IFF_UP (foo_stop() clears
> IFF_DRV_RUNNING).
>
Ideally they shoudn't, yes. But there are at least two scenarios
where resetting IFF_UP is currently used to attack bugs.
The first is the BPF detach bad interaction with foo_detach(),
as described in re_detach(). This panic is real with (I think)
all drivers. And testing IFF_DRV_RUNNING here doesn't seem to
be able to prevent the panic. Perhaps the fix would be to
move ether_ifdetach() before foo_stop() in foo_detach(), I'm
not yet sure.
Another panic sometimes seen on SMP machines on shutdown is when
foo_intr() is called after foo_shutdown() has already been called.
Some drivers (if_re, if_vr, if_ath) attack this problem by clearing
IFF_UP so that foo_intr() bails out quickly. I don't know if
anybody diagnosed the roots of this problem, but I have the
following idea: foo_shutdown() calls foo_stop() which disables
device interrupts. After foo_stop() has freed resources but
before interrupt has been teared down, another device that
shares the same IRQ generated an interrupt, and foo_intr() is
called again. It checks ISR register, and it has some interrupt
active, and the code calls some function that accesses already
freed memory. I don't have any real SMP hardware to play with,
so the above is pure theoretical. Do you think this is possible?
If so, checking IFF_DRV_RUNNING in foo_intr() should fix this.
If we can also fix the "BPF detach MII tick reactivation" panic
without involving resetting IFF_UP, all drivers can be cleaned
up to not much with IFF_UP.
Cheers,
--
Ruslan Ermilov
ru at FreeBSD.org
FreeBSD committer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/cvs-src/attachments/20050915/41abb4c1/attachment.bin
More information about the cvs-src
mailing list