From nobody Fri Nov 14 18:23:30 2025 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; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1761223021; cv=none; d=zohomail.com; s=zohoarc; b=YNBrBIQCkfnjlAZrEI9qiOtsC8VzUkbLpQzLM3ObKrKpaj0BKEpFc6/8YxQ400WmG4wqhsXeuOl6UYqyfzui5EYXurWJijWUo1xDgFnrDALnw5nmmYfutEMcF14SxszH4ShFEzLxcMjh2CrGPNCngIEQ1+DuTcFoRPQE4garOvE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1761223021; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=bwiPu58xtsujEHlJ/GWin93BUEQYUnUkKLKcbJwKIhg=; b=kMn6uYiCRoMDPw6SKk/ZGSzTafKG4DUI4RkksRiRWNE9LMFfd6qPX3BgeWomzAUv4tDJDIv279jdkmHPN23UBrc3CI3WAvU5VxPsFsKLqSfnHglCrmcSfoRs3fK1BVuGZLYgT6Vtqn6y1HeihkFlduHm0R74mhoxXsD5sWQ43a8= 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1761223021502243.35296495916748; Thu, 23 Oct 2025 05:37:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vBuTH-00038v-HZ; Thu, 23 Oct 2025 08:31:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vBuJN-00044U-U7; Thu, 23 Oct 2025 08:20:59 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vBuJJ-0006tc-RA; Thu, 23 Oct 2025 08:20:57 -0400 Received: from mail.maildlp.com (unknown [172.19.88.234]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4cslX617sXz11WtH; Thu, 23 Oct 2025 20:21:58 +0800 (CST) Received: from kwepemj100010.china.huawei.com (unknown [7.202.194.4]) by mail.maildlp.com (Postfix) with ESMTPS id E12851401E9; Thu, 23 Oct 2025 20:20:41 +0800 (CST) Received: from huawei.com (10.246.99.10) by kwepemj100010.china.huawei.com (7.202.194.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 23 Oct 2025 20:20:39 +0800 To: CC: , , , , , , , , , , , Subject: [RFC 1/2] block/qcow2-cache: Introduce qcow2_write_l2_entry() Date: Thu, 23 Oct 2025 20:24:56 +0800 Message-ID: <20251023122457.2610426-2-zhangjiaji1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20251023122457.2610426-1-zhangjiaji1@huawei.com> References: <20251023122457.2610426-1-zhangjiaji1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.246.99.10] X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To kwepemj100010.china.huawei.com (7.202.194.4) 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.32; envelope-from=zhangjiaji1@huawei.com; helo=szxga06-in.huawei.com 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_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Thu, 23 Oct 2025 08:24:37 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: zhangjiaji From: zhangjiaji via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1761223024184154100 Content-Type: text/plain; charset="utf-8" From: Zhu Yangyang This function will be used in the next optimization patch to flush only the actually changed portion of the qcow2 L2 Table cache, instead of flushing the entire L2 Table cache. Signed-off-by: Zhu Yangyang --- block/qcow2-cache.c | 33 ++++++++++++++++++++++++++++++--- block/qcow2.h | 2 ++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 23d9588b08..b5378d003d 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -180,7 +180,8 @@ qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow= 2Cache *c) } =20 static int GRAPH_RDLOCK -qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) +qcow2_cache_entry_flush_part(BlockDriverState *bs, Qcow2Cache *c, int i, + int l2_index, int nb_clusters) { BDRVQcow2State *s =3D bs->opaque; int ret =3D 0; @@ -226,8 +227,21 @@ qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cac= he *c, int i) BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); } =20 - ret =3D bdrv_pwrite(bs->file, c->entries[i].offset, c->table_size, - qcow2_cache_get_table_addr(c, i), 0); + if (l2_index < 0) { + ret =3D bdrv_pwrite(bs->file, c->entries[i].offset, c->table_size, + qcow2_cache_get_table_addr(c, i), 0); + } else { + /* Only flush the actual dirty portions. */ + int64_t l2_offset =3D l2_index * l2_entry_size(s); + int64_t l2_bytes =3D nb_clusters * l2_entry_size(s); + + int64_t aligned_offset =3D QEMU_ALIGN_DOWN(l2_offset, BDRV_SECTOR_= SIZE); + int64_t aligned_end =3D QEMU_ALIGN_UP(l2_offset + l2_bytes, BDRV_S= ECTOR_SIZE); + ret =3D bdrv_pwrite(bs->file, c->entries[i].offset + aligned_offse= t, + aligned_end - aligned_offset, + qcow2_cache_get_table_addr(c, i) + aligned_offse= t, 0); + } + if (ret < 0) { return ret; } @@ -237,6 +251,19 @@ qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cac= he *c, int i) return 0; } =20 +static int GRAPH_RDLOCK +qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) +{ + return qcow2_cache_entry_flush_part(bs, c, i, -1, 0); +} + +int qcow2_write_l2_entry(BlockDriverState *bs, Qcow2Cache *c, void *l2_tab= el, + int l2_index, int nb_clusters) +{ + int l2 =3D qcow2_cache_get_table_idx(c, l2_tabel); + return qcow2_cache_entry_flush_part(bs, c, l2, l2_index, nb_clusters); +} + int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c) { BDRVQcow2State *s =3D bs->opaque; diff --git a/block/qcow2.h b/block/qcow2.h index a9e3481c6e..b0ba2e1996 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -1001,6 +1001,8 @@ qcow2_cache_create(BlockDriverState *bs, int num_tabl= es, unsigned table_size); int qcow2_cache_destroy(Qcow2Cache *c); =20 void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table); +int qcow2_write_l2_entry(BlockDriverState *bs, Qcow2Cache *c, void *l2_tab= el, + int l2_index, int nb_clusters) int GRAPH_RDLOCK qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); int GRAPH_RDLOCK qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c); int GRAPH_RDLOCK qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cac= he *c, --=20 2.33.0 From nobody Fri Nov 14 18:23:30 2025 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; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1761222943; cv=none; d=zohomail.com; s=zohoarc; b=KrUH5WIh6ZbiGsqhJdBtuXblVCyaQRE2twEI99d/HcdtbpTPzHYiEtD6py0WD6sAZP1YNwiAMtOhi5nv/j/cgaas5jwzsIKYKQLRzTTegbc/6tV7hiL9OA1Kj8pCU6WdwNLGOvGztbu3YIYsxKMto5305OZU/c0aqrhH9f9rRBc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1761222943; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=8KFav78A+u6eclVuJhD5QrDbyWwnbTNJuK+QjxifXPY=; b=G4Ma5uUmqNsh8oGEZ1zi5IHdH2JOJllvUVNbKSRd1gc8H7lvAteDiTcsArvbN6JWpcnrC3Xv6c02Ye82of64BFM+13+DOfnPMw49Y/LuxI6VvcgYwTDrCjc/fNFRFmOkSVtdqS0sogKxqUyAb4myePbUUzz+zYRjqd+s0V9nVyY= 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1761222943052546.6539117906069; Thu, 23 Oct 2025 05:35:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vBuVH-00075o-Mc; Thu, 23 Oct 2025 08:33:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vBuJP-00047A-Qs; Thu, 23 Oct 2025 08:21:03 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vBuJK-0006tf-FQ; Thu, 23 Oct 2025 08:20:58 -0400 Received: from mail.maildlp.com (unknown [172.19.88.214]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4cslPq41PCz24jKn; Thu, 23 Oct 2025 20:16:31 +0800 (CST) Received: from kwepemj100010.china.huawei.com (unknown [7.202.194.4]) by mail.maildlp.com (Postfix) with ESMTPS id A47911A016C; Thu, 23 Oct 2025 20:20:42 +0800 (CST) Received: from huawei.com (10.246.99.10) by kwepemj100010.china.huawei.com (7.202.194.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 23 Oct 2025 20:20:41 +0800 To: CC: , , , , , , , , , , , Subject: [RFC 2/2] block/qcow2: Improve I/O performance in write-through cache mode for qcow2 driver Date: Thu, 23 Oct 2025 20:24:57 +0800 Message-ID: <20251023122457.2610426-3-zhangjiaji1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20251023122457.2610426-1-zhangjiaji1@huawei.com> References: <20251023122457.2610426-1-zhangjiaji1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.246.99.10] X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To kwepemj100010.china.huawei.com (7.202.194.4) 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.191; envelope-from=zhangjiaji1@huawei.com; helo=szxga05-in.huawei.com 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_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Thu, 23 Oct 2025 08:24:36 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: zhangjiaji From: zhangjiaji via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1761222948345158500 Content-Type: text/plain; charset="utf-8" From: Zhu Yangyang Optimize IO performance in writethrough cache mode by immediately performing write cache after updating the L2 entry and only flushing the portions that have actually changed. Signed-off-by: Zhu Yangyang --- block/qcow2-cache.c | 7 +++++++ block/qcow2-cluster.c | 15 +++++++++++++++ block/qcow2.h | 3 ++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index b5378d003d..3491cea7fb 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -463,6 +463,13 @@ void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void = *table) c->entries[i].dirty =3D true; } =20 +bool qcow2_cache_is_dirty(Qcow2Cache *c, void *table) +{ + int i =3D qcow2_cache_get_table_idx(c, table); + assert(c->entries[i].offset !=3D 0); + return c->entries[i].dirty; +} + void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset) { int i; diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index ce8c0076b3..95b0e44c6e 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1032,6 +1032,10 @@ int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDr= iverState *bs, int i, j =3D 0, l2_index, ret; uint64_t *old_cluster, *l2_slice; uint64_t cluster_offset =3D m->alloc_offset; + bool part_flush =3D false; + /* I haven't figured out yet how to perceive this IO + * as a writethrough cache mode. */ + bool writethrough =3D true; =20 trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters); assert(m->nb_clusters > 0); @@ -1061,6 +1065,13 @@ int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDr= iverState *bs, if (ret < 0) { goto err; } + + /* If the cache is clean before qcow2_cache_entry_mark_dirty(), + * we can flush only the modified L2 entries.. + */ + if (writethrough && !qcow2_cache_is_dirty(s->l2_table_cache, l2_slice)= ) { + part_flush =3D true; + } qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice); =20 assert(l2_index + m->nb_clusters <=3D s->l2_slice_size); @@ -1102,6 +1113,10 @@ int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDr= iverState *bs, } =20 =20 + if (part_flush) { + qcow2_write_l2_entry(bs, s->l2_table_cache, l2_slice, l2_index, + m->nb_clusters); + } qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); =20 /* diff --git a/block/qcow2.h b/block/qcow2.h index b0ba2e1996..8fb59c4e87 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -1000,9 +1000,10 @@ qcow2_cache_create(BlockDriverState *bs, int num_tab= les, unsigned table_size); =20 int qcow2_cache_destroy(Qcow2Cache *c); =20 +bool qcow2_cache_is_dirty(Qcow2Cache *c, void *table); void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table); int qcow2_write_l2_entry(BlockDriverState *bs, Qcow2Cache *c, void *l2_tab= el, - int l2_index, int nb_clusters) + int l2_index, int nb_clusters); int GRAPH_RDLOCK qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); int GRAPH_RDLOCK qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c); int GRAPH_RDLOCK qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cac= he *c, --=20 2.33.0