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