On Mon, Jun 07, 2021 at 09:15:20AM +0800, huang...@chinatelecom.cn wrote: > +static void calculate_dirtyrate_vcpu(struct DirtyRateConfig config) > +{ > + CPUState *cpu; > + int64_t msec = 0; > + int64_t start_time; > + uint64_t dirtyrate = 0; > + uint64_t dirtyrate_sum = 0; > + int nvcpu = 0; > + int i = 0; > + > + CPU_FOREACH(cpu) { > + nvcpu++; > + } > + > + dirty_pages = g_malloc0(sizeof(*dirty_pages) * nvcpu); > + > + dirtyrate_global_dirty_log_start(); > + > + CPU_FOREACH(cpu) { > + record_dirtypages(cpu, true); > + } > + > + DirtyStat.method.vcpu.nvcpu = nvcpu; > + if (last_method != CALC_DIRTY_RING) { > + DirtyStat.method.vcpu.rates = > + g_malloc0(sizeof(DirtyRateVcpu) * nvcpu); > + } > + > + start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); > + DirtyStat.start_time = start_time / 1000; > + > + msec = config.sample_period_seconds * 1000; > + msec = set_sample_page_period(msec, start_time); > + DirtyStat.calc_time = msec / 1000; > + > + CPU_FOREACH(cpu) { > + record_dirtypages(cpu, false); > + } > + > + dirtyrate_global_dirty_log_stop(); > + > + for (i = 0; i < DirtyStat.method.vcpu.nvcpu; i++) { > + dirtyrate = do_calculate_dirtyrate_vcpu(i); > + DirtyStat.method.vcpu.rates[i].id = i; > + DirtyStat.method.vcpu.rates[i].dirty_rate = dirtyrate; > + dirtyrate_sum += dirtyrate; > + } > + > + DirtyStat.dirty_rate = dirtyrate_sum / DirtyStat.method.vcpu.nvcpu;
Why you'd like to divide with nvcpu? Isn't dirtyrate_sum exactly what we want? As I don't think we care about average per-vcpu dirty rate, but total here. > + g_free(dirty_pages); > +} I did a run with 4G mem VM, alloc 1G and dirty it with 500MB/s, then - With old way: I got 95MB/s - With new way: I got 128MB/s The new way has the output with: Dirty rate: 128 (MB/s) vcpu[0], Dirty rate: 0 vcpu[1], Dirty rate: 1 vcpu[2], Dirty rate: 0 vcpu[3], Dirty rate: 511 I think if without the division, it'll be 512MB/s, which is matching the dirty workload I initiated. -- Peter Xu