svn commit: r295557 - head/sys/dev/uart

Marius Strobl marius at freebsd.org
Sat Feb 13 00:58:05 UTC 2016


On Sat, Feb 13, 2016 at 06:53:25AM +1100, Bruce Evans wrote:
> On Fri, 12 Feb 2016, Marius Strobl wrote:
> 
> > On Fri, Feb 12, 2016 at 05:14:58AM +0000, Michal Meloun wrote:
> >> Author: mmel
> >> Date: Fri Feb 12 05:14:58 2016
> >> New Revision: 295557
> >> URL: https://svnweb.freebsd.org/changeset/base/295557
> >>
> >> Log:
> >>   UART: Fix spurious interrupts generated by ns8250 and lpc drivers:
> >>    - don't enable transmitter empty interrupt before filling TX FIFO.
> >
> > Are you sure this doesn't create a race that leads to lost TX ready
> > interrupts? For a single character, the TX FIFO very well may be empty
> > again at the point in time IER_ETXRDY is enabled now.  With the varying
> > behavior of 8250/16x50 chips - some of which is documented in sio(4) -
> 
> That is mostly FUD.  More likely driver bugs than chip bugs.
> 
> A non-broken xx50 interrupts after you (re)enable tx interrupts, iff
> the fifo is already empty.  This gives a "spurious" interrupt.  But
> perhaps depending on this is too fragile.  Normal operation is to keep
> the tx interrupt enabled and depend on writing to the fifo causing a
> tx interrupt later.  But it is a more common chip bug for tx interrupts
> later to not go away when they should (normally by reading the IIR),
> so some drivers toggle the tx interrupt enable dynamically.
> 
> An example of a driver bug is only enabling tx interrupts for this.
> It takes a transition of the interrupt enable bit from off to on to
> get the interrupt.  Other driver bugs may result in a missing transition
> because the bit was supposed to be off but is actually on.
> 
> > I'd expect there are many that no longer generate a TX ready at all
> > with this change in place. In this case, receiving spurious interrupts
> > (which ones? IIR_NOPEND? IIR_TXRDY?) with some devices appears to be
> > the lesser evil.
> 
> Not many.  Only broken ones.

In my experience many xx50 are broken, especially the integrated
on-board ones you still have in workstations and servers today.

> The "spurious" interrupts are just normal
> ones from bon-broken chips:
> 
> - uart first does a potentially-unbounded busy-wait before the doing
>    anything to ensure that the fifo is empty.  This should be unecessary
>    since this function should not be called unless sc_txbusy is 0 and
>    sc_txbusy should be nonzero if the fifo is not empty.  If it is called
>    when the fifo is not emptu, then the worst-case busy-wait is approx.
>    640 seconds for a 128-byte fifo at 2 bps. The 'broken_txfifo case'
>    busy-waits for a long time in normal operation.
> - enabling the tx interrupt causes one immediately on non-broken uarts
> - the interrupt handler is normally called immediately.  Then it always
>    blocks on uart_lock()
> - then the main code fills the fifo and unlocks
> - then the interrupt handler runs.  It normally finds that the fifo is
>    not empty (since it has just been filled) and does nothing
> - another tx interrupt occurs later and the interrupt handler runs again.
>    It normally doesn't hit the lock again, and normally finds the fifo
>    empty, so it does something.

You correctly describe what happens at r295556 with a non-broken xx50.
That revision causes a spurious interrupt with non-broken xx50 but
also ensures that the relevant TX interrupt isn't missed with broken
xx50 that do not issue an interrupt when enabling IER_ETXRDY. Besides,
as you say, the general approach of dynamically enabling TX interrupts
works around the common brokenness of these interrupts no longer going
away when they should.

> But you are probably correct that a 1-byte write to the fifo often
> loses the race.  This depends on how fast the hardware moves the byte
> from the fifo to the tx register.  Actually, since we didn't wait
> for the tx register to become empty, it will often take a full character
> time before the move.  After that, I think it might take 1 bit time but
> no more.

My concern is that with r295557, when this race is lost no TX interrupt
is seen at all with broken xx50 that do not trigger an interrupt when
enabling IER_ETXRDY.

Marius



More information about the svn-src-all mailing list