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: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests
Date: Thu, 20 Oct 2011 10:34:04 -0700

On Tue, Oct 18, 2011 at 6:48 AM, Marcelo Tosatti <address@hidden> wrote:
> 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?

CoQueue is FIFO so overlapping requests are processed in order and
will not wait indefinitely.

Stefan



reply via email to

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