qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC 1/6] block: add request tracking


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [RFC 1/6] block: add request tracking
Date: Thu, 3 Nov 2011 07:57:44 +0000

On Wed, Nov 2, 2011 at 4:30 PM, Kevin Wolf <address@hidden> wrote:
> Am 17.10.2011 17:47, schrieb Stefan Hajnoczi:
>> The block layer does not know about pending requests.  This information
>> is necessary for copy-on-read since overlapping requests must be
>> serialized to prevent races that corrupt the image.
>>
>> Add a simple mechanism to enable/disable request tracking.  By default
>> request tracking is disabled.
>>
>> The BlockDriverState gets a new tracked_request list field which
>> contains all pending requests.  Each request is a BdrvTrackedRequest
>> record with sector_num, nb_sectors, and is_write fields.
>>
>> Signed-off-by: Stefan Hajnoczi <address@hidden>
>> ---
>>  block.c     |   83 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  block_int.h |    8 +++++
>>  2 files changed, 90 insertions(+), 1 deletions(-)
>>
>> diff --git a/block.c b/block.c
>> index 9873b57..2d2c62a 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -978,6 +978,77 @@ void bdrv_commit_all(void)
>>      }
>>  }
>>
>> +struct BdrvTrackedRequest {
>> +    BlockDriverState *bs;
>> +    int64_t sector_num;
>> +    int nb_sectors;
>> +    bool is_write;
>> +    QLIST_ENTRY(BdrvTrackedRequest) list;
>> +};
>> +
>> +/**
>> + * Remove an active request from the tracked requests list
>> + *
>> + * If req is NULL, no operation is performed.
>> + *
>> + * This function should be called when a tracked request is completing.
>> + */
>> +static void tracked_request_remove(BdrvTrackedRequest *req)
>> +{
>> +    if (req) {
>> +        QLIST_REMOVE(req, list);
>> +        g_free(req);
>> +    }
>> +}
>> +
>> +/**
>> + * Add an active request to the tracked requests list
>> + *
>> + * Return NULL if request tracking is disabled, non-NULL otherwise.
>> + */
>> +static BdrvTrackedRequest *tracked_request_add(BlockDriverState *bs,
>> +                                               int64_t sector_num,
>> +                                               int nb_sectors, bool 
>> is_write)
>> +{
>> +    BdrvTrackedRequest *req;
>> +
>> +    if (!bs->request_tracking) {
>> +        return NULL;
>> +    }
>> +
>> +    req = g_malloc(sizeof(*req));
>> +    req->bs = bs;
>> +    req->sector_num = sector_num;
>> +    req->nb_sectors = nb_sectors;
>> +    req->is_write = is_write;
>
> How about using g_malloc0 or a compound literal assignment for
> initialisation, so that we won't get surprises when the struct is extended?

Sure.

>> +
>> +    QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
>> +
>> +    return req;
>> +}
>> +
>> +/**
>> + * Enable tracking of incoming requests
>> + *
>> + * Request tracking can be safely used by multiple users at the same time,
>> + * there is an internal reference count to match start and stop calls.
>> + */
>> +void bdrv_start_request_tracking(BlockDriverState *bs)
>> +{
>> +    bs->request_tracking++;
>> +}
>> +
>> +/**
>> + * Disable tracking of incoming requests
>> + *
>> + * Note that in-flight requests are still tracked, this function only stops
>> + * tracking incoming requests.
>> + */
>> +void bdrv_stop_request_tracking(BlockDriverState *bs)
>> +{
>> +    bs->request_tracking--;
>> +}
>> +
>>  /*
>>   * Return values:
>>   * 0        - success
>> @@ -1262,6 +1333,8 @@ static int coroutine_fn 
>> bdrv_co_do_readv(BlockDriverState *bs,
>>      int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
>>  {
>>      BlockDriver *drv = bs->drv;
>> +    BdrvTrackedRequest *req;
>> +    int ret;
>>
>>      if (!drv) {
>>          return -ENOMEDIUM;
>> @@ -1270,7 +1343,10 @@ static int coroutine_fn 
>> bdrv_co_do_readv(BlockDriverState *bs,
>>          return -EIO;
>>      }
>>
>> -    return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
>> +    req = tracked_request_add(bs, sector_num, nb_sectors, false);
>> +    ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
>> +    tracked_request_remove(req);
>
> Hm... Do we actually need to malloc the BdrvTrackedRequest? If all users
> are like this (and at least those in this patch are), we can just keep
> it on the coroutine stack.

Okay.

Stefan



reply via email to

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