[Bug 240121] Serial console can eat a lot of CPU with low baudrate

Bruce Evans brde at optusnet.com.au
Thu Aug 29 10:18:15 UTC 2019


On Mon, 26 Aug 2019 a bug that doesn't want replies at freebsd.org wrote:

> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=240121
>
> That effect is unexpected to me.  I would expect opposite -- reduction of wait
> time, since code reduces number of buffer flushes and utilizes hardware FIFO.
> I may need to reproduce it to understand the issue.

uart already made dubious use of the fifo for serial consoles.  sio is more
careful, and reinitializes essentially the whole hardware device for every
character, as needed to work when the device is in an inderterminate of
unwanted active state.  For this, it is best to not use the fifo at all.

I see the following problems in the uart serial console code:
- can wait forever if hardware flow control is active (requires a 16650+ in
   if the uart is an xx50+).  But hardware flow control never worked even
   for sio (except in my uncomitted version of sio), and is hard-coded turned
   off for uart in the driver, and may also be locked off in the lock state
   device, and is also hard-coded-fixated off in some versions of uart.
- the previous version of uart has a 1 second timeout for the shift register
   (spelled LSR_TEMT) being empty.  I don't know if this bit really works for
   showning that the whole tx is empty.  The 1 second timeout is clearly
   wrong, and might be the reason for this PR -- it is too short, so gave
   wrong behaviour but less overhead.  E.g., at the PR speed of only 2400 bps,
   it takes about 1/240 second per character, so if the fifo size is > 240
   then data might be lost.  More likely, the fifo size is 128 an there was
   no data loss and less waiting for the fifo in the previous version.  I
   test sio down to 2 bps so would see large data loss with a 1 byte fifo
   (holding register) with a 1 second timeout.  My version of sio avoids
   such problems by using infinite timeouts not only for itself, but for
   things like spinlocks while console output is in progress.  Testing at
   2 bps is a good way to find timing problems.
- now for tx fifo size 1, you removed the 1 second timeout, but only wait
   for the holding register to become empty.  I don't like that.  Oops, my
   version of sio still has a 1 second timeout. but waits for the shift
   register to become empty too.  It waits before and after txing each char
   as needed for switching the mode on each char.
- now for tx fifo size > 1, the timeout is done differently.  That looks
   more like the cause of the slowness.  After finding the device busy, the
   device state was checked after about 4 usec.  Now the granularity of the
   check is supposed to be 1/10 of a character time = 1/2400 = 416 usec at
   2400 bps.
- after filling the fifo or holding register, uart still doesn't wait.  The
   code is too complicated for me.

>
> What UART hardware are you using?  Does it have FIFO?

Bruce


More information about the freebsd-bugs mailing list