[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC 4/6] block: request overlap detection
From: |
Zhi Yong Wu |
Subject: |
Re: [Qemu-devel] [RFC 4/6] block: request overlap detection |
Date: |
Mon, 7 Nov 2011 19:49:13 +0800 |
On Mon, Oct 17, 2011 at 11:47 PM, Stefan Hajnoczi
<address@hidden> wrote:
> Detect overlapping requests and remember to align to cluster boundaries
> if the image format uses them. This assumes that allocating I/O is
> performed in cluster granularity - which is true for qcow2, qed, etc.
>
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
> block.c | 39 +++++++++++++++++++++++++++++++++++++--
> 1 files changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/block.c b/block.c
> index cc3202c..0c22741 100644
> --- a/block.c
> +++ b/block.c
> @@ -1052,21 +1052,56 @@ static BdrvTrackedRequest
> *tracked_request_add(BlockDriverState *bs,
> return req;
> }
>
> +/**
> + * Round a region to cluster boundaries
> + */
> +static void round_to_clusters(BlockDriverState *bs,
> + int64_t sector_num, int nb_sectors,
> + int64_t *cluster_sector_num,
> + int *cluster_nb_sectors)
> +{
> + BlockDriverInfo bdi;
> +
> + if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
> + *cluster_sector_num = sector_num;
> + *cluster_nb_sectors = nb_sectors;
> + } else {
> + int64_t c = bdi.cluster_size / BDRV_SECTOR_SIZE;
> + *cluster_sector_num = (sector_num / c) * c;
I can understand the above formula, but the one below is
very magic. :) and can not be understood by me.
> + *cluster_nb_sectors = ((sector_num % c) + nb_sectors + c - 1) / c *
> c;
> + }
> +}
> +
> static bool tracked_request_overlaps(BdrvTrackedRequest *req,
> int64_t sector_num, int nb_sectors) {
> - return false; /* not yet implemented */
> + /* aaaa bbbb */
> + if (sector_num >= req->sector_num + req->nb_sectors) {
> + return false;
> + }
> + /* bbbb aaaa */
> + if (req->sector_num >= sector_num + nb_sectors) {
> + return false;
> + }
> + return true;
> }
>
> static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
> int64_t sector_num, int nb_sectors)
> {
> BdrvTrackedRequest *req;
> + int64_t cluster_sector_num;
> + int cluster_nb_sectors;
> bool retry;
>
> + /* If we touch the same cluster it counts as an overlap */
> + round_to_clusters(bs, sector_num, nb_sectors,
> + &cluster_sector_num, &cluster_nb_sectors);
> +
> do {
> retry = false;
> QLIST_FOREACH(req, &bs->tracked_requests, list) {
> - if (tracked_request_overlaps(req, sector_num, nb_sectors)) {
> + if (tracked_request_overlaps(req, cluster_sector_num,
> + cluster_nb_sectors)) {
> qemu_co_queue_wait(&req->wait_queue);
> retry = true;
> break;
> --
> 1.7.6.3
>
>
>
--
Regards,
Zhi Yong Wu
- Re: [Qemu-devel] [RFC 4/6] block: request overlap detection,
Zhi Yong Wu <=