From nobody Tue Apr 15 21:45:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1570711238; cv=none; d=zoho.com; s=zohoarc; b=M+l1lPpkDTnHm8w73QFQeKi1vC9KeC1CLB9mIPmLBWXdTZEZMANrW+XV1K9vOBipnvKUUljbzPaIPqTr6Zq5B6xR1cwysOB/X6WeV35CSHAwI+q4yF7sWkNNYuW/NF075f89QanF2+9agiuuYYfDxVa1Y43znO6BLnSl2gJoCbE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570711238; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DNAitkgnicIlaTlUZYR2hvzIwccRo3rGCkI4wsu5eOg=; b=RoF60b/WLXBWTw3WIbnoR7tXVs8hr0ni+JTJDtRTNaj0MK9xRR935RS3SHVOBPk0KUDBluaLbvlwuGZEZE7hpzOu3yJx2G+wcgVb9m3yaaDYJAZMp/lo0FbR78SnP8u5hswpAvLfSjHVSoJtS4rvrgK/MBAipTX96tRhgS1KVO0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570711238049337.8771293030544; Thu, 10 Oct 2019 05:40:38 -0700 (PDT) Received: from localhost ([::1]:37434 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIXk9-0005n6-4h for importer@patchew.org; Thu, 10 Oct 2019 08:40:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52260) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIWrg-0007JD-F0 for qemu-devel@nongnu.org; Thu, 10 Oct 2019 07:44:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIWre-0008R8-GR for qemu-devel@nongnu.org; Thu, 10 Oct 2019 07:44:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51248) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIWrX-0008OM-4W; Thu, 10 Oct 2019 07:44:10 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 65A4969089; Thu, 10 Oct 2019 11:44:06 +0000 (UTC) Received: from localhost (unknown [10.36.118.5]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D17875C223; Thu, 10 Oct 2019 11:44:05 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PULL 29/36] block/backup: move in-flight requests handling from backup to block-copy Date: Thu, 10 Oct 2019 13:42:53 +0200 Message-Id: <20191010114300.7746-30-mreitz@redhat.com> In-Reply-To: <20191010114300.7746-1-mreitz@redhat.com> References: <20191010114300.7746-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 10 Oct 2019 11:44:06 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Maydell , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Move synchronization mechanism to block-copy, to be able to use one block-copy instance from backup job and backup-top filter in parallel. Signed-off-by: Vladimir Sementsov-Ogievskiy Message-id: 20191001131409.14202-2-vsementsov@virtuozzo.com Reviewed-by: Max Reitz Signed-off-by: Max Reitz --- include/block/block-copy.h | 8 ++++++ block/backup.c | 52 -------------------------------------- block/block-copy.c | 43 +++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 52 deletions(-) diff --git a/include/block/block-copy.h b/include/block/block-copy.h index 54f90d0c9a..962f91056a 100644 --- a/include/block/block-copy.h +++ b/include/block/block-copy.h @@ -17,6 +17,13 @@ =20 #include "block/block.h" =20 +typedef struct BlockCopyInFlightReq { + int64_t start_byte; + int64_t end_byte; + QLIST_ENTRY(BlockCopyInFlightReq) list; + CoQueue wait_queue; /* coroutines blocked on this request */ +} BlockCopyInFlightReq; + typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque); typedef void (*ProgressResetCallbackFunc)(void *opaque); typedef struct BlockCopyState { @@ -27,6 +34,7 @@ typedef struct BlockCopyState { bool use_copy_range; int64_t copy_range_size; uint64_t len; + QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs; =20 BdrvRequestFlags write_flags; =20 diff --git a/block/backup.c b/block/backup.c index 4613b8c88d..d918836f1d 100644 --- a/block/backup.c +++ b/block/backup.c @@ -29,13 +29,6 @@ =20 #define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16) =20 -typedef struct CowRequest { - int64_t start_byte; - int64_t end_byte; - QLIST_ENTRY(CowRequest) list; - CoQueue wait_queue; /* coroutines blocked on this request */ -} CowRequest; - typedef struct BackupBlockJob { BlockJob common; BlockDriverState *source_bs; @@ -51,50 +44,12 @@ typedef struct BackupBlockJob { uint64_t bytes_read; int64_t cluster_size; NotifierWithReturn before_write; - QLIST_HEAD(, CowRequest) inflight_reqs; =20 BlockCopyState *bcs; } BackupBlockJob; =20 static const BlockJobDriver backup_job_driver; =20 -/* See if in-flight requests overlap and wait for them to complete */ -static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job, - int64_t start, - int64_t end) -{ - CowRequest *req; - bool retry; - - do { - retry =3D false; - QLIST_FOREACH(req, &job->inflight_reqs, list) { - if (end > req->start_byte && start < req->end_byte) { - qemu_co_queue_wait(&req->wait_queue, NULL); - retry =3D true; - break; - } - } - } while (retry); -} - -/* Keep track of an in-flight request */ -static void cow_request_begin(CowRequest *req, BackupBlockJob *job, - int64_t start, int64_t end) -{ - req->start_byte =3D start; - req->end_byte =3D end; - qemu_co_queue_init(&req->wait_queue); - QLIST_INSERT_HEAD(&job->inflight_reqs, req, list); -} - -/* Forget about a completed request */ -static void cow_request_end(CowRequest *req) -{ - QLIST_REMOVE(req, list); - qemu_co_queue_restart_all(&req->wait_queue); -} - static void backup_progress_bytes_callback(int64_t bytes, void *opaque) { BackupBlockJob *s =3D opaque; @@ -116,7 +71,6 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *jo= b, bool *error_is_read, bool is_write_notifier) { - CowRequest cow_request; int ret =3D 0; int64_t start, end; /* bytes */ =20 @@ -127,14 +81,9 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *j= ob, =20 trace_backup_do_cow_enter(job, start, offset, bytes); =20 - wait_for_overlapping_requests(job, start, end); - cow_request_begin(&cow_request, job, start, end); - ret =3D block_copy(job->bcs, start, end - start, error_is_read, is_write_notifier); =20 - cow_request_end(&cow_request); - trace_backup_do_cow_return(job, offset, bytes, ret); =20 qemu_co_rwlock_unlock(&job->flush_rwlock); @@ -316,7 +265,6 @@ static int coroutine_fn backup_run(Job *job, Error **er= rp) BackupBlockJob *s =3D container_of(job, BackupBlockJob, common.job); int ret =3D 0; =20 - QLIST_INIT(&s->inflight_reqs); qemu_co_rwlock_init(&s->flush_rwlock); =20 backup_init_copy_bitmap(s); diff --git a/block/block-copy.c b/block/block-copy.c index 3fc9152853..61e5ea5f46 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -19,6 +19,41 @@ #include "block/block-copy.h" #include "sysemu/block-backend.h" =20 +static void coroutine_fn block_copy_wait_inflight_reqs(BlockCopyState *s, + int64_t start, + int64_t end) +{ + BlockCopyInFlightReq *req; + bool waited; + + do { + waited =3D false; + QLIST_FOREACH(req, &s->inflight_reqs, list) { + if (end > req->start_byte && start < req->end_byte) { + qemu_co_queue_wait(&req->wait_queue, NULL); + waited =3D true; + break; + } + } + } while (waited); +} + +static void block_copy_inflight_req_begin(BlockCopyState *s, + BlockCopyInFlightReq *req, + int64_t start, int64_t end) +{ + req->start_byte =3D start; + req->end_byte =3D end; + qemu_co_queue_init(&req->wait_queue); + QLIST_INSERT_HEAD(&s->inflight_reqs, req, list); +} + +static void coroutine_fn block_copy_inflight_req_end(BlockCopyInFlightReq = *req) +{ + QLIST_REMOVE(req, list); + qemu_co_queue_restart_all(&req->wait_queue); +} + void block_copy_state_free(BlockCopyState *s) { if (!s) { @@ -79,6 +114,8 @@ BlockCopyState *block_copy_state_new( s->use_copy_range =3D !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size >= 0; =20 + QLIST_INIT(&s->inflight_reqs); + /* * We just allow aio context change on our block backends. block_copy(= ) user * (now it's only backup) is responsible for source and target being i= n same @@ -266,6 +303,7 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t end =3D bytes + start; /* bytes */ void *bounce_buffer =3D NULL; int64_t status_bytes; + BlockCopyInFlightReq req; =20 /* * block_copy() user is responsible for keeping source and target in s= ame @@ -276,6 +314,9 @@ int coroutine_fn block_copy(BlockCopyState *s, assert(QEMU_IS_ALIGNED(start, s->cluster_size)); assert(QEMU_IS_ALIGNED(end, s->cluster_size)); =20 + block_copy_wait_inflight_reqs(s, start, bytes); + block_copy_inflight_req_begin(s, &req, start, end); + while (start < end) { int64_t dirty_end; =20 @@ -329,5 +370,7 @@ int coroutine_fn block_copy(BlockCopyState *s, qemu_vfree(bounce_buffer); } =20 + block_copy_inflight_req_end(&req); + return ret; } --=20 2.21.0