qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests


From: Marcelo Tosatti
Subject: Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests
Date: Tue, 18 Oct 2011 11:48:23 -0200
User-agent: Mutt/1.5.21 (2010-09-15)

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 <address@hidden>
> ---
>  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?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]