[PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking

Zhenzhong Duan posted 23 patches 3 months, 2 weeks ago
There is a newer version of this series
[PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking
Posted by Zhenzhong Duan 3 months, 2 weeks ago
When doing ditry tracking or calculating dirty tracking range, readonly
regions can be bypassed, because corresponding DMA mappings are readonly
and never become dirty.

This can optimize dirty tracking a bit for passthrough device.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
 hw/vfio/listener.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
index 0862b2b834..cbd86c79af 100644
--- a/hw/vfio/listener.c
+++ b/hw/vfio/listener.c
@@ -828,7 +828,8 @@ static void vfio_dirty_tracking_update(MemoryListener *listener,
         container_of(listener, VFIODirtyRangesListener, listener);
     hwaddr iova, end;
 
-    if (!vfio_listener_valid_section(section, false, "tracking_update") ||
+    /* Bypass readonly section as it never become dirty */
+    if (!vfio_listener_valid_section(section, true, "tracking_update") ||
         !vfio_get_section_iova_range(dirty->bcontainer, section,
                                      &iova, &end, NULL)) {
         return;
@@ -1087,6 +1088,12 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
     if (!mr) {
         goto out_unlock;
     }
+
+    if (!(iotlb->perm & IOMMU_WO) || mr->readonly) {
+        rcu_read_unlock();
+        return;
+    }
+
     translated_addr = memory_region_get_ram_addr(mr) + xlat;
 
     ret = vfio_container_query_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1,
@@ -1222,7 +1229,7 @@ static void vfio_listener_log_sync(MemoryListener *listener,
     int ret;
     Error *local_err = NULL;
 
-    if (vfio_listener_skipped_section(section, false)) {
+    if (vfio_listener_skipped_section(section, true)) {
         return;
     }
 
-- 
2.47.1
Re: [PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking
Posted by Eric Auger 3 months, 1 week ago

On 10/24/25 10:43 AM, Zhenzhong Duan wrote:
> When doing ditry tracking or calculating dirty tracking range, readonly
dirty tracking or when ...
> regions can be bypassed, because corresponding DMA mappings are readonly
> and never become dirty.
>
> This can optimize dirty tracking a bit for passthrough device.
>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
>  hw/vfio/listener.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
> index 0862b2b834..cbd86c79af 100644
> --- a/hw/vfio/listener.c
> +++ b/hw/vfio/listener.c
> @@ -828,7 +828,8 @@ static void vfio_dirty_tracking_update(MemoryListener *listener,
>          container_of(listener, VFIODirtyRangesListener, listener);
>      hwaddr iova, end;
>  
> -    if (!vfio_listener_valid_section(section, false, "tracking_update") ||
> +    /* Bypass readonly section as it never become dirty */
> +    if (!vfio_listener_valid_section(section, true, "tracking_update") ||
>          !vfio_get_section_iova_range(dirty->bcontainer, section,
>                                       &iova, &end, NULL)) {
>          return;
> @@ -1087,6 +1088,12 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
>      if (!mr) {
>          goto out_unlock;
>      }
> +
> +    if (!(iotlb->perm & IOMMU_WO) || mr->readonly) {
> +        rcu_read_unlock();
> +        return;
This change is less obvsious compared to the others. Might be worth
explaining why you add it.
> +    }
> +
>      translated_addr = memory_region_get_ram_addr(mr) + xlat;
>  
>      ret = vfio_container_query_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1,
> @@ -1222,7 +1229,7 @@ static void vfio_listener_log_sync(MemoryListener *listener,
>      int ret;
>      Error *local_err = NULL;
>  
> -    if (vfio_listener_skipped_section(section, false)) {
> +    if (vfio_listener_skipped_section(section, true)) {
the false -> true change might be squashed into the 18/23 patch while
explainig why you set this value.

Eric
>          return;
>      }
>
Re: [PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking
Posted by Cédric Le Goater 3 months, 2 weeks ago
On 10/24/25 10:43, Zhenzhong Duan wrote:
> When doing ditry tracking or calculating dirty tracking range, readonly
> regions can be bypassed, because corresponding DMA mappings are readonly
> and never become dirty.
> 
> This can optimize dirty tracking a bit for passthrough device.
> 
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
>   hw/vfio/listener.c | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
> index 0862b2b834..cbd86c79af 100644
> --- a/hw/vfio/listener.c
> +++ b/hw/vfio/listener.c
> @@ -828,7 +828,8 @@ static void vfio_dirty_tracking_update(MemoryListener *listener,
>           container_of(listener, VFIODirtyRangesListener, listener);
>       hwaddr iova, end;
>   
> -    if (!vfio_listener_valid_section(section, false, "tracking_update") ||
> +    /* Bypass readonly section as it never become dirty */
> +    if (!vfio_listener_valid_section(section, true, "tracking_update") ||
>           !vfio_get_section_iova_range(dirty->bcontainer, section,
>                                        &iova, &end, NULL)) {
>           return;
> @@ -1087,6 +1088,12 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
>       if (!mr) {
>           goto out_unlock;
>       }
> +
> +    if (!(iotlb->perm & IOMMU_WO) || mr->readonly) {


In case you resend, please add a trace event.

Anyhow,

Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> +        rcu_read_unlock();
> +        return;
> +    }
> +
>       translated_addr = memory_region_get_ram_addr(mr) + xlat;
>   
>       ret = vfio_container_query_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1,
> @@ -1222,7 +1229,7 @@ static void vfio_listener_log_sync(MemoryListener *listener,
>       int ret;
>       Error *local_err = NULL;
>   
> -    if (vfio_listener_skipped_section(section, false)) {
> +    if (vfio_listener_skipped_section(section, true)) {
>           return;
>       }
>   


RE: [PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking
Posted by Duan, Zhenzhong 3 months, 2 weeks ago

>-----Original Message-----
>From: Cédric Le Goater <clg@redhat.com>
>Subject: Re: [PATCH v7 20/23] vfio: Bypass readonly region for dirty tracking
>
>On 10/24/25 10:43, Zhenzhong Duan wrote:
>> When doing ditry tracking or calculating dirty tracking range, readonly
>> regions can be bypassed, because corresponding DMA mappings are
>readonly
>> and never become dirty.
>>
>> This can optimize dirty tracking a bit for passthrough device.
>>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> ---
>>   hw/vfio/listener.c | 11 +++++++++--
>>   1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
>> index 0862b2b834..cbd86c79af 100644
>> --- a/hw/vfio/listener.c
>> +++ b/hw/vfio/listener.c
>> @@ -828,7 +828,8 @@ static void
>vfio_dirty_tracking_update(MemoryListener *listener,
>>           container_of(listener, VFIODirtyRangesListener, listener);
>>       hwaddr iova, end;
>>
>> -    if (!vfio_listener_valid_section(section, false, "tracking_update") ||
>> +    /* Bypass readonly section as it never become dirty */
>> +    if (!vfio_listener_valid_section(section, true, "tracking_update") ||
>>           !vfio_get_section_iova_range(dirty->bcontainer, section,
>>                                        &iova, &end, NULL)) {
>>           return;
>> @@ -1087,6 +1088,12 @@ static void
>vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
>>       if (!mr) {
>>           goto out_unlock;
>>       }
>> +
>> +    if (!(iotlb->perm & IOMMU_WO) || mr->readonly) {
>
>
>In case you resend, please add a trace event.

OK, will add:

  trace_vfio_iommu_map_dirty_notify_skip_ro(iova, iova + iotlb->addr_mask);

Thanks
Zhenzhong

>
>Anyhow,
>
>Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
>Thanks,
>
>C.
>
>
>> +        rcu_read_unlock();
>> +        return;
>> +    }
>> +
>>       translated_addr = memory_region_get_ram_addr(mr) + xlat;
>>
>>       ret = vfio_container_query_dirty_bitmap(bcontainer, iova,
>iotlb->addr_mask + 1,
>> @@ -1222,7 +1229,7 @@ static void
>vfio_listener_log_sync(MemoryListener *listener,
>>       int ret;
>>       Error *local_err = NULL;
>>
>> -    if (vfio_listener_skipped_section(section, false)) {
>> +    if (vfio_listener_skipped_section(section, true)) {
>>           return;
>>       }
>>