From 4ea9a0e3db39a3ef07f8a97c005733d127485891 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 24 Jul 2019 12:58:21 +0100 Subject: timer: Remove reset notifiers Remove the reset notifer from the core qemu-timer code. The only user was mc146818 and we've just remove it's use. Signed-off-by: Dr. David Alan Gilbert Message-Id: <20190724115823.4199-3-dgilbert@redhat.com> Signed-off-by: Paolo Bonzini --- util/qemu-timer.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'util') diff --git a/util/qemu-timer.c b/util/qemu-timer.c index b0e40a9..1ac8314 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -47,7 +47,6 @@ typedef struct QEMUClock { /* We rely on BQL to protect the timerlists */ QLIST_HEAD(, QEMUTimerList) timerlists; - NotifierList reset_notifiers; int64_t last; QEMUClockType type; @@ -132,7 +131,6 @@ static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *notify_cb clock->enabled = (type == QEMU_CLOCK_VIRTUAL ? false : true); clock->last = INT64_MIN; QLIST_INIT(&clock->timerlists); - notifier_list_init(&clock->reset_notifiers); main_loop_tlg.tl[type] = timerlist_new(type, notify_cb, NULL); } @@ -629,7 +627,7 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) int64_t qemu_clock_get_ns(QEMUClockType type) { - int64_t now, last; + int64_t now; QEMUClock *clock = qemu_clock_ptr(type); switch (type) { @@ -644,11 +642,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) } case QEMU_CLOCK_HOST: now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); - last = clock->last; clock->last = now; - if (now < last || now > (last + get_max_clock_jump())) { - notifier_list_notify(&clock->reset_notifiers, &now); - } return now; case QEMU_CLOCK_VIRTUAL_RT: return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock()); @@ -667,19 +661,6 @@ void qemu_clock_set_last(QEMUClockType type, uint64_t last) clock->last = last; } -void qemu_clock_register_reset_notifier(QEMUClockType type, - Notifier *notifier) -{ - QEMUClock *clock = qemu_clock_ptr(type); - notifier_list_add(&clock->reset_notifiers, notifier); -} - -void qemu_clock_unregister_reset_notifier(QEMUClockType type, - Notifier *notifier) -{ - notifier_remove(notifier); -} - void init_clocks(QEMUTimerListNotifyCB *notify_cb) { QEMUClockType type; -- cgit v1.1 From 3c2d4c8aa6a98366c9fe2f36305f12199257a7d5 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 24 Jul 2019 12:58:23 +0100 Subject: timer: last, remove last bits of last The reset notifiers kept a 'last' counter to notice jumps; now that we've remove the notifier we don't need to keep 'last'. Signed-off-by: Dr. David Alan Gilbert Message-Id: <20190724115823.4199-5-dgilbert@redhat.com> Signed-off-by: Paolo Bonzini --- util/qemu-timer.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'util') diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 1ac8314..37ecfe3 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -47,8 +47,6 @@ typedef struct QEMUClock { /* We rely on BQL to protect the timerlists */ QLIST_HEAD(, QEMUTimerList) timerlists; - int64_t last; - QEMUClockType type; bool enabled; } QEMUClock; @@ -129,7 +127,6 @@ static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *notify_cb clock->type = type; clock->enabled = (type == QEMU_CLOCK_VIRTUAL ? false : true); - clock->last = INT64_MIN; QLIST_INIT(&clock->timerlists); main_loop_tlg.tl[type] = timerlist_new(type, notify_cb, NULL); } @@ -627,9 +624,6 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) int64_t qemu_clock_get_ns(QEMUClockType type) { - int64_t now; - QEMUClock *clock = qemu_clock_ptr(type); - switch (type) { case QEMU_CLOCK_REALTIME: return get_clock(); @@ -641,26 +635,12 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return cpu_get_clock(); } case QEMU_CLOCK_HOST: - now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); - clock->last = now; - return now; + return REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); case QEMU_CLOCK_VIRTUAL_RT: return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock()); } } -uint64_t qemu_clock_get_last(QEMUClockType type) -{ - QEMUClock *clock = qemu_clock_ptr(type); - return clock->last; -} - -void qemu_clock_set_last(QEMUClockType type, uint64_t last) -{ - QEMUClock *clock = qemu_clock_ptr(type); - clock->last = last; -} - void init_clocks(QEMUTimerListNotifyCB *notify_cb) { QEMUClockType type; -- cgit v1.1 From dcb1578069dd072f9aec74e3024cadb9ed0f3aae Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Thu, 25 Jul 2019 11:44:26 +0300 Subject: util/qemu-timer: refactor deadline calculation for external timers icount-based record/replay uses qemu_clock_deadline_ns_all to measure the period until vCPU may be interrupted. This function takes in account the virtual timers, because they belong to the virtual devices that may generate interrupt request or affect the virtual machine state. However, there are a subset of virtual timers, that are marked with 'external' flag. These do not change the virtual machine state and only based on virtual clock. Calculating the deadling using the external timers breaks the determinism, because they do not belong to the replayed part of the virtual machine. This patch fixes the deadline calculation for this case by adding new parameter for skipping the external timers when it is needed. Signed-off-by: Pavel Dovgalyuk -- v2 changes: - added new parameter for timer attribute mask Message-Id: <156404426682.18669.17014100602930969222.stgit@pasha-Precision-3630-Tower> Signed-off-by: Paolo Bonzini --- util/qemu-timer.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'util') diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 37ecfe3..d428fec 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -247,14 +247,38 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) * ignore whether or not the clock should be used in deadline * calculations. */ -int64_t qemu_clock_deadline_ns_all(QEMUClockType type) +int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask) { int64_t deadline = -1; + int64_t delta; + int64_t expire_time; + QEMUTimer *ts; QEMUTimerList *timer_list; QEMUClock *clock = qemu_clock_ptr(type); + + if (!clock->enabled) { + return -1; + } + QLIST_FOREACH(timer_list, &clock->timerlists, list) { - deadline = qemu_soonest_timeout(deadline, - timerlist_deadline_ns(timer_list)); + qemu_mutex_lock(&timer_list->active_timers_lock); + ts = timer_list->active_timers; + /* Skip all external timers */ + while (ts && (ts->attributes & ~attr_mask)) { + ts = ts->next; + } + if (!ts) { + qemu_mutex_unlock(&timer_list->active_timers_lock); + continue; + } + expire_time = ts->expire_time; + qemu_mutex_unlock(&timer_list->active_timers_lock); + + delta = expire_time - qemu_clock_get_ns(type); + if (delta <= 0) { + delta = 0; + } + deadline = qemu_soonest_timeout(deadline, delta); } return deadline; } -- cgit v1.1