Using an oscilloscope and toggling some pins I sometimes see latencies of 1-2 seconds from when an 8-byte UART packet is transmitted to when a blocking read returns. The packets are 1 second part with a few milliseconds of jitter. I also measured timing to the system calls (see below) using strace and the results agreed with my I/O measurements.
I'm trying to determine if this latency is in the UART driver or if other tasks are bumping my task which has a niceness value of -20. The reason I'm wondering about the driver is that an earlier version of this code reliably used the UART to transmit packets that were ~26 kB each second (the driver buffer is 4 kB).
The process is a Python script that is using pyserial. In this failing case strace reports the time between epoll_wait and clock_gettime as more than 3 seconds.
0.000883 epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=8589934599}}) = -1 EEXIST (File exists)
0.000681 clock_gettime(CLOCK_MONOTONIC, {92406, 209555006}) = 0
0.000655 epoll_wait(3, {}, 64, 98) = 0
3.004082 clock_gettime(CLOCK_MONOTONIC, {92409, 214251206}) = 0
The repeated actions are: Receive 8-byte packet to request Linux to read N number of bytes via SPI. Perform the SPI. Read 8-byte packet to see if the SPI request completed successfully. The SPI transfer takes about 40 ms. The healthy pattern is ~40 ms between request packet and result packet. And ~960 ms until it receives the next request.
Duchess: strace -r -e read -p 7564
Process 7564 attached
0.000000 read(7, "\355\336\255\336\20d\0\0", 8) = 8
0.049142 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
0.950381 read(7, "\355\336\255\336\20d\0\0", 8) = 8
0.050035 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
0.949962 read(7, "\355\336\255\336\20d\0\0", 8) = 8
0.049601 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
0.950417 read(7, "\355\336\255\336\20d\0\0", 8) = 8
0.049654 read(7, "\255\336\355\336\1\0\0\0", 8) = 8
0.950507 read(7, "\355\336\255\336\20d\0\0", 8) = 80.950516 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
0.049944 read(7, "\255\336\355\336\1\0\0\0", 8) = 8 [Success]
2.196903 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
0.048876 read(7, "\255\336\355\336\0\0\0\0", 8) = 8 [Failure]
0.015570 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
0.053889 read(7, "\255\336\355\336\0\0\0\0", 8) = 8 [Failure]
0.634720 read(7, "\355\336\255\336\20d\0\0", 8) = 8 [SPI Request]
0.050070 read(7, "\255\336\355\336\1\0\0\0", 8) = 8 [Success]