Open teodly opened 6 months ago
Linux doesn't really support virtual clocks in the way you suggest here, so I am not sure whether this would be useful in the linux binary. As for when using statime as a library, since you are already required to provide the clock type this should be perfectly possible within the current feature set, so not sure what would be needed in addition there, perhaps you could elaborate on what exactly it is you would like to see added?
AFAIK virtual clocks (ptp_vclock) can indeed be implemented for network interfaces in their driver, but not really accessible as an available module and UAPI.
Yes, custom implementation of statime::Clock
should suffice. I was just thinking of making it available in statime
crate out-of-the-box. But it can be implemented in its own crate as well.
Hmmm, not really sure how that would work in a platform independent way (it still needs some sort of clock as basis) but let me know once you have something to review.
Here's the implementation. It's so simple since I'm relying on filters already implemented in Statime.
Other changes are necessary for:
That does look really interesting, particularly the library changes seem quite close to mergeable. We would need to discuss the extra dependency but that is not too hard to work around. If you would like to open a PR I would be interested.
The changes to statime-linux require some more discussion I think, primarily because we would then want that to be configurable, and we should probably have more options than just the current behaviour and what you provided, but I think we should have time soon to look into that.
I have a similar use-case for supporting ptp with ARB timescale. In my case the only available ptp hardware clock on the hardware is already in use for synchronizing the system clock. I really like the idea of the overlay clock, but I would like to keep the ARB time monotonic and avoid jumps caused by sync of the underlying clock. While this might not be possible with software timestamps it might work with virtual ptp clocks. Device not supporting this could still use the overlay clock, but should not be selected as a master clock. Detecting time jumps in the overlay clock and re-syncing should be doable.
After experimenting with it, I'm not sure whether CLOCK_TAI is a good base for overlay clocks. CLOCK_MONOTONIC seems to be better since it won't be updated by NTP. But it's not supported by clock_steering
crate (and adding it doesn't make sense, because it can't be set).
As @cmeissl pointed out, the kernel already supports virtual clocks for PHC.
So to cover the use case of keeping system time independent from PTP time, my implementation of OverlayClock would need to be changed to use CLOCK_MONOTONIC. Does supporting other clocks as underlying clocks make sense?
I would have no problems with adding something like CLOCK_MONOTONIC to the clock_steering crate if it is necessary or useful. That crate is primarily intended for internal consumption anyway and I could live with the slight rough edges this introduces.
BTW, note that CLOCK_MONOTONIC is still steered by ntp in terms of frequency. For this particular usecase, perhaps CLOCK_MONOTONIC_RAW is even better, as that doesn't even include frequency steering.
Currently and in upcoming weeks and months I have some time to work on it. I've started looking at improving my patch, making it possible to use CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW as the underlying clock. Let me know if I'm thinking correctly about these considerations:
clock_steering::unix::UnixClock::system_offset
always returns system timestamps from CLOCK_REALTIME. We're accounting for it by adding TAI-REALTIME offset.
clock_task
is not run at all because there is only one clock - system clock. Instead, timestamps in REALTIME timescale are converted to TAI for measurement purposes. If we're running as a slave, CLOCK_REALTIME is adjusted (implicitly adjusting CLOCK_TAI).
To sum up, we need a way of converting timestamps from CLOCK_REALTIME timescale to our virtual clock's timescale, but it isn't as easy as shifting and scaling I've already implemented because the underlying clock is different (in practice it is also shifting and scaling but the parameters are hidden in the kernel).
Do we need to measure the MONOTONIC_RAW-REALTIME offset and frequency drift? Have separate clock_task
for that? That looks unnecessarily complex and prone to jitter. Do you see better ways of doing it?
Most of it seems sensible, however in situations lacking support for comparing directly with CLOCK_MONOTONIC_RAW, I think the best solution is just to build a virtual clock on CLOCK_REALTIME, imperfect though it may be. You are probably right that doing separate tracking of the difference between monotonic_raw and realtime is jitterprone, probably to the point that it won't actually provide performance benefits over using realtime directly.
Sometimes we don't want to synchronize the system clock to PTP time source.
It's the case in local audiovisual networks - a device with low jitter clock becomes the master but often it isn't connected to the Internet or GPS so it can't be used as a source of time of day. If I understand correctly, in PTP it's called arbitrary timescale.
Statime used as a library could maintain internal clock, phase-locked to the system TAI clock, with timestamp offset and frequency factor changing according to PTP measurements. System TAI clock would be only read.
Network interface clock (
/dev/ptp0
) could also be used since it's independent from system clock, but we also need a fallback for NICs without hardware timestamping.I will start working on it soon since I need it in my unofficial Dante implementation - Inferno.