[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250513144615.252881431@linutronix.de>
Date: Tue, 13 May 2025 17:12:54 +0200 (CEST)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: netdev@...r.kernel.org,
Richard Cochran <richardcochran@...il.com>,
Christopher Hall <christopher.s.hall@...el.com>,
David Zage <david.zage@...el.com>,
John Stultz <jstultz@...gle.com>,
Frederic Weisbecker <frederic@...nel.org>,
Anna-Maria Behnsen <anna-maria@...utronix.de>,
Miroslav Lichvar <mlichvar@...hat.com>,
Werner Abt <werner.abt@...nberg-usa.com>,
David Woodhouse <dwmw2@...radead.org>,
Stephen Boyd <sboyd@...nel.org>,
Thomas Weißschuh <thomas.weissschuh@...utronix.de>,
Kurt Kanzenbach <kurt@...utronix.de>,
Nam Cao <namcao@...utronix.de>,
Alex Gieringer <gieri@...utronix.de>
Subject: [patch 00/26] timekeeping: Provide support for independent PTP
timekeepers
The kernel supports PTP clocks pretty well at the hardware level and the
ability to steer the core time keeper, but there is a major gap for other
PTP use cases especially in the context of TSN.
TSN use cases in automation, automotive, audio and other areas utilize PTP
for synchronizing nodes in a network accurately, but the underlying master
clock is not necessarily related to clock TAI. They are completely
independent and just represent a common notion of time in a network for an
application specific purpose. This comes with problems obvioulsy:
1) Applications have no fast access to the time of such independent PTP
clocks. The only way is to utilize the file descriptor of the PTP
device with clock_gettime(). That's slow as it has to go all the way
out to the hardware.
2) The network stack cannot access PTP time at all because accessing the
PTP hardware requires preemptible task context in quite some cases.
There has been attempts to solve this by creating a new PTP specific
infrastructure independent of the core timekeeping code, but that's a
patently bad idea as it would just create duplicated code with new bugs and
also be in the way of supporting these clocks in the VDSO and hrtimers
based on such clocks down the road.
This series addresses the timekeeping part by utilizing the existing
timekeeping and NTP infrastructure, which has been prepared for
multi-instance in recent kernels.
The approach is the same as for core timekeeping:
The clock readout uses the system clocksource, e.g. TSC, ARM
architected timer..., and converts it to a "nanoseconds" timestamp with
the underlying conversion factors.
The conversion factors are steered via clock_adjtimex(2) to provide the
required accuracy. That means tools like chrony can be reused with a
small amount of modifications.
The infrastructure supports up to eight independent PTP clocks, which can
be accessed by the new CLOCK_PTP0 .. CLOCK_PTP7 POSIX clock IDs.
The timekeepers are off by default and can be individually enabled/disabled
via a new sysfs interface. In the disabled case the overhead introduced by
these timekeepers is practically zero. Only if enabled, the periodic update
in the timekeeper tick adds extra work.
The infrastructure provides:
1) In-kernel time getter interfaces similar to the existing
ktime_get*() interfaces. The main difference is that they have a
boolean return value, which indicates whether the clock is enabled
and valid. These interfaces are lockless and sequence count
protected as the other ktime_get*() variants, so the same
restrictions apply (not usable from the timekeeper context or from
NMI).
2) clock_gettime() support
Same as the existing clock_gettime() for CLOCK_..., but returns
-ENODEV if the clock is disabled.
3) clock_settime() support
Same as clock_settime(CLOCK_REALTIME), but does not affect the
system timekeeping
4) clock_adjtime() support
Same as clock_settime(CLOCK_REALTIME), but does not affect the
system timekeeping. It has some restrictions: no support for PPS,
leap seconds and other tiny details which are only relevant for
CLOCK_REALTIME steering.
The timekeeper updates for these independent PTP clocks are not yet
propagated to VDSO and paravirt interfaces as this has to be addressed
separately once the core infrastructure is in place. Thomas W. has a
prototype implementation for the VDSO support ready, which will be posted
once the dust has settled here.
The sysfs control interface is a subject for discussion as it might make
sense to couple the clock enablement with the PTP clock subsystem, but this
can be handled in user space too. The proposed sysfs interface allows to
utilize this series without any other prerequisites and provides a high
degree of flexibility for creating other use cases of independent clocks
aside of the obvious PTP case.
Once the timekeeping infrastructure is in place, the road is paved for
supporting hrtimers on these clocks, which is another problem in the
context of applications and the network stack. The idea is to convert the
independent expiry time to clock MONOTONIC internally under the assumption
that both involved clocks will have halfways stable conversion factors
within the expiry time of the timer. If one of the clocks starts to jump
around via their respective clock_adjtime(2) steering, then there are
bigger problems to solve than a timer expiring late. But that's just an
concept in my head and on some scribbled notes. It will take some time to
materialize. But let's get the timekeeping part sorted first. :)
The series applies on top of 6.15-rc6 + tip timers/core and is available
from git:
git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git timers/ptp/clocks
Thanks,
tglx
---
Documentation/ABI/stable/sysfs-kernel-time-ptp | 6
include/linux/timekeeper_internal.h | 28 +
include/linux/timekeeping.h | 17
include/uapi/linux/time.h | 10
kernel/time/Kconfig | 3
kernel/time/ntp.c | 72 +--
kernel/time/ntp_internal.h | 13
kernel/time/posix-timers.c | 3
kernel/time/posix-timers.h | 1
kernel/time/timekeeping.c | 576 +++++++++++++++++++++----
kernel/time/timekeeping_internal.h | 3
11 files changed, 615 insertions(+), 117 deletions(-)
Powered by blists - more mailing lists