On 2024-11-04, Jiri Slaby <jirislaby@xxxxxxxxxx> wrote: > Instead of looping fifosize multiplied by random timeout, can we > re-use port->frame_time? Rather than 10k loops, we could loop (port->frame_time * some_scaled_padding) / 1000 times. The padding is important because we should not timeout in the normal scenario. Perhaps using ~2 as @some_padding. Something like: port->frame_time >> 9 ? >> The difference between THRE and TEMT is the state of the shift register >> only[2]: >> >> "In the FIFO mode, TEMT is set when the transmitter FIFO and shift >> register are both empty." > > But what's the purpose of spinning _here_? The kernel can run and > FIFO too. Without the kernel waiting for the FIFO. > > If we want to wait for fifo to empty, why not *also* the TSR. Meaning: > > Did you want UART_LSR_TEMT? Let us assume we have a line with 640 characters and a FIFO of 64 bytes. For this line, we must wait for the FIFO to empty 10 times. It is enough to wait for THRE for each of the 64-byte blocks because we are only interested in refilling the FIFO at this point. Only at the very end (in the caller... serial8250_console_write()) do we need to wait for everything to flush to the wire (TEMT). By waiting on TEMT for each of the 64-byte blocks, we are waiting longer than necessary. This creates a small window where the FIFO is empty and there is nothing being transmitted. I did a simple test on my beaglebone-black hardware, sending 100 lines of 924 bytes at 9600 bps. Since my hardware uses a 64-byte FIFO, each line would have 14 such windows. And indeed, waiting for TEMT rather than only THRE for the 64-byte blocks resulted in an extra 30ms total transfer for all 92400 bytes. That is about 20us lost in each window by unnecessarily waiting for TEMT. Of course, we are only talking about console output, which is horribly inefficient on system resources. But I would argue, if we do not care about unnecessary waiting, then why even have the FIFO optimization in the first place? John