From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:56410) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGA2r-0003BM-LU for qemu-devel@nongnu.org; Tue, 18 Oct 2011 09:49:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGA2q-0006jB-97 for qemu-devel@nongnu.org; Tue, 18 Oct 2011 09:49:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32982) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGA2p-0006ix-Ot for qemu-devel@nongnu.org; Tue, 18 Oct 2011 09:49:28 -0400 Date: Tue, 18 Oct 2011 11:48:23 -0200 From: Marcelo Tosatti Message-ID: <20111018134823.GA21122@amt.cnet> References: <1318866452-30026-1-git-send-email-stefanha@linux.vnet.ibm.com> <1318866452-30026-4-git-send-email-stefanha@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1318866452-30026-4-git-send-email-stefanha@linux.vnet.ibm.com> Subject: Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Stefan Hajnoczi Cc: Kevin Wolf , Paolo Bonzini , qemu-devel@nongnu.org On Mon, Oct 17, 2011 at 04:47:29PM +0100, Stefan Hajnoczi wrote: > When copy-on-read is enabled it is necessary to wait for overlapping > requests before issuing new requests. This prevents races between the > copy-on-read and a write request. > > Signed-off-by: Stefan Hajnoczi > --- > block.c | 39 +++++++++++++++++++++++++++++++++++++++ > 1 files changed, 39 insertions(+), 0 deletions(-) > > diff --git a/block.c b/block.c > index e624ac3..cc3202c 100644 > --- a/block.c > +++ b/block.c > @@ -1001,6 +1001,7 @@ struct BdrvTrackedRequest { > int nb_sectors; > bool is_write; > QLIST_ENTRY(BdrvTrackedRequest) list; > + CoQueue wait_queue; /* coroutines blocked on this request */ > }; > > /** > @@ -1014,6 +1015,12 @@ static void tracked_request_remove(BdrvTrackedRequest *req) > { > if (req) { > QLIST_REMOVE(req, list); > + > + /* Wake up all coroutines blocked on this request */ > + while (qemu_co_queue_next(&req->wait_queue)) { > + /* Do nothing */ > + } > + > g_free(req); > } > } > @@ -1038,12 +1045,36 @@ static BdrvTrackedRequest *tracked_request_add(BlockDriverState *bs, > req->sector_num = sector_num; > req->nb_sectors = nb_sectors; > req->is_write = is_write; > + qemu_co_queue_init(&req->wait_queue); > > QLIST_INSERT_HEAD(&bs->tracked_requests, req, list); > > return req; > } > > +static bool tracked_request_overlaps(BdrvTrackedRequest *req, > + int64_t sector_num, int nb_sectors) { > + return false; /* not yet implemented */ > +} > + > +static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs, > + int64_t sector_num, int nb_sectors) > +{ > + BdrvTrackedRequest *req; > + bool retry; > + > + do { > + retry = false; > + QLIST_FOREACH(req, &bs->tracked_requests, list) { > + if (tracked_request_overlaps(req, sector_num, nb_sectors)) { > + qemu_co_queue_wait(&req->wait_queue); > + retry = true; What prevents overlapping requests (from waiter criteria) to be inserted to the queue while there are waiters again? That is, why is it not possible for a waiter to wait indefinetely?