mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 05:20:50 +00:00
cpus: make icount warp behave well with respect to stop/cont
This patch makes icount warp use the new QEMU_CLOCK_VIRTUAL_RT clock. This way, icount's QEMU_CLOCK_VIRTUAL will never count time during which the virtual machine is stopped. Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
4e7fa73ec2
commit
bf2a7ddb0a
21
cpus.c
21
cpus.c
@ -352,7 +352,7 @@ static void icount_warp_rt(void *opaque)
|
|||||||
|
|
||||||
seqlock_write_lock(&timers_state.vm_clock_seqlock);
|
seqlock_write_lock(&timers_state.vm_clock_seqlock);
|
||||||
if (runstate_is_running()) {
|
if (runstate_is_running()) {
|
||||||
int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
int64_t clock = cpu_get_clock_locked();
|
||||||
int64_t warp_delta;
|
int64_t warp_delta;
|
||||||
|
|
||||||
warp_delta = clock - vm_clock_warp_start;
|
warp_delta = clock - vm_clock_warp_start;
|
||||||
@ -361,9 +361,8 @@ static void icount_warp_rt(void *opaque)
|
|||||||
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
|
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
|
||||||
* far ahead of real time.
|
* far ahead of real time.
|
||||||
*/
|
*/
|
||||||
int64_t cur_time = cpu_get_clock_locked();
|
|
||||||
int64_t cur_icount = cpu_get_icount_locked();
|
int64_t cur_icount = cpu_get_icount_locked();
|
||||||
int64_t delta = cur_time - cur_icount;
|
int64_t delta = clock - cur_icount;
|
||||||
warp_delta = MIN(warp_delta, delta);
|
warp_delta = MIN(warp_delta, delta);
|
||||||
}
|
}
|
||||||
timers_state.qemu_icount_bias += warp_delta;
|
timers_state.qemu_icount_bias += warp_delta;
|
||||||
@ -426,7 +425,7 @@ void qemu_clock_warp(QEMUClockType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We want to use the earliest deadline from ALL vm_clocks */
|
/* We want to use the earliest deadline from ALL vm_clocks */
|
||||||
clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
|
||||||
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
|
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
|
||||||
if (deadline < 0) {
|
if (deadline < 0) {
|
||||||
return;
|
return;
|
||||||
@ -444,8 +443,8 @@ void qemu_clock_warp(QEMUClockType type)
|
|||||||
* sleep in icount mode if there is a pending QEMU_CLOCK_VIRTUAL
|
* sleep in icount mode if there is a pending QEMU_CLOCK_VIRTUAL
|
||||||
* timer; rather time could just advance to the next QEMU_CLOCK_VIRTUAL
|
* timer; rather time could just advance to the next QEMU_CLOCK_VIRTUAL
|
||||||
* event. Instead, we do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL
|
* event. Instead, we do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL
|
||||||
* after some e"real" time, (related to the time left until the next
|
* after some "real" time, (related to the time left until the next
|
||||||
* event) has passed. The QEMU_CLOCK_REALTIME timer will do this.
|
* event) has passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this.
|
||||||
* This avoids that the warps are visible externally; for example,
|
* This avoids that the warps are visible externally; for example,
|
||||||
* you will not be sending network packets continuously instead of
|
* you will not be sending network packets continuously instead of
|
||||||
* every 100ms.
|
* every 100ms.
|
||||||
@ -519,8 +518,8 @@ void configure_icount(QemuOpts *opts, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
icount_align_option = qemu_opt_get_bool(opts, "align", false);
|
icount_align_option = qemu_opt_get_bool(opts, "align", false);
|
||||||
icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
|
icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
|
||||||
icount_warp_rt, NULL);
|
icount_warp_rt, NULL);
|
||||||
if (strcmp(option, "auto") != 0) {
|
if (strcmp(option, "auto") != 0) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
icount_time_shift = strtol(option, &rem_str, 0);
|
icount_time_shift = strtol(option, &rem_str, 0);
|
||||||
@ -544,10 +543,10 @@ void configure_icount(QemuOpts *opts, Error **errp)
|
|||||||
the virtual time trigger catches emulated time passing too fast.
|
the virtual time trigger catches emulated time passing too fast.
|
||||||
Realtime triggers occur even when idle, so use them less frequently
|
Realtime triggers occur even when idle, so use them less frequently
|
||||||
than VM triggers. */
|
than VM triggers. */
|
||||||
icount_rt_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
|
icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
|
||||||
icount_adjust_rt, NULL);
|
icount_adjust_rt, NULL);
|
||||||
timer_mod(icount_rt_timer,
|
timer_mod(icount_rt_timer,
|
||||||
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
|
||||||
icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||||
icount_adjust_vm, NULL);
|
icount_adjust_vm, NULL);
|
||||||
timer_mod(icount_vm_timer,
|
timer_mod(icount_vm_timer,
|
||||||
|
@ -41,7 +41,8 @@
|
|||||||
*
|
*
|
||||||
* Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL.
|
* Outside icount mode, this clock is the same as @QEMU_CLOCK_VIRTUAL.
|
||||||
* In icount mode, this clock counts nanoseconds while the virtual
|
* In icount mode, this clock counts nanoseconds while the virtual
|
||||||
* machine is running.
|
* machine is running. It is used to increase @QEMU_CLOCK_VIRTUAL
|
||||||
|
* while the CPUs are sleeping and thus not executing instructions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
Loading…
Reference in New Issue
Block a user