From nobody Tue Feb 10 15:46:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1601459453; cv=none; d=zohomail.com; s=zohoarc; b=GdDDGnlxqv5n5bhEzh9Oo5Ab9UPpEgdFBOjd5FJi+wDF3/0OSVPvlMthWMzTT2IpZI3FLZLKupM22gxwcOdMrr6mKwtoJb4yMbpPG4A3rzgCE+7/EZavK31GTUJOUkC8jFimZLs3eZFod9VHCNeWuiqOFBndtrAJCKB2hLGxnNE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1601459453; h=Content-Type: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=ambUA32mLgYlxjStX/82PBVoRsYtGN5PuYuPMpPavsc=; b=B5DGyITQBjau7m+0k/x5cROegwkeEnHiEY3O6QOrimfnqvPv3R2vsZlGz/mCgmj93+Zt5UO+C/6fGOM5Cev4dOjXVA0Ogs/dAZns/BV/svHyT1/OYdeNPKPE9kQRbpweBTmVbba553mT2XoqnXCASrUfzVliJPryGTYEXq2n0js= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1601459453138986.7728106978286; Wed, 30 Sep 2020 02:50:53 -0700 (PDT) Received: from localhost ([::1]:55460 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kNYl9-0002K5-Q8 for importer@patchew.org; Wed, 30 Sep 2020 05:50:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37532) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kNYhQ-00072p-M1 for qemu-devel@nongnu.org; Wed, 30 Sep 2020 05:47:01 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:5155 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kNYhM-0003oH-Tl for qemu-devel@nongnu.org; Wed, 30 Sep 2020 05:47:00 -0400 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id A8B59516CA08BE7B74C5; Wed, 30 Sep 2020 17:46:52 +0800 (CST) Received: from localhost (10.174.186.107) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.487.0; Wed, 30 Sep 2020 17:46:42 +0800 From: Jiahui Cen To: Subject: [RFC PATCH v2 2/8] block-backend: rehandle block aios when EIO Date: Wed, 30 Sep 2020 17:46:00 +0800 Message-ID: <20200930094606.5323-3-cenjiahui@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200930094606.5323-1-cenjiahui@huawei.com> References: <20200930094606.5323-1-cenjiahui@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.174.186.107] X-CFilter-Loop: Reflected Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=45.249.212.190; envelope-from=cenjiahui@huawei.com; helo=huawei.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/30 05:46:53 X-ACL-Warn: Detected OS = Linux 3.11 and newer [fuzzy] X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: kwolf@redhat.com, fangying1@huawei.com, cenjiahui@huawei.com, zhang.zhanghailiang@huawei.com, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" When a backend device temporarily does not response, like a network disk do= wn due to some network faults, any IO to the coresponding virtual block device in VM would return I/O error. If the hypervisor returns the error to VM, the filesystem on this block device may not work as usual. And in many situatio= ns, the returned error is often an EIO. To avoid this unavailablity, we can store the failed AIOs, and resend them later. If the error is temporary, the retries can succeed and the AIOs can be successfully completed. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang --- block/block-backend.c | 89 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/block/block-backend.c b/block/block-backend.c index b8367d82cc..8050669d23 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -365,6 +365,12 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, = uint64_t shared_perm) notifier_list_init(&blk->remove_bs_notifiers); notifier_list_init(&blk->insert_bs_notifiers); =20 + /* for rehandle */ + blk->reinfo.enable =3D false; + blk->reinfo.ts =3D NULL; + qatomic_set(&blk->reinfo.in_flight, 0); + QTAILQ_INIT(&blk->reinfo.re_aios); + QLIST_INIT(&blk->aio_notifiers); =20 QTAILQ_INSERT_TAIL(&block_backends, blk, link); @@ -1425,8 +1431,16 @@ static const AIOCBInfo blk_aio_em_aiocb_info =3D { .get_aio_context =3D blk_aio_em_aiocb_get_aio_context, }; =20 +static void blk_rehandle_timer_cb(void *opaque); +static void blk_rehandle_aio_complete(BlkAioEmAIOCB *acb); + static void blk_aio_complete(BlkAioEmAIOCB *acb) { + if (acb->rwco.blk->reinfo.enable) { + blk_rehandle_aio_complete(acb); + return; + } + if (acb->has_returned) { acb->common.cb(acb->common.opaque, acb->rwco.ret); blk_dec_in_flight(acb->rwco.blk); @@ -1459,6 +1473,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, in= t64_t offset, int bytes, .ret =3D NOT_DONE, }; acb->bytes =3D bytes; + acb->co_entry =3D co_entry; acb->has_returned =3D false; =20 co =3D qemu_coroutine_create(co_entry, acb); @@ -2054,6 +2069,20 @@ static int blk_do_set_aio_context(BlockBackend *blk,= AioContext *new_context, throttle_group_attach_aio_context(tgm, new_context); bdrv_drained_end(bs); } + + if (blk->reinfo.enable) { + if (blk->reinfo.ts) { + timer_del(blk->reinfo.ts); + timer_free(blk->reinfo.ts); + } + blk->reinfo.ts =3D aio_timer_new(new_context, QEMU_CLOCK_REALT= IME, + SCALE_MS, blk_rehandle_timer_cb, + blk); + if (qatomic_read(&blk->reinfo.in_flight)) { + timer_mod(blk->reinfo.ts, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME)); + } + } } =20 blk->ctx =3D new_context; @@ -2406,6 +2435,66 @@ static void blk_root_drained_end(BdrvChild *child, i= nt *drained_end_counter) } } =20 +static void blk_rehandle_insert_aiocb(BlockBackend *blk, BlkAioEmAIOCB *ac= b) +{ + assert(blk->reinfo.enable); + + qatomic_inc(&blk->reinfo.in_flight); + QTAILQ_INSERT_TAIL(&blk->reinfo.re_aios, acb, list); + timer_mod(blk->reinfo.ts, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + + blk->reinfo.timer_interval_ms); +} + +static void blk_rehandle_remove_aiocb(BlockBackend *blk, BlkAioEmAIOCB *ac= b) +{ + QTAILQ_REMOVE(&blk->reinfo.re_aios, acb, list); + qatomic_dec(&blk->reinfo.in_flight); +} + +static void blk_rehandle_timer_cb(void *opaque) +{ + BlockBackend *blk =3D opaque; + BlockBackendRehandleInfo *reinfo =3D &blk->reinfo; + BlkAioEmAIOCB *acb, *tmp; + Coroutine *co; + + aio_context_acquire(blk_get_aio_context(blk)); + QTAILQ_FOREACH_SAFE(acb, &reinfo->re_aios, list, tmp) { + if (acb->rwco.ret =3D=3D NOT_DONE) { + continue; + } + + blk_inc_in_flight(acb->rwco.blk); + acb->rwco.ret =3D NOT_DONE; + acb->has_returned =3D false; + blk_rehandle_remove_aiocb(acb->rwco.blk, acb); + + co =3D qemu_coroutine_create(acb->co_entry, acb); + qemu_coroutine_enter(co); + + acb->has_returned =3D true; + if (acb->rwco.ret !=3D NOT_DONE) { + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), + blk_aio_complete_bh, acb); + } + } + aio_context_release(blk_get_aio_context(blk)); +} + +static void blk_rehandle_aio_complete(BlkAioEmAIOCB *acb) +{ + if (acb->has_returned) { + blk_dec_in_flight(acb->rwco.blk); + if (acb->rwco.ret =3D=3D -EIO) { + blk_rehandle_insert_aiocb(acb->rwco.blk, acb); + return; + } + + acb->common.cb(acb->common.opaque, acb->rwco.ret); + qemu_aio_unref(acb); + } +} + void blk_register_buf(BlockBackend *blk, void *host, size_t size) { bdrv_register_buf(blk_bs(blk), host, size); --=20 2.28.0