* [Qemu-devel] [PATCH v2 0/3] Simplify and fix alarm deadline computation
@ 2011-02-03 13:48 Paolo Bonzini
2011-02-03 13:48 ` [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation Paolo Bonzini
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Paolo Bonzini @ 2011-02-03 13:48 UTC (permalink / raw)
To: qemu-devel; +Cc: aurelien
This is a rebased and updated version of the series to fix alarm
deadline computation. I adopted Aurelien's suggestion to change
everything to nanoseconds. I also did more testing than just
compiling, by booting with -icount.
And it wasn't enough. Patch 1 was broken due to a mistake in converting
to QEMU_CLOCK_REALTIME to nanoseconds (in patch 1). I found it just by
inspection, but at this point I believe this should be baked in 0.15
first before backporting.
v1->v2
Add patch 1
v2->v3
Fix patch 1
Paolo Bonzini (3):
use nanoseconds everywhere for timeout computation
Correct alarm deadline computation
Unify alarm deadline computation
qemu-timer.c | 65 +++++++++++++++++++++++++++++----------------------------
1 files changed, 33 insertions(+), 32 deletions(-)
--
1.7.3.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation
2011-02-03 13:48 [Qemu-devel] [PATCH v2 0/3] Simplify and fix alarm deadline computation Paolo Bonzini
@ 2011-02-03 13:48 ` Paolo Bonzini
2011-02-04 12:51 ` Anthony Liguori
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 2/3] Correct alarm deadline computation Paolo Bonzini
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 3/3] Unify " Paolo Bonzini
2 siblings, 1 reply; 5+ messages in thread
From: Paolo Bonzini @ 2011-02-03 13:48 UTC (permalink / raw)
To: qemu-devel; +Cc: aurelien
Suggested by Aurelien Jarno.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-timer.c | 30 +++++++++++++++---------------
1 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/qemu-timer.c b/qemu-timer.c
index db1ec49..60283a8 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -197,8 +197,8 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
t->rearm(t);
}
-/* TODO: MIN_TIMER_REARM_US should be optimized */
-#define MIN_TIMER_REARM_US 250
+/* TODO: MIN_TIMER_REARM_NS should be optimized */
+#define MIN_TIMER_REARM_NS 250000
#ifdef _WIN32
@@ -698,11 +698,11 @@ int64_t qemu_next_deadline(void)
if (active_timers[QEMU_CLOCK_VIRTUAL]) {
delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
- qemu_get_clock(vm_clock);
+ qemu_get_clock_ns(vm_clock);
}
if (active_timers[QEMU_CLOCK_HOST]) {
int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
- qemu_get_clock(host_clock);
+ qemu_get_clock_ns(host_clock);
if (hdelta < delta)
delta = hdelta;
}
@@ -727,17 +727,17 @@ static uint64_t qemu_next_deadline_dyntick(void)
if (use_icount)
delta = INT32_MAX;
else
- delta = (qemu_next_deadline() + 999) / 1000;
+ delta = qemu_next_deadline();
if (active_timers[QEMU_CLOCK_REALTIME]) {
- rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
- qemu_get_clock(rt_clock))*1000;
+ rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 -
+ qemu_get_clock_ns(rt_clock));
if (rtdelta < delta)
delta = rtdelta;
}
- if (delta < MIN_TIMER_REARM_US)
- delta = MIN_TIMER_REARM_US;
+ if (delta < MIN_TIMER_REARM_NS)
+ delta = MIN_TIMER_REARM_NS;
return delta;
}
@@ -887,8 +887,8 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
{
timer_t host_timer = (timer_t)(long)t->priv;
struct itimerspec timeout;
- int64_t nearest_delta_us = INT64_MAX;
- int64_t current_us;
+ int64_t nearest_delta_ns = INT64_MAX;
+ int64_t current_ns;
assert(alarm_has_dynticks(t));
if (!active_timers[QEMU_CLOCK_REALTIME] &&
@@ -896,7 +896,7 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
!active_timers[QEMU_CLOCK_HOST])
return;
- nearest_delta_us = qemu_next_deadline_dyntick();
+ nearest_delta_ns = qemu_next_deadline_dyntick();
/* check whether a timer is already running */
if (timer_gettime(host_timer, &timeout)) {
@@ -904,14 +904,14 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
fprintf(stderr, "Internal timer error: aborting\n");
exit(1);
}
- current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
- if (current_us && current_us <= nearest_delta_us)
+ current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
+ if (current_ns && current_ns <= nearest_delta_ns)
return;
timeout.it_interval.tv_sec = 0;
timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
- timeout.it_value.tv_sec = nearest_delta_us / 1000000;
- timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
+ timeout.it_value.tv_sec = nearest_delta_ns / 1000000000;
+ timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
perror("settime");
fprintf(stderr, "Internal timer error: aborting\n");
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 2/3] Correct alarm deadline computation
2011-02-03 13:48 [Qemu-devel] [PATCH v2 0/3] Simplify and fix alarm deadline computation Paolo Bonzini
2011-02-03 13:48 ` [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation Paolo Bonzini
@ 2011-02-03 13:49 ` Paolo Bonzini
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 3/3] Unify " Paolo Bonzini
2 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2011-02-03 13:49 UTC (permalink / raw)
To: qemu-devel; +Cc: Jan Kiszka, aurelien
When the QEMU_CLOCK_HOST clock was added, computation of its
deadline was added to qemu_next_deadline, which is correct but
incomplete.
I noticed this by reading the very convoluted rules whereby
qemu_next_deadline_dyntick is computed, which miss QEMU_CLOCK_HOST
when use_icount is true. This patch inlines qemu_next_deadline
into qemu_next_deadline_dyntick, and then corrects the logic to skip
only QEMU_CLOCK_VIRTUAL when use_icount is true.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
---
qemu-timer.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/qemu-timer.c b/qemu-timer.c
index 60283a8..c19d0a2 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -724,11 +724,18 @@ static uint64_t qemu_next_deadline_dyntick(void)
int64_t delta;
int64_t rtdelta;
- if (use_icount)
+ if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) {
+ delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
+ qemu_get_clock(vm_clock);
+ } else {
delta = INT32_MAX;
- else
- delta = qemu_next_deadline();
-
+ }
+ if (active_timers[QEMU_CLOCK_HOST]) {
+ int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
+ qemu_get_clock_ns(host_clock);
+ if (hdelta < delta)
+ delta = hdelta;
+ }
if (active_timers[QEMU_CLOCK_REALTIME]) {
rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 -
qemu_get_clock_ns(rt_clock));
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 3/3] Unify alarm deadline computation
2011-02-03 13:48 [Qemu-devel] [PATCH v2 0/3] Simplify and fix alarm deadline computation Paolo Bonzini
2011-02-03 13:48 ` [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation Paolo Bonzini
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 2/3] Correct alarm deadline computation Paolo Bonzini
@ 2011-02-03 13:49 ` Paolo Bonzini
2 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2011-02-03 13:49 UTC (permalink / raw)
To: qemu-devel; +Cc: aurelien
This patch shows how using the correct formula for
qemu_next_deadline_dyntick can simplify the code of
host_alarm_handler and eliminate useless duplication.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-timer.c | 28 +++++++++++-----------------
2 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/qemu-timer.c b/qemu-timer.c
index c19d0a2..d3c426c 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -635,6 +635,8 @@ void qemu_run_all_timers(void)
qemu_run_timers(host_clock);
}
+static int64_t qemu_next_alarm_deadline(void);
+
#ifdef _WIN32
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -677,14 +679,7 @@ static void host_alarm_handler(int host_signum)
}
#endif
if (alarm_has_dynticks(t) ||
- (!use_icount &&
- qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
- qemu_get_clock(vm_clock))) ||
- qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
- qemu_get_clock(rt_clock)) ||
- qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
- qemu_get_clock(host_clock))) {
-
+ qemu_next_alarm_deadline () <= 0) {
t->expired = alarm_has_dynticks(t);
t->pending = 1;
qemu_notify_event();
@@ -715,11 +710,7 @@ int64_t qemu_next_deadline(void)
#ifndef _WIN32
-#if defined(__linux__)
-
-#define RTC_FREQ 1024
-
-static uint64_t qemu_next_deadline_dyntick(void)
+static int64_t qemu_next_alarm_deadline(void)
{
int64_t delta;
int64_t rtdelta;
@@ -743,12 +734,13 @@ static uint64_t qemu_next_deadline_dyntick(void)
delta = rtdelta;
}
- if (delta < MIN_TIMER_REARM_NS)
- delta = MIN_TIMER_REARM_NS;
-
return delta;
}
+#if defined(__linux__)
+
+#define RTC_FREQ 1024
+
static void enable_sigio_timer(int fd)
{
struct sigaction act;
@@ -903,7 +895,9 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
!active_timers[QEMU_CLOCK_HOST])
return;
- nearest_delta_ns = qemu_next_deadline_dyntick();
+ nearest_delta_ns = qemu_next_alarm_deadline();
+ if (nearest_delta_ns < MIN_TIMER_REARM_NS)
+ nearest_delta_ns = MIN_TIMER_REARM_NS;
/* check whether a timer is already running */
if (timer_gettime(host_timer, &timeout)) {
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation
2011-02-03 13:48 ` [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation Paolo Bonzini
@ 2011-02-04 12:51 ` Anthony Liguori
0 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2011-02-04 12:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, aurelien
On 02/03/2011 07:48 AM, Paolo Bonzini wrote:
> Suggested by Aurelien Jarno.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
>
Applied to master, Thanks.
Regards,
Anthony Liguori
> ---
> qemu-timer.c | 30 +++++++++++++++---------------
> 1 files changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/qemu-timer.c b/qemu-timer.c
> index db1ec49..60283a8 100644
> --- a/qemu-timer.c
> +++ b/qemu-timer.c
> @@ -197,8 +197,8 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
> t->rearm(t);
> }
>
> -/* TODO: MIN_TIMER_REARM_US should be optimized */
> -#define MIN_TIMER_REARM_US 250
> +/* TODO: MIN_TIMER_REARM_NS should be optimized */
> +#define MIN_TIMER_REARM_NS 250000
>
> #ifdef _WIN32
>
> @@ -698,11 +698,11 @@ int64_t qemu_next_deadline(void)
>
> if (active_timers[QEMU_CLOCK_VIRTUAL]) {
> delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
> - qemu_get_clock(vm_clock);
> + qemu_get_clock_ns(vm_clock);
> }
> if (active_timers[QEMU_CLOCK_HOST]) {
> int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
> - qemu_get_clock(host_clock);
> + qemu_get_clock_ns(host_clock);
> if (hdelta< delta)
> delta = hdelta;
> }
> @@ -727,17 +727,17 @@ static uint64_t qemu_next_deadline_dyntick(void)
> if (use_icount)
> delta = INT32_MAX;
> else
> - delta = (qemu_next_deadline() + 999) / 1000;
> + delta = qemu_next_deadline();
>
> if (active_timers[QEMU_CLOCK_REALTIME]) {
> - rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
> - qemu_get_clock(rt_clock))*1000;
> + rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 -
> + qemu_get_clock_ns(rt_clock));
> if (rtdelta< delta)
> delta = rtdelta;
> }
>
> - if (delta< MIN_TIMER_REARM_US)
> - delta = MIN_TIMER_REARM_US;
> + if (delta< MIN_TIMER_REARM_NS)
> + delta = MIN_TIMER_REARM_NS;
>
> return delta;
> }
> @@ -887,8 +887,8 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
> {
> timer_t host_timer = (timer_t)(long)t->priv;
> struct itimerspec timeout;
> - int64_t nearest_delta_us = INT64_MAX;
> - int64_t current_us;
> + int64_t nearest_delta_ns = INT64_MAX;
> + int64_t current_ns;
>
> assert(alarm_has_dynticks(t));
> if (!active_timers[QEMU_CLOCK_REALTIME]&&
> @@ -896,7 +896,7 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
> !active_timers[QEMU_CLOCK_HOST])
> return;
>
> - nearest_delta_us = qemu_next_deadline_dyntick();
> + nearest_delta_ns = qemu_next_deadline_dyntick();
>
> /* check whether a timer is already running */
> if (timer_gettime(host_timer,&timeout)) {
> @@ -904,14 +904,14 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
> fprintf(stderr, "Internal timer error: aborting\n");
> exit(1);
> }
> - current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
> - if (current_us&& current_us<= nearest_delta_us)
> + current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
> + if (current_ns&& current_ns<= nearest_delta_ns)
> return;
>
> timeout.it_interval.tv_sec = 0;
> timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
> - timeout.it_value.tv_sec = nearest_delta_us / 1000000;
> - timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
> + timeout.it_value.tv_sec = nearest_delta_ns / 1000000000;
> + timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
> if (timer_settime(host_timer, 0 /* RELATIVE */,&timeout, NULL)) {
> perror("settime");
> fprintf(stderr, "Internal timer error: aborting\n");
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-02-04 12:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-03 13:48 [Qemu-devel] [PATCH v2 0/3] Simplify and fix alarm deadline computation Paolo Bonzini
2011-02-03 13:48 ` [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation Paolo Bonzini
2011-02-04 12:51 ` Anthony Liguori
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 2/3] Correct alarm deadline computation Paolo Bonzini
2011-02-03 13:49 ` [Qemu-devel] [PATCH v2 3/3] Unify " Paolo Bonzini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.