On Tue, Aug 27, 2013 at 05:55:26PM -0500, Yaodong Yang wrote: > Step 3: > file block.c > function: > static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, > int64_t sector_num, > QEMUIOVector *qiov, > int nb_sectors, > BlockDriverCompletionFunc *cb, > void *opaque, > bool is_write) > This function create a coroutine and then enter this coroutine. > co = qemu_coroutine_create(bdrv_co_do_rw); > qemu_coroutine_enter(co, acb); > > My questions: > 1. What is the purpose of creating a coroutine here?
A coroutine can yield back to the event loop and can be resumed again later. This is useful for code paths where requests must wait for each other (e.g. I/O throttling, copy-on-read, allocating writes to the same region). > Step 4: > file: block.c > function: static void coroutine_fn bdrv_co_do_rw(void *opaque) > In this function, the bdrv_co_do_readv() is called. and After it, it create a > bottom-half and then schedule this buttom half. > acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, > acb->req.nb_sectors, acb->req.qiov, 0); > > My questions: > 1. is the bdrv_co_do_readv function called within the IOthread or Migration > thread? It will be called in the migration thread but the global mutex has been acquired, so the iothread must wait. > Step 5 > file: block.c > function: static void bdrv_co_em_bh(void *opaque) > > My questions: > 1. Is this function called within the IOthread or Migration thread? It depends: aio_poll() dispatches BHs that are ready, so BHs can be invoked from the migration thread if something is calling aio_poll() (like bdrv_read()/bdrv_pread()/etc). In the case of bdrv_aio_readv() the BH will probably be executed later in the iothread since the caller did not wait for the request to complete by calling aio_poll() in a loop. > In sum, > I do not know clearly how the coroutine, bottom-half schemes are used for the > migration job. is there any reference material related? The migration thread grabs the global mutex before accessing the BlockDriverState, so the iothread has to wait. Therefore you don't really need to worry about which thread you are in. I hope my answers have made the relationships a bit clearer for you. Ultimately you need to read the qemu.git/master code, there is no stable API and things change over time. Stefan