Re: [PATCH RFC 09/10] migration/dirtyrate: Expand dirty_bitmap to be tracked separately for devices

2022-05-02 Thread Joao Martins
On 5/2/22 13:54, Markus Armbruster wrote:
> Joao Martins  writes:
> 
>> Expand dirtyrate measurer that is accessible via HMP calc_dirty_rate
>> or QMP 'calc-dirty-rate' to receive a @scope argument. The scope
>> then restricts the dirty tracking to be done at devices only,
>> while neither enabling or using the KVM (CPU) dirty tracker.
>> The default stays as is i.e. dirty-ring / dirty-bitmap from KVM.
>>
>> This is useful to test, exercise the IOMMU dirty tracker and observe
>> how much a given device is dirtying memory.
>>
>> Signed-off-by: Joao Martins 
> 
> [...]
> 
>> diff --git a/qapi/migration.json b/qapi/migration.json
>> index 27d7b281581d..082830c6e771 100644
>> --- a/qapi/migration.json
>> +++ b/qapi/migration.json
>> @@ -1793,6 +1793,19 @@
>>  { 'enum': 'DirtyRateMeasureMode',
>>'data': ['page-sampling', 'dirty-ring', 'dirty-bitmap'] }
>>  
>> +##
>> +# @DirtyRateScope:
>> +#
>> +# An enumeration of scope of measuring dirtyrate.
> 
> "dirtyrate" is not a word.
> 
Indeed. I will be more verbose rather than using 'dirty rate'.

>> +#
>> +# @dirty-devices: calculate dirtyrate by devices only.
> 
> Please document @all, too.
> 
OK. I probably should have used 'vcpu' and 'devices',
rather than 'all' and 'dirty-devices'

>> +#
>> +# Since: 6.2
>> +#

This should be 7.1.

>> +##
>> +{ 'enum': 'DirtyRateScope',
>> +  'data': ['all', 'dirty-devices'] }
>> +
>>  ##
>>  # @DirtyRateInfo:
>>  #
>> @@ -1827,6 +1840,7 @@
>> 'calc-time': 'int64',
>> 'sample-pages': 'uint64',
>> 'mode': 'DirtyRateMeasureMode',
>> +   'scope': 'DirtyRateScope',
> 
> Please document new member @scope.
> 
OK.



Re: [PATCH RFC 09/10] migration/dirtyrate: Expand dirty_bitmap to be tracked separately for devices

2022-05-02 Thread Markus Armbruster
Joao Martins  writes:

> Expand dirtyrate measurer that is accessible via HMP calc_dirty_rate
> or QMP 'calc-dirty-rate' to receive a @scope argument. The scope
> then restricts the dirty tracking to be done at devices only,
> while neither enabling or using the KVM (CPU) dirty tracker.
> The default stays as is i.e. dirty-ring / dirty-bitmap from KVM.
>
> This is useful to test, exercise the IOMMU dirty tracker and observe
> how much a given device is dirtying memory.
>
> Signed-off-by: Joao Martins 

[...]

> diff --git a/qapi/migration.json b/qapi/migration.json
> index 27d7b281581d..082830c6e771 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1793,6 +1793,19 @@
>  { 'enum': 'DirtyRateMeasureMode',
>'data': ['page-sampling', 'dirty-ring', 'dirty-bitmap'] }
>  
> +##
> +# @DirtyRateScope:
> +#
> +# An enumeration of scope of measuring dirtyrate.

"dirtyrate" is not a word.

> +#
> +# @dirty-devices: calculate dirtyrate by devices only.

Please document @all, too.

> +#
> +# Since: 6.2
> +#
> +##
> +{ 'enum': 'DirtyRateScope',
> +  'data': ['all', 'dirty-devices'] }
> +
>  ##
>  # @DirtyRateInfo:
>  #
> @@ -1827,6 +1840,7 @@
> 'calc-time': 'int64',
> 'sample-pages': 'uint64',
> 'mode': 'DirtyRateMeasureMode',
> +   'scope': 'DirtyRateScope',

Please document new member @scope.

> '*vcpu-dirty-rate': [ 'DirtyRateVcpu' ] } }
>  
>  ##
> @@ -1851,6 +1865,7 @@
>  ##
>  { 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64',
>   '*sample-pages': 'int',
> + '*scope': 'DirtyRateScope',
>   '*mode': 'DirtyRateMeasureMode'} }
>  
>  ##

[...]




[PATCH RFC 09/10] migration/dirtyrate: Expand dirty_bitmap to be tracked separately for devices

2022-04-28 Thread Joao Martins
Expand dirtyrate measurer that is accessible via HMP calc_dirty_rate
or QMP 'calc-dirty-rate' to receive a @scope argument. The scope
then restricts the dirty tracking to be done at devices only,
while neither enabling or using the KVM (CPU) dirty tracker.
The default stays as is i.e. dirty-ring / dirty-bitmap from KVM.

