Patch pps-gpio for PREEMPT_RT
Do this if: you run PPS from a GPIO pin on a PREEMPT_RT kernel. Which is to say — do this if you followed any realtime-kernel time-server guide. Why.
You do not need to rebuild the whole kernel. pps-gpio is a module.
1. Confirm you have the problem
Section titled “1. Confirm you have the problem”$ uname -a | grep -o PREEMPT_RTPREEMPT_RT
$ ps -eo pid,class,rtprio,psr,comm | grep irq/.*pps 239 RR 50 3 irq/41-pps@12.-1 ← the handler is a thread. That's the bug.If that ps prints nothing, your handler is already in hard-IRQ context and you
have nothing to fix.
2. Patch
Section titled “2. Patch”In your kernel source tree, drivers/pps/clients/pps-gpio.c, in
get_irqf_trigger_flags(), just before the return:
/* The handler timestamps the pulse, so it has to run in hard-irq * context. Under PREEMPT_RT it would otherwise be force-threaded and * the timestamp taken after thread wakeup latency, adding microseconds * of jitter to an edge that should be good to nanoseconds. */ flags |= IRQF_NO_THREAD;
return flags;3. Build just the module
Section titled “3. Build just the module”make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \ M=drivers/pps/clients modulesAbout a minute, versus ~40 for a full kernel.
4. Install and reboot
Section titled “4. Install and reboot”scp drivers/pps/clients/pps-gpio.ko pi@host:/tmp/ssh pi@host 'sudo install -m644 /tmp/pps-gpio.ko \ /lib/modules/$(uname -r)/kernel/drivers/pps/clients/pps-gpio.ko && \ sudo depmod -a && sudo reboot'5. Verify
Section titled “5. Verify”$ ps -eo pid,class,rtprio,psr,comm | grep irq/.*pps(nothing — back in hard-irq context)Then measure it. You should see roughly a 3× improvement in raw PPS jitter, and about a 10× improvement in chrony’s RMS offset.