Updated switch/glue patch?

Stefan Bethke stb at lassitu.de
Thu Dec 29 10:50:11 UTC 2011


Am 29.12.2011 um 11:18 schrieb Stefan Bethke:

>> http://gitorious.org/~stb/freebsd/stb-adrianchadd-freebsd-work (branch work/ath)
>> http://www.lassitu.de/freebsd/etherswitch-adrian.patch (patch against Adrians gitorious repo as of now)
>> http://www.lassitu.de/freebsd/etherswitch.tbz (all files)
> 
> I've now gotten the panic again with the callout:
> Sleeping on "rtl8366rbstart" with the following non-sleepable locks held:
> exclusive sleep mutex rtl8366rbcallout (rtl8366rbcallout) r = 0 (0x80769114) locked @ /home/stb/working/fe/stb-adrianchadd-freebsd-work/sys/kern/kern_mutex.c:148
> 
> callout_init_mtx() says
>> The usable lock classes are currently limited to mutexes and rwlocks, because callout handlers run in softclock swi, so they cannot sleep nor acquire sleepable locks like sx or lockmgr.
> 
> The way I read that, any callout will be run in a way that does not allow sleeping.  I'm not sure how to handle this.

Here's one way, replacing the callout with a thread:
diff --git a/sys/dev/etherswitch/rtl8366rb.c b/sys/dev/etherswitch/rtl8366rb.c
index 599f5f0..2acb206 100644
--- a/sys/dev/etherswitch/rtl8366rb.c
+++ b/sys/dev/etherswitch/rtl8366rb.c
@@ -30,6 +30,7 @@
 #include <sys/bus.h>
 #include <sys/errno.h>
 #include <sys/kernel.h>
+#include <sys/kthread.h>
 #include <sys/module.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
@@ -60,13 +61,13 @@
 
 struct rtl8366rb_softc {
        struct mtx      smi_mtx;        /* serialize access to SMI/I2C bus */
-       struct mtx      callout_mtx;    /* serialize callout */
        device_t        dev;
        char            *ifname[RTL8366RB_NUM_PHYS];
        device_t        miibus[RTL8366RB_NUM_PHYS];
        struct ifnet    *ifp[RTL8366RB_NUM_PHYS];
        device_t        etherswitch;
-       struct callout  callout_tick;
+       struct thread   *tickthread;
+       int             ticking;
 };
 
 static etherswitch_info_t etherswitch_info = {
@@ -171,7 +172,6 @@ rtl8366rb_attach(device_t dev)
        sc = device_get_softc(dev);
        sc->dev = dev;
        mtx_init(&sc->smi_mtx, "rtl8366rbsmi", NULL, MTX_DEF);
-       mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
 
        rtl8366rb_init(dev);
        smi_read(dev, RTL8366RB_CVCR, &rev);
@@ -202,8 +202,9 @@ rtl8366rb_attach(device_t dev)
        if (err != 0)
                return (err);
        
-       callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
-       rtl8366rb_tick(sc);
+       sc->ticking = 1;
+       kthread_add(rtl8366rb_tick, sc, NULL, &sc->tickthread, 0, 0, \
+               "%s tick", device_get_nameunit(dev));
        
        return (err);
 }
@@ -217,6 +218,11 @@ rtl8366rb_detach(device_t dev)
        sc = device_get_softc(dev);
        if (sc->etherswitch)
                device_delete_child(dev, sc->etherswitch);
+       if (sc->ticking) {
+               sc->ticking = 0;
+               wakeup_one(sc->tickthread);
+               tsleep(sc, 0, "tickexit", 0);
+       }
        for (i=0; i < RTL8366RB_NUM_PHYS; i++) {
                if (sc->miibus[i])
                        device_delete_child(dev, sc->miibus[i]);
@@ -225,8 +231,6 @@ rtl8366rb_detach(device_t dev)
                free(sc->ifname[i], M_DEVBUF);
        }
        bus_generic_detach(dev);
-       callout_drain(&sc->callout_tick);
-       mtx_destroy(&sc->callout_mtx);
        mtx_destroy(&sc->smi_mtx);
 
        return (0);
@@ -295,8 +299,12 @@ rtl8366rb_tick(void *arg)
 {
        struct rtl8366rb_softc *sc = arg;
 
-       rtl833rb_miipollstat(sc);
-       callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
+       while (sc->ticking) {
+               rtl833rb_miipollstat(sc);
+               tsleep(sc->tickthread, 0, "tick", hz);
+       };
+       wakeup_one(sc);
+       kthread_exit();
 }
 
 static int


-- 
Stefan Bethke <stb at lassitu.de>   Fon +49 151 14070811





More information about the freebsd-embedded mailing list