libqos: use microseconds instead of iterations for virtio timeout

Some hosts are slow or overloaded so test execution takes a long time.
Test cases use timeouts to protect against an infinite loop stalling the
test forever (especially important in automated test setups).

Commit 6cd14054b6 ("libqos virtio:
Increase ISR timeout") increased the clock_step() value in an attempt to
lengthen the virtio interrupt wait timeout, but timeout failures are
still occuring on the Travis automated testing platform.

This is because clock_step() only affects the guest's virtual time.
Virtio requests can be bottlenecked on host disk I/O latency - which
cannot be improved by stepping the clock, so the fix was ineffective.

This patch changes the qvirtio_wait_queue_isr() and
qvirtio_wait_config_isr() timeout mechanism from loop iterations to
microseconds.  This way the test case can specify an absolute 30 second
timeout.  Number of loop iterations is not a reliable timeout mechanism
since the speed depends on many factors including host performance.

Tests should no longer timeout on overloaded Travis instances.

Cc: Marc Marí <marc.mari.barcelo@gmail.com>
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Stefan Hajnoczi 2014-09-29 16:40:12 +01:00 committed by Peter Maydell
parent e8c81b4d8a
commit 70556264a8
3 changed files with 42 additions and 43 deletions

View file

@ -78,17 +78,18 @@ void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
}
bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
QVirtQueue *vq, uint64_t timeout)
void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
QVirtQueue *vq, gint64 timeout_us)
{
do {
gint64 start_time = g_get_monotonic_time();
for (;;) {
clock_step(100);
if (bus->get_queue_isr_status(d, vq)) {
break; /* It has ended */
return;
}
} while (--timeout);
return timeout != 0;
g_assert(g_get_monotonic_time() - start_time <= timeout_us);
}
}
/* Wait for the status byte at given guest memory address to be set
@ -113,17 +114,18 @@ uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
return val;
}
bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
uint64_t timeout)
void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
gint64 timeout_us)
{
do {
gint64 start_time = g_get_monotonic_time();
for (;;) {
clock_step(100);
if (bus->get_config_isr_status(d)) {
break; /* It has ended */
return;
}
} while (--timeout);
return timeout != 0;
g_assert(g_get_monotonic_time() - start_time <= timeout_us);
}
}
void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)