This is useful to test, exercise the IOMMU dirty tracker and observe
how much a given device is dirtying memory.

Signed-off-by: Joao Martins 
---
 accel/kvm/kvm-all.c   | 12 +
 hmp-commands.hx   |  5 ++--
 hw/vfio/container.c   |  8 ++
 hw/vfio/iommufd.c |  4 +++
 include/exec/memory.h | 10 +++-
 migration/dirtyrate.c | 59 +--
 migration/dirtyrate.h |  1 +
 qapi/migration.json   | 15 +++
 softmmu/memory.c  |  5 
 9 files changed, 102 insertions(+), 17 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 5f1377ca048c..b4bbe0d20f6e 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1517,6 +1517,10 @@ static void kvm_log_sync(MemoryListener *listener,
 {
 KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, 
listener);
 
+if (memory_global_dirty_devices()) {
+return;
+}
+
 kvm_slots_lock();
 kvm_physical_sync_dirty_bitmap(kml, section);
 kvm_slots_unlock();
@@ -1529,6 +1533,10 @@ static void kvm_log_sync_global(MemoryListener *l)
 KVMSlot *mem;
 int i;
 
+if (memory_global_dirty_devices()) {
+return;
+}
+
 /* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
 kvm_dirty_ring_flush();
 
@@ -1558,6 +1566,10 @@ static void kvm_log_clear(MemoryListener *listener,
 KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, 
listener);
 int r;
 
+if (memory_global_dirty_devices()) {
+return;
+}
+
 r = kvm_physical_log_clear(kml, section);
 if (r < 0) {
 error_report_once("%s: kvm log clear failed: mr=%s "
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8476277aa9c9..28122d268ea3 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1739,10 +1739,11 @@ ERST
 
 {
 .name   = "calc_dirty_rate",
-.args_type  = 
"dirty_ring:-r,dirty_bitmap:-b,second:l,sample_pages_per_GB:l?",
-.params = "[-r] [-b] second [sample_pages_per_GB]",
+.args_type  = 
"dirty_devices:-d,dirty_ring:-r,dirty_bitmap:-b,second:l,sample_pages_per_GB:l?",
+.params = "[-d] [-r] [-b] second [sample_pages_per_GB]",
 .help   = "start a round of guest dirty rate measurement (using -r 
to"
   "\n\t\t\t specify dirty ring as the method of 
calculation and"
+  "\n\t\t\t specify devices as the only scope and"
   "\n\t\t\t -b to specify dirty bitmap as method of 
calculation)",
 .cmd= hmp_calc_dirty_rate,
 },
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 6bc1b8763f75..fff8319c0036 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -84,6 +84,10 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*bcontainer)
 VFIODevice *vbasedev;
 MigrationState *ms = migrate_get_current();
 
+if (bcontainer->dirty_pages_supported) {
+return true;
+}
+
 if (!migration_is_setup_or_active(ms->state)) {
 return false;
 }
@@ -311,6 +315,10 @@ static int vfio_get_dirty_bitmap(VFIOContainer 
*bcontainer, uint64_t iova,
 uint64_t pages;
 int ret;
 
+if (!memory_global_dirty_devices()) {
+return 0;
+}
+
 dbitmap = g_malloc0(sizeof(*dbitmap) + sizeof(*range));
 
 dbitmap->argsz = sizeof(*dbitmap) + sizeof(*range);
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index d75ecbf2ae52..4686cc713aac 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -150,6 +150,10 @@ static int iommufd_get_dirty_bitmap(VFIOContainer 
*bcontainer, uint64_t iova,
 VFIOIOASHwpt *hwpt;
 unsigned long *data, page_size, bitmap_size, pages;
 
+if (!memory_global_dirty_devices()) {
+return 0;
+}
+
 if (!bcontainer->dirty_pages_supported) {
 return 0;
 }
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 4d5997e6bbae..59c1d8bcc495 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -69,7 +69,10 @@ static inline void fuzz_dma_read_cb(size_t addr,
 /* Dirty tracking enabled because measuring dirty rate */
 #define GLOBAL_DIRTY_DIRTY_RATE (1U << 1)
 
-#define GLOBAL_DIRTY_MASK  (0x3)
+/* Dirty tracking enabled because measuring devices dirty rate */
+#define GLOBAL_DIRTY_DIRTY_RATE_DEVICES (1U << 2)
+
+#define GLOBAL_DIRTY_MASK  (0x7)
 
 extern unsigned int global_dirty_tracking;
 
@@ -2433,6 +2436,11 @@ void memory_global_dirty_log_start(unsigned int flags);
  */
 void memory_global_dirty_log_stop(unsigned int flags);
 
+/**
+ * memory_global_dirty_devices: check if the scope is just devices
+ */
+bool