From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MmVz0-0000Xc-SA for qemu-devel@nongnu.org; Sat, 12 Sep 2009 13:01:54 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MmVyv-0000OG-Tp for qemu-devel@nongnu.org; Sat, 12 Sep 2009 13:01:54 -0400 Received: from [199.232.76.173] (port=46970 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MmVyv-0000Nx-Pj for qemu-devel@nongnu.org; Sat, 12 Sep 2009 13:01:49 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]:55743) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MmVyu-00077u-Rt for qemu-devel@nongnu.org; Sat, 12 Sep 2009 13:01:49 -0400 Message-ID: <4AABD3C9.7050900@web.de> Date: Sat, 12 Sep 2009 19:00:57 +0200 From: Jan Kiszka MIME-Version: 1.0 References: <20090911213508.GA97446@triton8.kn-bremen.de> <4AAB938B.9080004@web.de> <20090912165222.GA38048@triton8.kn-bremen.de> In-Reply-To: <20090912165222.GA38048@triton8.kn-bremen.de> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigA85D85BEA838F4640133AC0F" Sender: jan.kiszka@web.de Subject: [Qemu-devel] Re: qemu serial: lost tx irqs (affectig FreeBSD's new uart(4) driver) List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Juergen Lock Cc: =?ISO-8859-1?Q?Olivier_Cochard-Labb=E9?= , freebsd-current@FreeBSD.org, qemu-devel@nongnu.org, Stefano Stabellini This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigA85D85BEA838F4640133AC0F Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Juergen Lock wrote: > On Sat, Sep 12, 2009 at 02:26:51PM +0200, Jan Kiszka wrote: >> Juergen Lock wrote: >>> Hi! >>> >>> I got a report of FreeBSD guest's new uart(4) driver misbehaving in >>> qemu again(?) (output stopping for no apparent reason), and now found= >>> out the problem is tx irqs (UART_IIR_THRI) are getting lost because >>> serial_update_irq() checks for the rx condtion, >>> ... if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) >>> first before checking for the tx irq condition, >>> ... if ((s->ier & UART_IER_THRI) && s->thr_ipending) >>> which at least in this case (FreeBSD 8 guest after doing >>> set console=3D"comconsole" >>> at the loader prompt or when simply echo'ing text to /dev/ttyu0 >>> or typing to the serial port from cu(1) on a `regular' vga console) >>> causes the second condition (.. && s->thr_ipending) to be never >>> reached anymore, or only after a very long delay. Moving that >>> condition up so it is checked first like this, >>> >>> Index: qemu/hw/serial.c >>> @@ -189,7 +188,9 @@ static void serial_update_irq(SerialStat >>> { >>> uint8_t tmp_iir =3D UART_IIR_NO_INT; >>> =20 >>> - if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) { >>> + if ((s->ier & UART_IER_THRI) && s->thr_ipending) { >>> + tmp_iir =3D UART_IIR_THRI; >>> + } else if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_AN= Y)) { >>> tmp_iir =3D UART_IIR_RLSI; >>> } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) { >>> /* Note that(s->ier & UART_IER_RDI) can mask this interrupt,= >>> @@ -202,8 +203,6 @@ static void serial_update_irq(SerialStat >>> } else if (s->recv_fifo.count >=3D s->recv_fifo.itl) { >>> tmp_iir =3D UART_IIR_RDI; >>> } >>> - } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) { >>> - tmp_iir =3D UART_IIR_THRI; >>> } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DEL= TA)) { >>> tmp_iir =3D UART_IIR_MSI; >>> } >>> >>> ...fixes the issue for me, but I'm not 100% sure if this might cause >>> rx irqs to come (too?) late when a guest keeps sending while its >>> receiving at the same time. Anyone care to comment? :) >> The reordering violates the 16550A spec in that RX event overrules TX = in >> the IRQ status register. Maybe something else is wrong but it's not th= e >> ordering in serial_update_irq. >=20 > Well one problem seems to be the rx condition, > ... if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) > is not enough to trigger an irq, yet still causes the following > conditions not to be checked anymore at all. And ideed, fixing that > seems to get my FreeBSD 8 guest back to working order as well: >=20 > Index: qemu/hw/serial.c > @@ -196,12 +195,10 @@ static void serial_update_irq(SerialStat > * this is not in the specification but is observed on existin= g > * hardware. */ > tmp_iir =3D UART_IIR_CTI; > - } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) { > - if (!(s->fcr & UART_FCR_FE)) { > - tmp_iir =3D UART_IIR_RDI; > - } else if (s->recv_fifo.count >=3D s->recv_fifo.itl) { > - tmp_iir =3D UART_IIR_RDI; > - } > + } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) && > + (!(s->fcr & UART_FCR_FE) || > + s->recv_fifo.count >=3D s->recv_fifo.itl)) { > + tmp_iir =3D UART_IIR_RDI; > } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) { > tmp_iir =3D UART_IIR_THRI; > } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA= )) { >=20 > Signed-off-by: Juergen Lock Yep, that does make sense! Acked-by: Jan Kiszka But I also but Stefano on CC as he introduced the logic above. Jan --------------enigA85D85BEA838F4640133AC0F Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iEYEARECAAYFAkqr08kACgkQniDOoMHTA+kZMgCfbwpuS4pVi6jJgaurSotQqJko YqoAoIMREkhLaoV8SNY0BWUUWEswFRBE =Wz3B -----END PGP SIGNATURE----- --------------enigA85D85BEA838F4640133AC0F--