Date: Thu, 29 Aug 2019 20:18:04 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Alexander Motin <mav@FreeBSD.org> Cc: bugs@FreeBSD.org, nicolas.masse@stormshield.eu Subject: Re: [Bug 240121] Serial console can eat a lot of CPU with low baudrate Message-ID: <20190829185320.Y2032@besplex.bde.org> In-Reply-To: <bug-240121-227-8aJdQnzRoh@https.bugs.freebsd.org/bugzilla/> References: <bug-240121-227@https.bugs.freebsd.org/bugzilla/> <bug-240121-227-8aJdQnzRoh@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 26 Aug 2019 a bug that doesn't want replies@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20190829185320.Y2032>