Horloge matérielle (PHC) et phc2sys#
Pourquoi#
Même avec un noyau temps réel bien configuré, un timestamp logiciel (pris au moment où le kernel traite le paquet) accumule 10 à 100 µs de latence non-déterministe entre l’arrivée physique du signal sur le câble réseau et le moment où le timestamp est réellement enregistré : réception PHY, DMA vers la RAM, interruption, traversée de la pile réseau. Pour servir des clients avec une précision meilleure que la dizaine de microsecondes, il faut sortir cette latence de l’équation, en demandant à la carte réseau elle-même d’horodater le paquet, avant tout traitement logiciel.
Comment#
Le PHC (PTP Hardware Clock)#
Le contrôleur réseau du Raspberry Pi 5 expose une horloge matérielle
dédiée accessible via /dev/ptp0, le PHC, standardisé par IEEE 1588.
Chrony peut l’utiliser directement pour horodater les paquets NTP entrants
et sortants au niveau du silicium, indépendamment de la latence du noyau.
# Dans chrony.conf
hwtimestamp end0 rxfilter all txcomp 0 rxcomp 0 minpoll 0hwtimestamp end0 seul est incomplet : sans ces options explicites,
chrony doit deviner les meilleurs réglages, ce qui ne fonctionne pas
toujours de façon fiable. rxfilter all demande d’horodater tous les
paquets reçus au niveau matériel, pas seulement ceux reconnus comme PTP
par le filtre du contrôleur (sans quoi le trafic NTP ordinaire ne
bénéficierait pas du timestamp matériel). txcomp 0 active l’horodatage
matériel à la complétion de l’émission, sans compensation logicielle
additionnelle (0). rxcomp 0 fait de même en réception : aucune
correction n’est appliquée après coup, le timestamp matériel brut est pris
tel quel. minpoll 0 n’impose aucun plancher artificiel à la fréquence de
mesure au-delà du grain standard de 2⁰ = 1 seconde.
phc2sys : maintenir le PHC aligné#
Le PHC a besoin d’être maintenu synchronisé sur l’horloge système (qui,
elle, est disciplinée par chrony depuis le PPS). C’est le rôle de
phc2sys, du paquet linuxptp :
cat > /etc/systemd/system/phc2sys-chrony.service <<'EOF'
[Unit]
Description=Synchronize PHC to system clock
After=chrony.service
Wants=chrony.service
[Service]
Type=simple
ExecStart=/usr/sbin/phc2sys -s CLOCK_REALTIME -c /dev/ptp0 -O 0 -R 1 -q
Restart=always
RestartSec=5
CPUSchedulingPolicy=fifo
CPUSchedulingPriority=90
CPUAffinity=1
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now phc2sys-chrony.service-s CLOCK_REALTIME désigne l’horloge système (disciplinée par chrony
depuis le PPS) comme source de référence pour le PHC, -c /dev/ptp0 la
cible à aligner. -O 0 fixe l’offset TAI-UTC à zéro : ce n’est pas un
oubli des secondes intercalaires, c’est chrony (via leap-seconds.list,
chapitre dédié) qui gère déjà cet aspect, phc2sys n’a pas à le refaire
en double. -q (quiet) supprime la journalisation par défaut, sans quoi
le tmpfs /var/log (chapitre Système de fichiers) se remplirait
rapidement d’une ligne par mesure.
Erreurs à éviter#
Requires=chrony.servicecasse silencieusementphc2sysen production. Une dépendance systemdRequires=arrête automatiquement le service dépendant à chaque transition d’état de sa dépendance, y compris un simple redémarrage ou un échec temporaire de chrony. Un incident réel sur ce projet :phc2syss’arrêtait silencieusement à chaque cycle de chrony, laissant le PHC dériver de 94 µs par seconde sans aucune alerte visible. La solution :Wants=chrony.service(une dépendance souple, qui n’entraîne pas d’arrêt en cascade), combiné àRestart=alwayspour la résilience en cas de crash réel.
La fréquence de mesure
-Rdephc2sysdoit être réduite, pas maximisée. Le PHC est un compteur matériel unique, lu et écrit simultanément par deux processus concurrents :phc2sysqui l’écrit pour le maintenir aligné, etchronyqui le lit pour horodater les paquets entrants. Le pilote réseau ne sérialise pas explicitement ces accès. Mesures en conditions réelles : à-R 16(valeur par défaut delinuxptp), seulement 63% des paquets reçoivent un timestamp matériel (le reste bascule silencieusement sur un timestamp logiciel, moins précis) ; à-R 1, ce taux monte à 86%. Réduire la fréquence d’écriture réduit la contention, au prix d’un offset PHC marginalement plus élevé, mais qui reste largement sous la microseconde.
- S’attendre à un horodatage matériel TX proche de 100%. Sur Pi 5, le
pilote réseau ne pose le flag matériel nécessaire à l’horodatage TX que
pour les paquets reconnus comme PTP par le filtre matériel, les paquets
NTP “normaux” n’en bénéficient pas. C’est un bug documenté du pilote
(
raspberrypi/linux, issue #5904), pas une erreur de configuration : le taux d’horodatage matériel TX reste proche de 0% quelle que soit la configuration. L’impact réel côté client est modeste (quelques dizaines de microsecondes au pire, largement filtré par la PLL du client).
Vérifier#
# Le PHC doit être détecté sur l'interface
ethtool -T end0
# Doit afficher "PTP Hardware Clock: 0" (ou un autre numéro, pas "none")
# Offset instantané entre le PHC et l'horloge système
phc_ctl /dev/ptp0 cmp
# ex : "offset from CLOCK_REALTIME is 14ns"Une lecture unique de
phc_ctl cmpest un instantané non filtré, donc parfois sujet à un pic ponctuel d’ordonnancement (quelques centaines de ns à quelques µs). Pour un diagnostic fiable, mieux vaut répéter la lecture plusieurs fois avec une priorité temps réel (chrt -f 99) et prendre la médiane, exactement la même logique de filtrage statistique qu’utilise chrony pour le PPS (chapitre Chrony).
# Taux d'horodatage matériel effectif, côté chrony
chronyc -h /run/chrony/chronyd.sock serverstats | grep -i hardware📚 Pour aller plus loin
Le timestamping matériel est standardisé par IEEE 1588 (Precision Time Protocol, dernière révision 2019). Linux l’expose via l’option de socket
SO_TIMESTAMPING(depuis le noyau 2.6.30) : quand chrony activehwtimestamp end0, il demande au noyau, viasetsockopt(), que les timestamps de réception et d’émission soient pris directement dans le silicium de la carte réseau plutôt que dans la pile logicielle, une précision typique inférieure à 100 ns une fois la contention PHC/chrony maîtrisée (mesures publiées par M. Lichvar, mainteneur de chrony, Linux.conf.au 2020).