On Fri, Sep 1, 2023 at 10:19 AM <alloc.yo...@outlook.com> wrote: > From: alloc <alloc.yo...@outlook.com> > > Timeout functions like usleep can return early on signal, which reduces > more dirty pages than expected. In dirtylimit case, dirtyrate meter > thread needs to kick all vcpus out to sync. The callchain: > > vcpu_calculate_dirtyrate > global_dirty_log_sync > memory_global_dirty_log_sync > kvm_log_sync_global > kvm_dirty_ring_flush > kvm_cpu_synchronize_kick_all <---- send vcpu signal > > For long time sleep, use qemu_cond_timedwait_iothread to handle cpu stop > event. > > The Dirty Limit algorithm seeks to keep the vCPU dirty page rate within the set limit; since it focuses more emphasis on processing time and precision, I feel that improvement should strive for the same result. Could you please provide the final test results showing the impact of that improvement?
> Signed-off-by: alloc <alloc.yo...@outlook.com> > --- > softmmu/dirtylimit.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c > index fa959d7743..ee938c636d 100644 > --- a/softmmu/dirtylimit.c > +++ b/softmmu/dirtylimit.c > @@ -411,13 +411,28 @@ void dirtylimit_set_all(uint64_t quota, > > void dirtylimit_vcpu_execute(CPUState *cpu) > { > + int64_t sleep_us, endtime_us; > + > + dirtylimit_state_lock(); > if (dirtylimit_in_service() && > dirtylimit_vcpu_get_state(cpu->cpu_index)->enabled && > cpu->throttle_us_per_full) { > trace_dirtylimit_vcpu_execute(cpu->cpu_index, > cpu->throttle_us_per_full); > - usleep(cpu->throttle_us_per_full); > - } > + sleep_us = cpu->throttle_us_per_full; > + dirtylimit_state_unlock(); > + endtime_us = qemu_clock_get_us(QEMU_CLOCK_REALTIME) + sleep_us; > + while (sleep_us > 0 && !cpu->stop) { > + if (sleep_us > SCALE_US) { > + qemu_mutex_lock_iothread(); > + qemu_cond_timedwait_iothread(cpu->halt_cond, sleep_us / > SCALE_US); > + qemu_mutex_unlock_iothread(); > + } else > + g_usleep(sleep_us); > + sleep_us = endtime_us - > qemu_clock_get_us(QEMU_CLOCK_REALTIME); > + } > + } else > + dirtylimit_state_unlock(); > } > > static void dirtylimit_init(void) > -- > 2.39.3 > > -- Best regards