On Mon, Jun 07, 2021 at 09:15:20AM +0800, huangy81@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.