From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32874) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMyFu-0002gK-JA for qemu-devel@nongnu.org; Thu, 28 Aug 2014 07:52:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XMyFs-0000qB-Ly for qemu-devel@nongnu.org; Thu, 28 Aug 2014 07:52:42 -0400 Received: from mail-wi0-x22c.google.com ([2a00:1450:400c:c05::22c]:57302) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMyFs-0000q4-Df for qemu-devel@nongnu.org; Thu, 28 Aug 2014 07:52:40 -0400 Received: by mail-wi0-f172.google.com with SMTP id n3so7356197wiv.11 for ; Thu, 28 Aug 2014 04:52:38 -0700 (PDT) MIME-Version: 1.0 Date: Thu, 28 Aug 2014 15:52:38 +0400 Message-ID: From: Vladimir Sementsov-Ogievskij Content-Type: multipart/alternative; boundary=047d7bb040aa5b68870501af2c3f Subject: [Qemu-devel] bdrv_read race List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --047d7bb040aa5b68870501af2c3f Content-Type: text/plain; charset=UTF-8 calling bdrv_read in a loop leads to the follwing situation: bs->drv->bdrv_aio_readv is called, and finally calls bdrv_co_io_em_complete in other thread context. there is a possibility of calling bdrv_co_io_em_complete before calling qemu_coroutine_yield in bdrv_co_io_em. And qemu fails with "co-routine re-entered recursively". static void bdrv_co_io_em_complete(void *opaque, int ret) { CoroutineIOCompletion *co = opaque; co->ret = ret; qemu_coroutine_enter(co->coroutine, NULL); } static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *iov, bool is_write) { CoroutineIOCompletion co = { .coroutine = qemu_coroutine_self(), }; BlockDriverAIOCB *acb; if (is_write) { acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, bdrv_co_io_em_complete, &co); } else { acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, bdrv_co_io_em_complete, &co); } trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); if (!acb) { return -EIO; } qemu_coroutine_yield(); return co.ret; } is it a bug, or may be I don't understand something? Best regards, Vladimir --047d7bb040aa5b68870501af2c3f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
calling bdrv_read in a loop leads to the follwing situatio= n:

bs->drv->bdrv_aio_readv is called, and finally = calls=C2=A0bdrv_co_io_em_complete in other thread context.
there = is a possibility of calling=C2=A0bdrv_co_io_em_complete before calling=C2= =A0qemu_coroutine_yield in=C2=A0bdrv_co_io_em. And qemu fails with "co= -routine re-entered recursively".

static void bdrv_co_io_em_complete(void *opaque, i= nt ret)
{
=C2=A0 =C2=A0 CoroutineIOCompletion *co =3D o= paque;

=C2=A0 =C2=A0 co->ret =3D ret;
=C2=A0 =C2=A0 qemu_coroutine_enter(co->coroutine, NULL);
}

static int coroutine_fn bdrv_co_io_em(Block= DriverState *bs, int64_t sector_num,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int nb_sectors, QEMUIOVector *iov,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bool is_write)<= /div>
{
=C2=A0 =C2=A0 CoroutineIOCompletion co =3D {
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 .coroutine =3D qemu_coroutine_self(),
= =C2=A0 =C2=A0 };
=C2=A0 =C2=A0 BlockDriverAIOCB *acb;
<= br>
=C2=A0 =C2=A0 if (is_write) {
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 acb =3D bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_secto= rs,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bdrv_c= o_io_em_complete, &co);
=C2=A0 =C2=A0 } else {
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 acb =3D bs->drv->bdrv_aio_readv(bs, sector_n= um, iov, nb_sectors,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 bdrv_co_io_em_complete, &co);
=C2=A0 =C2=A0 }

=C2=A0 =C2=A0 trace_bdrv_co_i= o_em(bs, sector_num, nb_sectors, is_write, acb);
=C2=A0 =C2=A0 if= (!acb) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EIO;
=C2= =A0 =C2=A0 }
=C2=A0 =C2=A0 qemu_coroutine_yield();

=C2=A0 =C2=A0 return co.ret;
}

is it a bug, or may be I don't understand something?<= /div>

Best regards,
Vladimir
--047d7bb040aa5b68870501af2c3f--