From nobody Wed Feb 11 05:36:49 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=oracle.com ARC-Seal: i=1; a=rsa-sha256; t=1687470642; cv=none; d=zohomail.com; s=zohoarc; b=WzDKscv9j26wyfWHPZE01z7I3d8kY1W8jQFKxKUk4OdfFqKb3W0TQbnH1+Ji+s2Mszjq+iuTRGdiYGVwp4UHuV/gOO+I59tOnPyRFNfTXbod4BEUM3JWrQdP/o+waoZrESxWD3PG7ByW9sEPqBLBWAYIrEcdfCBAzZYwyulVs+8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1687470642; 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=9kNKx6R9jFh+8uU24jkKwYU0650934+xnHSDNWrDuoo=; b=An2BWaQhZcOq6MvoQPTcQpIMhjKwdHIDSRVLODyj7KbJL0Jt2Am/byvqDHGpK1Z3aNA61+sUd+8tXNi8U6yyy0ifJoSrnwwK9pihkkh/lU98PfUrL22GecHnEmtMeFU0T/+BUNbddECRHsfh6VBr0j2PnGO9R9keMKkoBAZUH3k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 1687470642578217.51099973333498; Thu, 22 Jun 2023 14:50:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qCSC9-00041w-U2; Thu, 22 Jun 2023 17:50:25 -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 1qCSC7-0003xk-Ul for qemu-devel@nongnu.org; Thu, 22 Jun 2023 17:50:23 -0400 Received: from mx0b-00069f02.pphosted.com ([205.220.177.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qCSC5-0007v2-RH for qemu-devel@nongnu.org; Thu, 22 Jun 2023 17:50:23 -0400 Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 35MJo4a3021548; Thu, 22 Jun 2023 21:50:19 GMT Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.appoci.oracle.com [138.1.37.129]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3r93m3txvb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 22 Jun 2023 21:50:19 +0000 Received: from pps.filterd (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 35ML7Sfn008390; Thu, 22 Jun 2023 21:50:18 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3r9398eq96-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 22 Jun 2023 21:50:18 +0000 Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 35MLn77G035791; Thu, 22 Jun 2023 21:50:17 GMT Received: from joaomart-mac.uk.oracle.com (dhcp-10-175-180-251.vpn.oracle.com [10.175.180.251]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 3r9398ep1g-15; Thu, 22 Jun 2023 21:50:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=9kNKx6R9jFh+8uU24jkKwYU0650934+xnHSDNWrDuoo=; b=AdcwoVpDKBcSZMHOY1xne0xmfTsvVUpA8zHs4neSatlVAQQWZgL8jYbkSBE8lORBxlQh xV3763TBzKJM+08K6hHMd0d5c1FUooHo7I520ACb2Ie3pWVLE0fAvhF1Nsxk9kEk0GF9 J8yIq8QqeZRfXXVBvfp3X4pn85GOn9llPmsNBPfBjIeJzSgeW5IRHMwqLfKUY1Qgdnj7 79ztAm1R26bUY9YFY7Pwsssw1DFu1wfo7x7vuvzmkc1G4iBVMUAZXxqRjU9IqIdm4xpd vtyO65VZe58SJPGMjrLEnHSJzgM/Th8PISVGsIi5iGw7Opp0s327UJrqitPdJ75k89sI HA== From: Joao Martins To: qemu-devel@nongnu.org Cc: Alex Williamson , Cedric Le Goater , Paolo Bonzini , Peter Xu , David Hildenbrand , Philippe Mathieu-Daude , "Michael S. Tsirkin" , Marcel Apfelbaum , Jason Wang , Richard Henderson , Eduardo Habkost , Avihai Horon , Jason Gunthorpe , Joao Martins Subject: [PATCH v4 14/15] vfio/common: Optimize device dirty page tracking with vIOMMU Date: Thu, 22 Jun 2023 22:48:44 +0100 Message-Id: <20230622214845.3980-15-joao.m.martins@oracle.com> In-Reply-To: <20230622214845.3980-1-joao.m.martins@oracle.com> References: <20230622214845.3980-1-joao.m.martins@oracle.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-06-22_16,2023-06-22_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=781 adultscore=0 spamscore=0 phishscore=0 suspectscore=0 malwarescore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2306220186 X-Proofpoint-GUID: sK5VgQ-L1MaNJgeE2Z4X21Yt6rgcyDcP X-Proofpoint-ORIG-GUID: sK5VgQ-L1MaNJgeE2Z4X21Yt6rgcyDcP 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=205.220.177.32; envelope-from=joao.m.martins@oracle.com; helo=mx0b-00069f02.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @oracle.com) X-ZM-MESSAGEID: 1687470644291100003 Content-Type: text/plain; charset="utf-8" From: Avihai Horon When vIOMMU is enabled, syncing dirty page bitmaps is done by replaying the vIOMMU mappings and querying the dirty bitmap for each mapping. With device dirty tracking this causes a lot of overhead, since the HW is queried many times (even with small idle guest this can end up with thousands of calls to HW). Optimize this by de-coupling dirty bitmap query from vIOMMU replay. Now a single dirty bitmap is queried per vIOMMU MR section, which is then used for all corresponding vIOMMU mappings within that MR section. Signed-off-by: Avihai Horon Signed-off-by: Joao Martins --- hw/vfio/common.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index c530e9d87f21..62f91e8e102d 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1832,8 +1832,36 @@ out: typedef struct { IOMMUNotifier n; VFIOGuestIOMMU *giommu; + VFIOBitmap vbmap; } vfio_giommu_dirty_notifier; =20 +static int vfio_iommu_set_dirty_bitmap(VFIOContainer *container, + vfio_giommu_dirty_notifier *gdn, + hwaddr iova, hwaddr size, + ram_addr_t ram_addr) +{ + VFIOBitmap *vbmap =3D &gdn->vbmap; + VFIOBitmap dst_vbmap; + hwaddr start_iova =3D REAL_HOST_PAGE_ALIGN(gdn->n.start); + hwaddr copy_offset; + int ret; + + ret =3D vfio_bitmap_alloc(&dst_vbmap, size); + if (ret) { + return -ENOMEM; + } + + copy_offset =3D (iova - start_iova) / qemu_real_host_page_size(); + bitmap_copy_with_src_offset(dst_vbmap.bitmap, vbmap->bitmap, copy_offs= et, + dst_vbmap.pages); + + cpu_physical_memory_set_dirty_lebitmap(dst_vbmap.bitmap, ram_addr, + dst_vbmap.pages); + g_free(dst_vbmap.bitmap); + + return 0; +} + static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *i= otlb) { vfio_giommu_dirty_notifier *gdn =3D container_of(n, @@ -1854,8 +1882,15 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifie= r *n, IOMMUTLBEntry *iotlb) =20 rcu_read_lock(); if (vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) { - ret =3D vfio_get_dirty_bitmap(container, iova, iotlb->addr_mask + = 1, - translated_addr); + if (gdn->vbmap.bitmap) { + ret =3D vfio_iommu_set_dirty_bitmap(container, gdn, iova, + iotlb->addr_mask + 1, + translated_addr); + } else { + ret =3D vfio_get_dirty_bitmap(container, iova, iotlb->addr_mas= k + 1, + translated_addr); + } + if (ret) { error_report("vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx"= , " "0x%"HWADDR_PRIx") =3D %d (%s)", @@ -1936,6 +1971,7 @@ static int vfio_sync_iommu_dirty_bitmap(VFIOContainer= *container, } =20 gdn.giommu =3D giommu; + gdn.vbmap.bitmap =3D NULL; idx =3D memory_region_iommu_attrs_to_index(giommu->iommu_mr, MEMTXATTRS_UNSPECIFIED); =20 @@ -1943,10 +1979,44 @@ static int vfio_sync_iommu_dirty_bitmap(VFIOContain= er *container, section->size); llend =3D int128_sub(llend, int128_one()); =20 + /* + * Optimize device dirty tracking if the MR section is at least partia= lly + * tracked. Optimization is done by querying a single dirty bitmap for= the + * entire range instead of querying dirty bitmap for each vIOMMU mappi= ng. + */ + if (vfio_devices_all_device_dirty_tracking(container)) { + hwaddr start =3D REAL_HOST_PAGE_ALIGN(section->offset_within_regio= n); + hwaddr end =3D int128_get64(llend); + hwaddr iommu_max_iova; + hwaddr size; + int ret; + + ret =3D vfio_viommu_get_max_iova(&iommu_max_iova); + if (ret) { + return -EINVAL; + } + + size =3D REAL_HOST_PAGE_ALIGN(MIN(iommu_max_iova, end) - start); + + ret =3D vfio_bitmap_alloc(&gdn.vbmap, size); + if (ret) { + return -ENOMEM; + } + + ret =3D vfio_devices_query_dirty_bitmap(container, &gdn.vbmap, + start, size); + if (ret) { + g_free(gdn.vbmap.bitmap); + + return ret; + } + } + iommu_notifier_init(&gdn.n, vfio_iommu_map_dirty_notify, IOMMU_NOTIFIE= R_MAP, section->offset_within_region, int128_get64(llend), idx); memory_region_iommu_replay(giommu->iommu_mr, &gdn.n); + g_free(gdn.vbmap.bitmap); =20 return 0; } --=20 2.17.2