[Top][All Lists]
[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
- Re: [Qemu-devel] [RFC 1/6] block: add request tracking,
Kevin Wolf <=