very rough if_sk fixes
Doug White
dwhite at gumbysoft.com
Mon Jun 14 01:23:23 GMT 2004
Hey all,
I ran out and bought a Linksys EG1032 today and fixed up some of the
witness warnings and a detach panic. I'm not 100% sure my lock relocation
is totally correct, though, so if someone wants to look at this and tell
me I have no idea what I'm doing, that'd be great. :-) Suggestions
appreciated. In particular I may need to tighten up the locking and
ordering in skc_detach() since I'm not sure if we can take an interrupt in
that context, and it'd be kinda bad to.
Most of the changes were trivial... too trivial maybe :-)
I'm also hoarding a copy of this patch at
http://people.freebsd.org/~dwhite/if_sk.c.diff if the attachment doesn't
come through.
Thanks!
--
Doug White | FreeBSD: The Power to Serve
dwhite at gumbysoft.com | www.FreeBSD.org
-------------- next part --------------
--- if_sk.c.orig Sun Jun 13 16:50:15 2004
+++ if_sk.c Sun Jun 13 18:11:16 2004
@@ -1446,11 +1446,22 @@
callout_handle_init(&sc_if->sk_tick_ch);
+ /* XXX dwhite
+ * Drop interface lock around ether_ifattach, which
+ * cannot be called with locks held.
+ */
+ SK_UNLOCK(sc);
+
/*
* Call MI attach routine.
*/
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
+ /* XXX dwhite
+ * Pick the lock back up.
+ */
+ SK_LOCK(sc);
+
/*
* Do miibus setup.
*/
@@ -1647,7 +1658,7 @@
bus_generic_attach(dev);
/* Hook interrupt last to avoid having to lock softc */
- error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
+ error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET|INTR_MPSAFE,
sk_intr, sc, &sc->sk_intrhand);
if (error) {
@@ -1685,10 +1696,22 @@
/* These should only be active if attach_xmac succeeded */
if (device_is_attached(dev)) {
sk_stop(sc_if);
+ /* XXX dwhite
+ * Can't hold locks while calling detach
+ */
+ SK_IF_UNLOCK(sc_if);
ether_ifdetach(ifp);
+ SK_IF_LOCK(sc_if);
}
+ /* XXX dwhite
+ * We're generally called from skc_detach() which is using
+ * device_delete_child() to get to here. It's already trashed
+ * miibus for us, so don't do it here or we'll panic.
+ */
+ /*
if (sc_if->sk_miibus)
device_delete_child(dev, sc_if->sk_miibus);
+ */
bus_generic_detach(dev);
if (sc_if->sk_cdata.sk_jumbo_buf)
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
@@ -1709,7 +1732,12 @@
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->sk_mtx), ("sk mutex not initialized"));
+ /* XXX dwhite
+ * Don't need the locks here?
+ */
+ /*
SK_LOCK(sc);
+ */
if (device_is_alive(dev)) {
if (sc->sk_devs[SK_PORT_A] != NULL)
@@ -1726,7 +1754,12 @@
if (sc->sk_res)
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
+ /* XXX dwhite
+ * Don't need this?
+ */
+ /*
SK_UNLOCK(sc);
+ */
mtx_destroy(&sc->sk_mtx);
return(0);
More information about the freebsd-current
mailing list