From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XXYUl-0003OP-Jj for qemu-devel@nongnu.org; Fri, 26 Sep 2014 12:35:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XXYUg-0003ja-3t for qemu-devel@nongnu.org; Fri, 26 Sep 2014 12:35:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:22955) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XXYUf-0003hR-No for qemu-devel@nongnu.org; Fri, 26 Sep 2014 12:35:42 -0400 From: Stefan Hajnoczi Date: Fri, 26 Sep 2014 17:35:25 +0100 Message-Id: <1411749325-19489-1-git-send-email-stefanha@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH] libqos: use microseconds instead of iterations for virtio timeout List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Marc=20Mar=C3=AD?= , Peter Maydell , Andreas Faerber , Stefan Hajnoczi 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 6cd14054b67774cc58a51fca6660cfa1d3c08059 ("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. Note that I dropped an assertion that waits for the full timeout duration to assert that no interrupt was raised. I think this is not a huge loss because it makes the test case non-deterministic (it cannot really prove the no interrupt will ever be raised). Cc: Marc Mar=C3=AD Reported-by: Peter Maydell Signed-off-by: Stefan Hajnoczi --- tests/libqos/virtio.c | 30 +++++++++++++++------------- tests/libqos/virtio.h | 8 ++++---- tests/virtio-blk-test.c | 52 ++++++++++++++++++++++---------------------= ------ 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 9b6de2c..0f6ffa4 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -78,30 +78,32 @@ void qvirtio_set_driver_ok(const QVirtioBus *bus, QVi= rtioDevice *d) QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE= ); } =20 -bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, - QVirtQueue *vq, uint64_t tim= eout) +void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, + QVirtQueue *vq, gint64 timeout_us) { - do { + gint64 start_time =3D 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 !=3D 0; + g_assert(g_get_monotonic_time() - start_time <=3D timeout_us); + } } =20 -bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, - uint64_t tim= eout) +void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, + gint64 timeout_us) { - do { + gint64 start_time =3D g_get_monotonic_time(); + + for (;;) { clock_step(100); if (bus->get_config_isr_status(d)) { - break; /* It has ended */ + return; } - } while (--timeout); - - return timeout !=3D 0; + g_assert(g_get_monotonic_time() - start_time <=3D timeout_us); + } } =20 void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t = addr) diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h index 70b3376..42a37dd 100644 --- a/tests/libqos/virtio.h +++ b/tests/libqos/virtio.h @@ -160,10 +160,10 @@ void qvirtio_set_acknowledge(const QVirtioBus *bus,= QVirtioDevice *d); void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d); void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d); =20 -bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, - QVirtQueue *vq, uint64_t tim= eout); -bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, - uint64_t tim= eout); +void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, + QVirtQueue *vq, gint64 timeout_us); +void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, + gint64 timeout_us); QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d, QGuestAllocator *alloc, uint16_t= index); =20 diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 588666c..41efea1 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -41,7 +41,7 @@ #define QVIRTIO_BLK_T_GET_ID 8 =20 #define TEST_IMAGE_SIZE (64 * 1024 * 1024) -#define QVIRTIO_BLK_TIMEOUT 100 +#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000) #define PCI_SLOT 0x04 #define PCI_FN 0x00 =20 @@ -183,8 +183,8 @@ static void pci_basic(void) qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -205,8 +205,8 @@ static void pci_basic(void) =20 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -233,8 +233,8 @@ static void pci_basic(void) =20 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -256,8 +256,8 @@ static void pci_basic(void) =20 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -329,8 +329,8 @@ static void pci_indirect(void) free_head =3D qvirtqueue_add_indirect(&vqpci->vq, indirect); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -354,8 +354,8 @@ static void pci_indirect(void) free_head =3D qvirtqueue_add_indirect(&vqpci->vq, indirect); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -396,8 +396,7 @@ static void pci_config(void) =20 qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0',= " " 'size': %d } }", n= _size); - g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOU= T_US); =20 capacity =3D qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr); g_assert_cmpint(capacity, =3D=3D, n_size / 512); @@ -452,8 +451,7 @@ static void pci_msix(void) qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0',= " " 'size': %d } }", n= _size); =20 - g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOU= T_US); =20 capacity =3D qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr); g_assert_cmpint(capacity, =3D=3D, n_size / 512); @@ -473,8 +471,8 @@ static void pci_msix(void) qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); =20 status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); @@ -497,8 +495,8 @@ static void pci_msix(void) qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); =20 status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); @@ -574,8 +572,8 @@ static void pci_idx(void) qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); =20 /* Write request */ req.type =3D QVIRTIO_BLK_T_OUT; @@ -594,10 +592,6 @@ static void pci_idx(void) qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 - /* No notification expected */ - g_assert(!qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->v= q, - QVIRTIO_BLK_TIME= OUT)); - status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); =20 @@ -619,8 +613,8 @@ static void pci_idx(void) qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); =20 =20 - g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq= , - QVIRTIO_BLK_TIME= OUT)); + qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT_US); =20 status =3D readb(req_addr + 528); g_assert_cmpint(status, =3D=3D, 0); --=20 1.9.3