Skip to content

Final configuration

/etc/chrony/conf.d/gps.conf
# Coarse NMEA time from gpsd. Labels WHICH second it is. Never the time source.
refclock SHM 0 refid GPS precision 1e-1 offset 0.0 delay 0.2 poll 3 noselect
# Kernel PPS: the precise source. Median-filter 10 pulses, lock to GPS for
# second-numbering, prefer it as the reference.
refclock PPS /dev/pps0 refid PPS precision 1e-9 poll 2 lock GPS filter 10 prefer
allow 10.0.0.0/8

Plus, in chrony.conf:

user root # needed to read gpsd's SHM segments (mode 0600, root-owned)
/etc/default/gpsd
START_DAEMON="true"
USBAUTO="false"
DEVICES="/dev/ttyAMA0"
GPSD_OPTIONS="-n" # -n = poll immediately. NEVER pin the baud with -s.
Terminal window
systemctl enable gpsd.service # NOT just gpsd.socket — see below
isolcpus=2,3 irqaffinity=0,1 nohz=off cpuidle.off=1 skew_tick=1

cpu0 is sacred — it holds the PPS interrupt.

chrony.service.d/affinity.conf
[Service]
CPUSchedulingPolicy=rr
CPUSchedulingPriority=20
CPUAffinity=2
# gpsd.service.d/affinity.conf
[Service]
CPUAffinity=3
# everything else (dashboard, Caddy, exporters, cron…)
[Service]
CPUAffinity=1
Nice=10