Am 19.10.2011 16:59, schrieb Paolo Bonzini: > The big conversion of bdrv_read/write to coroutines caused the two > homonymous callbacks in BlockDriver to become reentrant. It goes > like this: > > 1) bdrv_read is now called in a coroutine, and calls bdrv_read or > bdrv_pread. > > 2) the nested bdrv_read goes through the fast path in bdrv_rw_co_entry; > > 3) in the common case when the protocol is file, bdrv_co_do_readv calls > bdrv_co_readv_em (and from here goes to bdrv_co_io_em), which yields > until the AIO operation is complete; > > 4) if bdrv_read had been called from a bottom half, the main loop > is free to iterate again: a device model or another bottom half > can then come and call bdrv_read again. > > This applies to all four of read/write/flush/discard. It would also > apply to is_allocated, but it is not used from within coroutines: > besides qemu-img.c and qemu-io.c, which operate synchronously, the > only user is the monitor. Copy-on-read will introduce a use in the > block layer, and will require converting it. > > The solution is "simply" to convert all drivers to coroutines! We > have nothing to do for the read-only drivers. For the others, we > add a Rwlock that is taken around affected operations. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
For the record, we just discussed this on IRC: We'll probably need a mutex in some/most cases instead. Also, cloop and dmg need locking. That leaves only bochs and parallels that should be okay without a lock. We decided to play it the safe way and add locking in every driver and make it a mutex everywhere. Kevin