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: Kevin Wolf
Subject: Re: [Qemu-devel] [RFC 1/6] block: add request tracking
Date: Wed, 02 Nov 2011 17:30:10 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110927 Thunderbird/7.0

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?

> +
> +    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.

Kevin



reply via email to

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