cvs commit: src/sys/dev/md md.c

Scott Long scottl at samsco.org
Thu Sep 16 15:19:12 PDT 2004


Nate Lawson wrote:
> Pawel Jakub Dawidek wrote:
> 
>> On Thu, Sep 16, 2004 at 12:40:23PM -0700, Nate Lawson wrote:
>> +> >@@ -379,9 +379,8 @@
>> +> >     bp->bio_bcount = bp->bio_length;
>> +> >     mtx_lock(&sc->queue_mtx);
>> +> >     bioq_disksort(&sc->bio_queue, bp);
>> +> >-    mtx_unlock(&sc->queue_mtx);
>> +> >-
>> +> >     wakeup(sc);
>> +> >+    mtx_unlock(&sc->queue_mtx);
>> +> > }
>> +> +> I think the original order is correct since you can occur 2 
>> switches if +> you wakeup first and then unlock.
>>
>> Nope, this order was wrong:
>>
>> thread1        thread2
>> -----------------------
>> mtx_lock(mtx)
>> ...
>> mtx_unlock(mtx)
>>         mtx_lock(mtx)
>> wakeup(ptr)
>>         msleep(ptr, mtx) <- Race, it will be never woken up.
> 
> 
> You still have a race, like this:
> 
> thread1               thread2
> -----------------------------
> mtx_lock(mtx)
> wakeup(ptr)
> mtx_unlock(mtx)
>                       mtx_lock(mtx)
>                       msleep(ptr, mtx)
> 
> You should be checking the work condition in thread 2 while holding the 
> mutex but before going to sleep.  Adding work to the queue happens in 
> thread 1 where you write "..." and that is done with the mutex held so 
> there is no race.  The full diagram with this detail included is:
> 
> thread1               thread2
> -----------------------------
> mtx_lock(mtx)
> add work to queue
> mtx_unlock(mtx)
>                       mtx_lock(mtx)
> wakeup(ptr)
>                       check queue for work item
>                       if (!work item)
>                           msleep(ptr, mtx)
>                       else
>                           dequeue work item and loop
> 
> Since the work item is added in thread1 with the mutex held, the check 
> for it in thread2 is safe and race-free.  A wakeup is only there to 
> kickstart thread2 if it's asleep.  If it's running, it needs to check 
> atomically that there is no work before sleeping.  If it doesn't do 
> this, it's a bug.
> 

Or just use a semaphore.

Scott


More information about the cvs-src mailing list