From 1b2ec08c94b3d09c95e11a877daf1965557ae40f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 24 May 2006 17:22:53 +0000 Subject: [PATCH] Fix a race when detaching the cbb worker thread. There were a couple of cases where we didn't take out the lock before setting or clearing a bit. This apparently can lead to a race at kldunload time (at least on my Turion64 laptop, never saw it on my Sony Vaio). --- sys/dev/pccbb/pccbb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index a9bf97a5444..387795f0d72 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -330,7 +330,8 @@ cbb_detach(device_t brdev) mtx_lock(&sc->mtx); bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); sc->flags |= CBB_KTHREAD_DONE; - if (sc->flags & CBB_KTHREAD_RUNNING) { + while (sc->flags & CBB_KTHREAD_RUNNING) { + DEVPRINTF((sc->dev, "Waiting for thread to die\n")); cv_broadcast(&sc->cv); msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0); } @@ -481,7 +482,9 @@ cbb_event_thread(void *arg) int err; int not_a_card = 0; + mtx_lock(&sc->mtx); sc->flags |= CBB_KTHREAD_RUNNING; + mtx_unlock(&sc->mtx); while ((sc->flags & CBB_KTHREAD_DONE) == 0) { /* * We take out Giant here because we need it deep, @@ -538,7 +541,10 @@ cbb_event_thread(void *arg) err = cv_timedwait(&sc->cv, &sc->mtx, 1 * hz); mtx_unlock(&sc->mtx); } + DEVPRINTF((sc->dev, "Thread terminating\n")); + mtx_lock(&sc->mtx); sc->flags &= ~CBB_KTHREAD_RUNNING; + mtx_unlock(&sc->mtx); kthread_exit(0); }