From: Christopher S. Hall <hidden> Date: 2015-08-22 01:52:52
6th generation Intel platforms will have an Always Running
Timer (ART) that always runs when the system is powered and
is available to both the CPU and various on-board devices.
Initially, those devices include audio and network. The
ART will give these devices the capability of precisely
cross timestamping their local device clock with the system
clock. The ART is precisely related to the TSC by a ratio
read from CPUID leaf 0x15.
A device (such as the network controller) produces cross timestamps in
terms of the ART and the local device clock. The ART value on its
own isn't useful.
The first two patches enable translation of ART to system time.
The first patch adds the correlated clocksource concept which is
an auxiliary clock directly relate-able to a clock registered as
a clocksource. The second patch adds the Intel specific ART
correlated clocksource.
The last two patches modify the PTP character driver to call a
cross timestamp function (getsynctime()) in the driver when
available and perform the cross timestamp in the e1000e driver.
The patches taken together enable sub-microsecond cross timestamps
between the system clock and network device clock
Changelog since v2:
Split out x86 architecture specific code from common timekeeping code
additions
Split ART initialization between early TSC initialization and TSC
frequency refinement. Now, cpu_has_art can be used in
driver initialization code
Added e1000e PTP init code that detects presence of ART/spt disabling
cross timestamp if they're not available
Added additional commenting in TSC/ART init code, minor renaming of
functions and variables for greater clarity
Fixed a few formatting problems in e1000e driver patch
Christopher Hall (2):
Add support for driver cross-timestamp to PTP_SYS_OFFSET ioctl
Enabling hardware supported PTP system/device crosstimestamping
Christopher S. Hall (2):
Add correlated clocksource deriving system time from an auxiliary
clocksource
Added ART correlated clocksource and ART CPU feature
Documentation/ptp/testptp.c | 6 +-
arch/x86/include/asm/cpufeature.h | 3 +-
arch/x86/include/asm/tsc.h | 2 +
arch/x86/kernel/tsc.c | 54 ++++++++++++++++++
drivers/net/ethernet/intel/e1000e/defines.h | 5 ++
drivers/net/ethernet/intel/e1000e/ptp.c | 88 +++++++++++++++++++++++++++++
drivers/net/ethernet/intel/e1000e/regs.h | 4 ++
drivers/ptp/ptp_chardev.c | 29 +++++++---
include/linux/clocksource.h | 33 +++++++++++
include/linux/ptp_clock_kernel.h | 7 +++
include/linux/timekeeping.h | 4 ++
include/uapi/linux/ptp_clock.h | 4 +-
kernel/time/timekeeping.c | 65 +++++++++++++++++++++
13 files changed, 292 insertions(+), 12 deletions(-)
--
2.1.4
From: Christopher S. Hall <hidden> Date: 2015-08-22 01:53:22
From: Christopher Hall <redacted>
This patch allows system and device time ("cross-timestamp") to be
performed by the driver. Currently, the cross-timestamping is performed
in the PTP_SYS_OFFSET ioctl. The PTP clock driver reads gettimeofday()
and the gettime64() callback provided by the driver. The cross-timestamp
is best effort where the latency between the capture of system time
(getnstimeofday()) and the device time (driver callback) may be
significant.
This patch adds an additional callback getsynctime64(). Which will be
called when the driver is able to perform a more accurate, implementation
specific cross-timestamping. For example, future network devices that
implement PCIE PTM will be able to precisely correlate the device clock
with the system clock with virtually zero latency between captures.
This added callback can be used by the driver to expose this functionality.
The callback, getsynctime64(), will only be called when defined and
n_samples == 1 because the driver returns only 1 cross-timestamp where
multiple samples cannot be chained together.
This patch also adds to the capabilities ioctl (PTP_CLOCK_GETCAPS),
allowing applications to query whether or not drivers implement the
getsynctime callback, providing more precise cross timestamping.
Commit Details:
Added additional callback to ptp_clock_info:
* getsynctime64()
This takes 2 arguments referring to system and device time
With this callback drivers may provide both system time and device time
to ensure precise correlation
Modified PTP_SYS_OFFSET ioctl in PTP clock driver to use the above
callback if it's available
Added capability (PTP_CLOCK_GETCAPS) for checking whether driver supports
cross timestamping
Added check for cross timestamping flag to testptp.c
Signed-off-by: Christopher S. Hall <redacted>
---
Documentation/ptp/testptp.c | 6 ++++--
drivers/ptp/ptp_chardev.c | 29 +++++++++++++++++++++--------
include/linux/ptp_clock_kernel.h | 7 +++++++
include/uapi/linux/ptp_clock.h | 4 +++-
4 files changed, 35 insertions(+), 11 deletions(-)
@@ -124,7 +124,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)structptp_clock*ptp=container_of(pc,structptp_clock,clock);structptp_clock_info*ops=ptp->info;structptp_clock_time*pct;-structtimespec64ts;+structtimespec64ts,systs;intenable,err=0;unsignedinti,pin_index;
@@ -138,6 +138,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)caps.n_per_out=ptp->info->n_per_out;caps.pps=ptp->info->pps;caps.n_pins=ptp->info->n_pins;+caps.cross_timestamping=ptp->info->getsynctime64!=NULL;if(copy_to_user((void__user*)arg,&caps,sizeof(caps)))err=-EFAULT;break;
@@ -196,19 +197,31 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)break;}pct=&sysoff->ts[0];-for(i=0;i<sysoff->n_samples;i++){-getnstimeofday64(&ts);+if(ptp->info->getsynctime64&&sysoff->n_samples==1&&+ptp->info->getsynctime64(ptp->info,&ts,&systs)==0){+pct->sec=systs.tv_sec;+pct->nsec=systs.tv_nsec;+pct++;pct->sec=ts.tv_sec;pct->nsec=ts.tv_nsec;pct++;-ptp->info->gettime64(ptp->info,&ts);+pct->sec=systs.tv_sec;+pct->nsec=systs.tv_nsec;+}else{+for(i=0;i<sysoff->n_samples;i++){+getnstimeofday64(&ts);+pct->sec=ts.tv_sec;+pct->nsec=ts.tv_nsec;+pct++;+ptp->info->gettime64(ptp->info,&ts);+pct->sec=ts.tv_sec;+pct->nsec=ts.tv_nsec;+pct++;+}+getnstimeofday64(&ts);pct->sec=ts.tv_sec;pct->nsec=ts.tv_nsec;-pct++;}-getnstimeofday64(&ts);-pct->sec=ts.tv_sec;-pct->nsec=ts.tv_nsec;if(copy_to_user((void__user*)arg,sysoff,sizeof(*sysoff)))err=-EFAULT;break;
@@ -51,7 +51,9 @@ struct ptp_clock_caps {intn_per_out;/* Number of programmable periodic signals. */intpps;/* Whether the clock supports a PPS callback. */intn_pins;/* Number of input/output pins. */-intrsv[14];/* Reserved for future use. */+/* Whether the clock supports precise system-device cross timestamps */+intcross_timestamping;+intrsv[13];/* Reserved for future use. */};structptp_extts_request{
From: Christopher S. Hall <hidden> Date: 2015-08-22 01:53:24
From: Christopher Hall <redacted>
Add getsynctime() PTP device callback to cross timestamp system device
clock using ART translation depends on platform being >= SPT
and having ART
getsynctime() reads ART (TSC-derived)/device cross timestamp and
converts to realtime/device time reporting cross timestamp to
PTP driver
Signed-off-by: Christopher S. Hall <redacted>
---
drivers/net/ethernet/intel/e1000e/defines.h | 5 ++
drivers/net/ethernet/intel/e1000e/ptp.c | 88 +++++++++++++++++++++++++++++
drivers/net/ethernet/intel/e1000e/regs.h | 4 ++
3 files changed, 97 insertions(+)
@@ -236,6 +320,10 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)break;}+/* CPU must have ART and GBe must be from Sunrise Point or greater */+if(hw->mac.type<e1000_pch_spt||!cpu_has_art)+adapter->ptp_clock_info.getsynctime64=NULL;+INIT_DELAYED_WORK(&adapter->systim_overflow_work,e1000e_systim_overflow_work);
From: Christopher S. Hall <hidden> Date: 2015-08-22 01:53:25
Add detect_art() call to early TSC initialization which reads ART->TSC
numerator/denominator and sets CPU feature if present
Add convert_art_to_tsc() function performing conversion ART to TSC
Add art_timestamp referencing art_to_tsc() and clocksource_tsc enabling
driver conversion of ART to TSC
Signed-off-by: Christopher S. Hall <redacted>
---
arch/x86/include/asm/cpufeature.h | 3 ++-
arch/x86/include/asm/tsc.h | 2 ++
arch/x86/kernel/tsc.c | 54 +++++++++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+), 1 deletion(-)
From: Christopher S. Hall <hidden> Date: 2015-08-22 01:53:27
Add struct correlated_cs with pointer to original clocksource and
function pointer to convert correlated clocksource to the original
Add get_correlated_timestamp() function which given specific correlated_cs
and correlated_ts convert correlated counter value to system time
Signed-off-by: Christopher S. Hall <redacted>
---
include/linux/clocksource.h | 33 +++++++++++++++++++++++
include/linux/timekeeping.h | 4 +++
kernel/time/timekeeping.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+)
@@ -312,6 +312,19 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)returnnsec+arch_gettimeoffset();}+staticinlines64timekeeping_convert_to_ns(structtk_read_base*tkr,+cycle_tcycles)+{+cycle_tdelta;+s64nsec;++/* calculate the delta since the last update_wall_time */+delta=clocksource_delta(cycles,tkr->cycle_last,tkr->mask);++nsec=delta*tkr->mult+tkr->xtime_nsec;+returnnsec>>tkr->shift;+}+/***update_fast_timekeeper-UpdatethefastandNMIsafemonotonictimekeeper.*@tkr:Timekeepingreadoutbasefromwhichwetaketheupdate
@@ -885,6 +898,58 @@ EXPORT_SYMBOL(getnstime_raw_and_real);#endif /* CONFIG_NTP_PPS *//**+*get_correlated_timestamp-Getacorrelatedtimestamp+*+*Readsatimestampfromadeviceandcorrelatesittosystemtime+*/+intget_correlated_timestamp(structcorrelated_ts*crt,+structcorrelated_cs*crs)+{+structtimekeeper*tk=&tk_core.timekeeper;+unsignedlongseq;+cycles_tcycles;+ktime_tbase;+s64nsecs;+intret;++do{+seq=read_seqcount_begin(&tk_core.seq);+/*+*Verifythatthecorrelatedclocksoureisrelatedto+*thecurrentlyinstalledtimekeeperclocksoure+*/+if(tk->tkr_mono.clock!=crs->related_cs)+return-ENODEV;++/*+*Trytogetatimestampfromthedevice.+*/+ret=crt->get_ts(crt);+if(ret)+returnret;++/*+*Convertthetimestamptotimekeeperclockcycles+*/+cycles=crs->convert(crs,crt->system_ts);++/* Convert to clock realtime */+base=ktime_add(tk->tkr_mono.base,+tk_core.timekeeper.offs_real);+nsecs=timekeeping_convert_to_ns(&tk->tkr_mono,cycles);+crt->system_real=ktime_add_ns(base,nsecs);++/* Convert to clock raw monotonic */+base=tk->tkr_raw.base;+nsecs=timekeeping_convert_to_ns(&tk->tkr_raw,cycles);+crt->system_raw=ktime_add_ns(base,nsecs);++}while(read_seqcount_retry(&tk_core.seq,seq));+return0;+}+EXPORT_SYMBOL(get_correlated_timestamp);++/***do_gettimeofday-Returnsthetimeofdayinatimeval*@tv:pointertothetimevaltobeset*
From: Thomas Gleixner <hidden> Date: 2015-08-22 20:17:48
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
Add struct correlated_cs with pointer to original clocksource and
function pointer to convert correlated clocksource to the original
Add get_correlated_timestamp() function which given specific correlated_cs
and correlated_ts convert correlated counter value to system time
This is not a proper changelog.
1) The subject line lacks a subsystem prefix
timekeeping:
Is the proper choice here
2) The subject line should be short and precise
timekeeping: Add mechanism to gather correlated timestamps
Might be an informative one.
3) The changelog itself should describe the reason why we want this
change, the purpose of the change etc.
Add foo
Add bar
Is pointless because we can see that from the patch itself.
What the patch cannot not explain is the WHY. That's what the
changelog is for.
4) You dropped the authorship
The proper way to do this is to add a 'FROM: author' at the top of
the changelog body.
As I wrote the patch, so I give you a changelog along with it:
<---
Subject: timekeeping: Add mechanism to gather correlated timestamps
From: Thomas Gleixner <redacted>
Modern Intel hardware provides the so called Always Running Timer
(ART). The TSC which is usually used for timekeeping is derived from
ART and runs with a fixed frequency ratio to it. ART is routed to
devices and allows to take atomic timestamp samples from the device
clock and the ART. One use case is PTP timestamps on network cards. We
want to utilize this feature as it allows us to better correlate the
PTP timestamp to the system time.
In order to gather precise timestamps we need to make sure that the
conversion from ART to TSC and the following conversion from TSC to
clock realtime happens synchronized with the ongoing timekeeping
updates. Otherwise we might convert an ART timestamp from point A in
time with the conversion factors of point B in time. These conversion
factors can differ due to NTP/PTP frequency adjustments and therefor
the resulting clock realtime timestamp would be slightly off, which is
contrary to the whole purpose of synchronized hardware timestamps.
Provide data structures which describe the correlation between two
clocksources and a function to gather correlated and convert
timestamps from a device. The function is as any other timekeeping
function protected against current timekeeper updates via the
timekeeper sequence lock. It calls the device function to gather the
hardware timestamps and converts them to clock real time and clock
monotonic raw.
Signed-off-by: Thomas Gleixner <redacted>
---->
Can you see the difference?
quoted hunk
Signed-off-by: Christopher S. Hall <redacted>
---
include/linux/clocksource.h | 33 +++++++++++++++++++++++
include/linux/timekeeping.h | 4 +++
kernel/time/timekeeping.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+)
Don't believe checkpatch here. KernelDoc requires that this is one
line, 80 char limit or not.
/**
+ * get_correlated_timestamp - Get a correlated timestamp
+ *
Lacks the parameter documentation:
* @crt: Pointer to a correlated timestamp structure which provides
* the device specific timestamp function and is used to store
* the raw and the correlated timestamps.
* @crs: Pointer to a correlated clocksource structure which describes
* the correlated clocksource and provides a conversion function
* to the timekeeping clocksource
From: Thomas Gleixner <hidden> Date: 2015-08-22 20:27:11
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
Add detect_art() call to early TSC initialization which reads ART->TSC
numerator/denominator and sets CPU feature if present
Add convert_art_to_tsc() function performing conversion ART to TSC
Add art_timestamp referencing art_to_tsc() and clocksource_tsc enabling
driver conversion of ART to TSC
+/*
+ * If ART is present detect the numberator:denominator to convert to TSC
+ */
+void detect_art(void)
+{
+ unsigned int unused[2];
+
+ if (boot_cpu_data.cpuid_level >= ART_CPUID_LEAF) {
+ cpuid(ART_CPUID_LEAF, &art_to_tsc_denominator,
+ &art_to_tsc_numerator, unused, unused+1);
+
+ if (art_to_tsc_denominator >= ART_MIN_DENOMINATOR) {
+ set_cpu_cap(&boot_cpu_data, X86_FEATURE_ART);
+ }
No parentheses around one liners please.
quoted hunk
+ }
+}
+
static int __init cpufreq_tsc(void)
{
if (!cpu_has_tsc)
return 0;
+
+ detect_art();
+
if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
return 0;
cpufreq_register_notifier(&time_cpufreq_notifier_block,
@@ -1059,6 +1085,32 @@ int unsynchronized_tsc(void) return 0; }+/*+ * Convert ART to TSC given numerator/denominator found in detect_art()+ */+static u64 convert_art_to_tsc(struct correlated_cs *cs, u64 cycles)+{+ u64 tmp, res;++ switch (art_to_tsc_denominator) {+ default:+ res = (cycles / art_to_tsc_denominator) * art_to_tsc_numerator;+ tmp = (cycles % art_to_tsc_denominator) * art_to_tsc_numerator;+ res += tmp / art_to_tsc_denominator;+ break;+ case 2:+ res = (cycles >> 1) * art_to_tsc_numerator;+ tmp = (cycles & 0x1) * art_to_tsc_numerator;+ res += tmp >> 1;+ break;
Is it really worth do do this optimization? And if we do it we
shouldn't special case it for 2. You can check at ART detection time
whether the denominator is a power of two and have a flag which
selects a div/mod base or a shift based conversion.
Thanks,
tglx
From: Thomas Gleixner <hidden> Date: 2015-08-22 20:34:28
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
From: Christopher Hall <redacted>
This patch allows system and device time ("cross-timestamp") to be
performed by the driver. Currently, the cross-timestamping is performed
in the PTP_SYS_OFFSET ioctl. The PTP clock driver reads gettimeofday()
and the gettime64() callback provided by the driver. The cross-timestamp
is best effort where the latency between the capture of system time
(getnstimeofday()) and the device time (driver callback) may be
significant.
This patch adds an additional callback getsynctime64(). Which will be
called when the driver is able to perform a more accurate, implementation
specific cross-timestamping. For example, future network devices that
implement PCIE PTM will be able to precisely correlate the device clock
with the system clock with virtually zero latency between captures.
This added callback can be used by the driver to expose this functionality.
The callback, getsynctime64(), will only be called when defined and
n_samples == 1 because the driver returns only 1 cross-timestamp where
multiple samples cannot be chained together.
This patch also adds to the capabilities ioctl (PTP_CLOCK_GETCAPS),
allowing applications to query whether or not drivers implement the
getsynctime callback, providing more precise cross timestamping.
That looks close to a proper changelog. A few nitpicks though.
Please avoid 'This patch does ...' phrases. We already know that this
is a patch.
Commit Details:
Please get rid of this. It's useless noise.
Added additional callback to ptp_clock_info:
* getsynctime64()
quoted hunk
@@ -196,19 +197,31 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) break; } pct = &sysoff->ts[0];- for (i = 0; i < sysoff->n_samples; i++) {- getnstimeofday64(&ts);+ if (ptp->info->getsynctime64 && sysoff->n_samples == 1 &&
The number of samples should be irrelevant for this sampling method.
Why is this function taking struct timespec64 pointers? Just so every
driver which implements the callback needs to convert from u64 to
struct timespec64? That's simply wrong. Use u64 for both and do the
conversion in the ioctl.
Thanks,
tglx
From: Thomas Gleixner <hidden> Date: 2015-08-22 20:46:57
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
From: Christopher Hall <redacted>
Add getsynctime() PTP device callback to cross timestamp system device
clock using ART translation depends on platform being >= SPT
and having ART
getsynctime() reads ART (TSC-derived)/device cross timestamp and
converts to realtime/device time reporting cross timestamp to
PTP driver
The usual way to order includes is:
#include <linux/timekeeping.h>
#include <asm/tsc.h>
#include "e1000.h"
+/**
+ * e1000e_phc_getsynctime - Reads the current time from the hardware clock and
+ * correlated system time
+ * @ptp: ptp clock structure
+ * @devts: timespec structure to hold the current device time value
+ * @systs: timespec structure to hold the current system time value
+ *
+ * Read device and system (ART) clock simultaneously and return the correct
+ * clock values in ns after converting into a struct timespec.
+ **/
+static int e1000e_phc_getsynctime(struct ptp_clock_info *ptp,
+ struct timespec64 *devts,
+ struct timespec64 *systs)
+{
+ struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
+ ptp_clock_info);
+ unsigned long flags;
+ u32 remainder;
+ struct correlated_ts art_correlated_ts;
+ u64 device_time;
+ int ret;
+
+ art_correlated_ts.get_ts = e1000e_phc_get_ts;
+ art_correlated_ts.private = adapter;
+ ret = get_correlated_timestamp(&art_correlated_ts,
+ &art_timestamper);
Pointless line break
+ if (ret != 0)
+ goto bail;
What's the purpose of this goto?
if (ret)
return ret;
is completely sufficient.
+ /* CPU must have ART and GBe must be from Sunrise Point or greater */
+ if (hw->mac.type < e1000_pch_spt || !cpu_has_art)
+ adapter->ptp_clock_info.getsynctime64 = NULL;
We do it the other way round. We leave the default NULL and update it
if we detect the feature.
Thanks,
tglx
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-08-22 21:17:25
On Sat, Aug 22, 2015 at 10:33:48PM +0200, Thomas Gleixner wrote:
quoted
@@ -196,19 +197,31 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) break; } pct = &sysoff->ts[0];- for (i = 0; i < sysoff->n_samples; i++) {- getnstimeofday64(&ts);+ if (ptp->info->getsynctime64 && sysoff->n_samples == 1 &&
The number of samples should be irrelevant for this sampling method.
Chris had send me a preview of this before he posted, so I can explain
that test for one sample.
User space requests N (1 to 25) samples of the two clocks. The kernel
is supposed to deliver that many samples. This has always been the
documented behavior. From ptp_clock.h:
struct ptp_sys_offset {
unsigned int n_samples; /* Desired number of measurements. */
unsigned int rsv[3]; /* Reserved for future use. */
/*
* Array of interleaved system/phc time stamps. The kernel
* will provide 2*n_samples + 1 time stamps, with the last
* one as a system time stamp.
*/
struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
};
So the kernel cannot simply change n_samples to 1.
I would prefer to have a new system call that compares any two posix
clock_t, but that is of course more work.
Allowing n_samples=1 as a special case is a kind of overloading of the
ioctl to support the new capability. At least it preserves the
behavior of the interface from the user's perspective.
Thanks,
Richard
From: Thomas Gleixner <hidden> Date: 2015-08-23 08:15:46
On Sat, 22 Aug 2015, Richard Cochran wrote:
On Sat, Aug 22, 2015 at 10:33:48PM +0200, Thomas Gleixner wrote:
quoted
quoted
@@ -196,19 +197,31 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) break; } pct = &sysoff->ts[0];- for (i = 0; i < sysoff->n_samples; i++) {- getnstimeofday64(&ts);+ if (ptp->info->getsynctime64 && sysoff->n_samples == 1 &&
The number of samples should be irrelevant for this sampling method.
Chris had send me a preview of this before he posted, so I can explain
that test for one sample.
User space requests N (1 to 25) samples of the two clocks. The kernel
is supposed to deliver that many samples. This has always been the
documented behavior. From ptp_clock.h:
struct ptp_sys_offset {
unsigned int n_samples; /* Desired number of measurements. */
unsigned int rsv[3]; /* Reserved for future use. */
/*
* Array of interleaved system/phc time stamps. The kernel
* will provide 2*n_samples + 1 time stamps, with the last
* one as a system time stamp.
*/
struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
};
So the kernel cannot simply change n_samples to 1.
I would prefer to have a new system call that compares any two posix
clock_t, but that is of course more work.
Allowing n_samples=1 as a special case is a kind of overloading of the
ioctl to support the new capability. At least it preserves the
behavior of the interface from the user's perspective.
So why can't you take N samples from the synced hardware? It does not
make any sense to me to switch to the imprecise mode if nsamples > 1.
You can also provide a new IOCTL PTP_SYS_OFFSET_PRECISE which returns
-ENOSYS if hardware timestamping is not available and avoid the whole
nsamples dance for the case where we can get precise timestamps.
Thanks,
tglx
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-08-23 11:26:05
On Sun, Aug 23, 2015 at 10:15:00AM +0200, Thomas Gleixner wrote:
So why can't you take N samples from the synced hardware? It does not
make any sense to me to switch to the imprecise mode if nsamples > 1.
Ok, then I prefer to leave this "imprecise" method in place and ...
You can also provide a new IOCTL PTP_SYS_OFFSET_PRECISE which returns
-ENOSYS if hardware timestamping is not available and avoid the whole
nsamples dance for the case where we can get precise timestamps.
have this for the new way.
By keeping the imprecise method, we will be able to run both methods
on the new hardware. That will help to quantify how imprecise the old
method is.
Thanks,
Richard
From: Hall, Christopher S <hidden> Date: 2015-08-24 20:16:55
-----Original Message-----
From: Richard Cochran [mailto:richardcochran@gmail.com]
Sent: Sunday, August 23, 2015 4:26 AM
To: Thomas Gleixner
Cc: Hall, Christopher S; Kirsher, Jeffrey T; hpa@zytor.com;
mingo@redhat.com; john.stultz@linaro.org; x86@kernel.org; linux-
kernel@vger.kernel.org; netdev@vger.kernel.org; intel-wired-
lan@lists.osuosl.org; peterz@infradead.org
Subject: Re: [PATCH v3 3/4] Add support for driver cross-timestamp to
PTP_SYS_OFFSET ioctl
On Sun, Aug 23, 2015 at 10:15:00AM +0200, Thomas Gleixner wrote:
quoted
So why can't you take N samples from the synced hardware? It does not
make any sense to me to switch to the imprecise mode if nsamples > 1.
Ok, then I prefer to leave this "imprecise" method in place and ...
quoted
You can also provide a new IOCTL PTP_SYS_OFFSET_PRECISE which returns
-ENOSYS if hardware timestamping is not available and avoid the whole
nsamples dance for the case where we can get precise timestamps.
have this for the new way.
By keeping the imprecise method, we will be able to run both methods
on the new hardware. That will help to quantify how imprecise the old
method is.
This means: remove code changes from the PTP_SYS_OFFSET ioctl and call getsynctime64() from a new ioctl PTP_SYS_OFFSET_PRECISE. Right?
And use the same type (struct ptp_sys_offset) for the new ioctl? Or should a new simplified struct be used? Such as:
struct precise_ptp_sys_offset {
struct ptp_clock_time device;
struct ptp_clock_time system;
};
Does it make sense to keep the "cross-timestamp" capabilities flag as-is?
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-08-25 07:31:17
On Mon, Aug 24, 2015 at 08:16:51PM +0000, Hall, Christopher S wrote:
This means: remove code changes from the PTP_SYS_OFFSET ioctl and call getsynctime64() from a new ioctl PTP_SYS_OFFSET_PRECISE. Right?
Yes.
And use the same type (struct ptp_sys_offset) for the new ioctl? Or should a new simplified struct be used? Such as:
struct precise_ptp_sys_offset {
struct ptp_clock_time device;
struct ptp_clock_time system;
};
I don't have a strong preference either way. I would not mind reusing
the existing struct.
Does it make sense to keep the "cross-timestamp" capabilities flag as-is?
From: Hall, Christopher S <hidden> Date: 2015-09-03 23:20:50
-----Original Message-----
From: Thomas Gleixner [mailto:tglx@linutronix.de]
Sent: Saturday, August 22, 2015 1:17 PM
To: Hall, Christopher S
Cc: Kirsher, Jeffrey T; hpa@zytor.com; mingo@redhat.com;
john.stultz@linaro.org; richardcochran@gmail.com; x86@kernel.org; linux-
kernel@vger.kernel.org; netdev@vger.kernel.org; intel-wired-
lan@lists.osuosl.org; peterz@infradead.org
Subject: Re: [PATCH v3 1/4] Add correlated clocksource deriving system time
from an auxiliary clocksource
quoted
+/**
+ * get_correlated_timestamp - Get a correlated timestamp
+ *
+ * Reads a timestamp from a device and correlates it to system time
+ */
+int get_correlated_timestamp(struct correlated_ts *crt,
+ struct correlated_cs *crs)
+{
+ struct timekeeper *tk = &tk_core.timekeeper;
+ unsigned long seq;
+ cycles_t cycles;
+ ktime_t base;
+ s64 nsecs;
+ int ret;
+
+ do {
+ seq = read_seqcount_begin(&tk_core.seq);
+ /*
+ * Verify that the correlated clocksoure is related to
+ * the currently installed timekeeper clocksoure
+ */
+ if (tk->tkr_mono.clock != crs->related_cs)
+ return -ENODEV;
+
+ /*
+ * Try to get a timestamp from the device.
+ */
+ ret = crt->get_ts(crt);
+ if (ret)
+ return ret;
+
[Re-added code for context]
In addition to the network interface, ART will be used in the audio interface as well.
We need to support the case where an audio co-processor will control the audio device.
In this case, the get_ts() function supplied by the audio driver will be very slow
(several milliseconds) and the result will be out of date by some fraction of that
amount.
This loop makes strict requirements on the latency and recency. Is it possible to relax
that requirement in some way?
For example, supply the ART value as an argument and, in the case of the realtime
clock, keep a short history of clock changes. It would fail in cases where there
are a lot of calls to adjtimex(), but it will would work most of the time.
What can you suggest? Thanks
Chris
quoted
+ } while (read_seqcount_retry(&tk_core.seq, seq));
+ return 0;
+}
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-09-04 08:11:34
On Thu, Sep 03, 2015 at 11:20:37PM +0000, Hall, Christopher S wrote:
In addition to the network interface, ART will be used in the audio interface as well.
We need to support the case where an audio co-processor will control the audio device.
In this case, the get_ts() function supplied by the audio driver will be very slow
(several milliseconds) and the result will be out of date by some fraction of that
amount.
Why does it take milliseconds to read one audio time stamp?
Thanks,
Richard
From: Thomas Gleixner <hidden> Date: 2015-09-04 13:03:18
On Thu, 3 Sep 2015, Hall, Christopher S wrote:
Can you please teach your mail client to add proper line breaks around
80? Your mail renders horrible in a text based mail client.
In addition to the network interface, ART will be used in the audio
interface as well. We need to support the case where an audio
co-processor will control the audio device. In this case, the
get_ts() function supplied by the audio driver will be very slow
(several milliseconds) and the result will be out of date by some
fraction of that amount.
You are not telling at all, what this driver is supposed to do, what
this get_ts() function is for and how that co-processor thing works.
You just make claims, that you need this without explaining WHY. And
that WHY is the most interesting part.
This loop makes strict requirements on the latency and recency. Is
it possible to relax that requirement in some way?
No. This function is explicitely for the precise timestamp usecase,
which is required by PTP and other sane use cases.
For example, supply the ART value as an argument and, in the case of
the realtime clock, keep a short history of clock changes. It would
It's not only clock realtime which is affected by those.
fail in cases where there are a lot of calls to adjtimex(),
That has nothing to do with lots of adjtimex calls. The kernel does a
slow correction of the conversion values itself to avoid time jumping
around.
but it will would work most of the time.
Will, would, most? - Could, perhaps, sometimes?
Looks like a design from the trainwreck engineering departement. We
want to have it very precise, but we don't care if it behaves like a
random number generator.
Can you folks please get your act together and provide coherent
explanations about the usecase and the constraints instead of
proposing random functions with obscure semantics?
Thanks,
tglx
From: Peter Zijlstra <peterz@infradead.org> Date: 2015-09-04 14:28:40
On Fri, Sep 04, 2015 at 10:11:22AM +0200, Richard Cochran wrote:
On Thu, Sep 03, 2015 at 11:20:37PM +0000, Hall, Christopher S wrote:
quoted
In addition to the network interface, ART will be used in the audio interface as well.
We need to support the case where an audio co-processor will control the audio device.
In this case, the get_ts() function supplied by the audio driver will be very slow
(several milliseconds) and the result will be out of date by some fraction of that
amount.
Why does it take milliseconds to read one audio time stamp?
So what I suspect, but please correct me if I'm wrong Chris, is that a
DSP will buffer and process audio signals, and only later wake up the
main CPU.
So by the time the CPU is made aware of the data, it's 'old'.
From: Peter Zijlstra <peterz@infradead.org> Date: 2015-09-04 15:10:31
On Fri, Sep 04, 2015 at 03:02:19PM +0200, Thomas Gleixner wrote:
quoted
For example, supply the ART value as an argument and, in the case of
the realtime clock, keep a short history of clock changes. It would
It's not only clock realtime which is affected by those.
quoted
fail in cases where there are a lot of calls to adjtimex(),
That has nothing to do with lots of adjtimex calls. The kernel does a
slow correction of the conversion values itself to avoid time jumping
around.
I think what they're getting at is asking if there's a rate limit to
time adjustments, without that, saving the last n transition points will
still not cover any given length of history.
So what I think they're looking for; is given an upper bound on the DSP
delaying its data, come up with a fixed minimal amount of transitions
points we must store to cover the history.
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-09-04 15:17:50
On Fri, Sep 04, 2015 at 05:10:21PM +0200, Peter Zijlstra wrote:
I think what they're getting at is asking if there's a rate limit to
time adjustments, without that, saving the last n transition points will
still not cover any given length of history.
As if the ntp code isn't complex enough already - now we're adding
sample histories and adjustment rating limiting?
And all for some unknown DSP in a mythical sound card??
Thanks,
Richard
From: Richard Cochran <richardcochran@gmail.com> Date: 2015-09-04 15:32:12
On Fri, Sep 04, 2015 at 03:02:19PM +0200, Thomas Gleixner wrote:
No. This function is explicitely for the precise timestamp usecase,
which is required by PTP and other sane use cases.
Right. The audio department only needs to know the (ART, ptp) offset.
The kernel and user space never need the (ART, mediaclock) offset.
That is private information for the DSP.
As long as user space reads (ART, ptp) and provides this regulary to
the audio DSP, then the DSP will have all the information it needs to
figure out (ptp, mediaclock).
Thanks,
Richard
From: Peter Zijlstra <peterz@infradead.org> Date: 2015-09-04 15:41:42
On Fri, Sep 04, 2015 at 05:17:43PM +0200, Richard Cochran wrote:
On Fri, Sep 04, 2015 at 05:10:21PM +0200, Peter Zijlstra wrote:
quoted
I think what they're getting at is asking if there's a rate limit to
time adjustments, without that, saving the last n transition points will
still not cover any given length of history.
As if the ntp code isn't complex enough already - now we're adding
sample histories and adjustment rating limiting?
And all for some unknown DSP in a mythical sound card??
Hehe, I'm just a 'translator' here. But going by you answer I'm taking
it there isn't in fact a rate-limit to adjustments. Which, even if you
were not opposed to that direction, makes it an unfeasible proposition.
Also, I'm not thinking its too mythical, sound/soc/intel/ is full of
audio DSP stuff, I think a newer version will just gain ART support.
From: Thomas Gleixner <hidden> Date: 2015-09-04 16:36:17
On Fri, 4 Sep 2015, Peter Zijlstra wrote:
On Fri, Sep 04, 2015 at 05:17:43PM +0200, Richard Cochran wrote:
quoted
On Fri, Sep 04, 2015 at 05:10:21PM +0200, Peter Zijlstra wrote:
quoted
I think what they're getting at is asking if there's a rate limit to
time adjustments, without that, saving the last n transition points will
still not cover any given length of history.
As if the ntp code isn't complex enough already - now we're adding
sample histories and adjustment rating limiting?
And all for some unknown DSP in a mythical sound card??
Hehe, I'm just a 'translator' here. But going by you answer I'm taking
it there isn't in fact a rate-limit to adjustments. Which, even if you
were not opposed to that direction, makes it an unfeasible proposition.
Also, I'm not thinking its too mythical, sound/soc/intel/ is full of
audio DSP stuff, I think a newer version will just gain ART support.
Right, but we still do not know how that is going to be used. And
that's the key question. As long as that is not answered all can do is
wild guessing.
Thanks,
tglx
From: Hall, Christopher S <hidden> Date: 2015-09-04 21:01:13
-----Original Message-----
From: Thomas Gleixner [mailto:tglx@linutronix.de]
Sent: Friday, September 04, 2015 9:35 AM
To: Peter Zijlstra
Cc: Richard Cochran; Hall, Christopher S; Kirsher, Jeffrey T;
hpa@zytor.com; mingo@redhat.com; john.stultz@linaro.org; x86@kernel.org;
linux-kernel@vger.kernel.org; netdev@vger.kernel.org; intel-wired-
lan@lists.osuosl.org
Subject: Re: [PATCH v3 1/4] Add correlated clocksource deriving system time
from an auxiliary clocksource
On Fri, 4 Sep 2015, Peter Zijlstra wrote:
quoted
On Fri, Sep 04, 2015 at 05:17:43PM +0200, Richard Cochran wrote:
quoted
On Fri, Sep 04, 2015 at 05:10:21PM +0200, Peter Zijlstra wrote:
quoted
I think what they're getting at is asking if there's a rate limit to
time adjustments, without that, saving the last n transition points
will
quoted
quoted
quoted
still not cover any given length of history.
As if the ntp code isn't complex enough already - now we're adding
sample histories and adjustment rating limiting?
And all for some unknown DSP in a mythical sound card??
Hehe, I'm just a 'translator' here. But going by you answer I'm taking
it there isn't in fact a rate-limit to adjustments. Which, even if you
were not opposed to that direction, makes it an unfeasible proposition.
Also, I'm not thinking its too mythical, sound/soc/intel/ is full of
audio DSP stuff, I think a newer version will just gain ART support.
Right, but we still do not know how that is going to be used. And
that's the key question. As long as that is not answered all can do is
wild guessing.
It's not wild guessing. We do have it working on other OSs and have a pretty good
idea of how it will work. The DSP firmware will be largely identical for Linux. I
think now, we have a chicken and egg problem.
We can't post audio drivers that break, or are broken by, the current ART interface.
How do I move this forward? Should I minimally (I don't know exactly what that means
just yet) rewrite the ART interface so that the audio driver is mostly not broken and
post that along with the audio driver code? Is this an acceptable approach?
From: Hall, Christopher S <hidden> Date: 2015-09-04 21:12:50
-----Original Message-----
From: Peter Zijlstra [mailto:peterz@infradead.org]
Sent: Friday, September 04, 2015 7:28 AM
To: Richard Cochran
Cc: Hall, Christopher S; Thomas Gleixner; Kirsher, Jeffrey T;
hpa@zytor.com; mingo@redhat.com; john.stultz@linaro.org; x86@kernel.org;
linux-kernel@vger.kernel.org; netdev@vger.kernel.org; intel-wired-
lan@lists.osuosl.org
Subject: Re: [PATCH v3 1/4] Add correlated clocksource deriving system time
from an auxiliary clocksource
quoted
quoted
(several milliseconds) and the result will be out of date by some
fraction of that
quoted
quoted
amount.
Why does it take milliseconds to read one audio time stamp?
So what I suspect, but please correct me if I'm wrong Chris, is that a
DSP will buffer and process audio signals, and only later wake up the
main CPU.
So by the time the CPU is made aware of the data, it's 'old'.
That's about right. The DSP runs on a 1 ms cadence. Any access to registers controlled by the DSP will take 1-2 DSP ticks to access.
From: John Stultz <hidden> Date: 2015-09-04 21:50:49
On Thu, Sep 3, 2015 at 4:20 PM, Hall, Christopher S
[off-list ref] wrote:
For example, supply the ART value as an argument and, in the case of the realtime
clock, keep a short history of clock changes. It would fail in cases where there
are a lot of calls to adjtimex(), but it will would work most of the time.
So, I really don't think something like this would be reasonable. For
one, keeping track of the adjtimex adjustments would be difficult
enough to do sanely, but the real issue is that the clock has its own
long-term error correction adjustments that it does in order to keep
long term frequency accuracy with coarsely adjusted clocksources.
Trying to track those small oscillation intervals would be even more
complicated.
I still think that being able to calculate the CLOCK_MONOTONIC_RAW
value for a given ART counter value is reasonable, and then one can
use the getnstime_raw_and_real() to get a current raw/real sync point,
which you can then calculate the raw delta, and subtract that from the
sycned real timestamp.
You're error there would be bound by the maxium clocksource adjustment
rate * the raw-delta interval length.
To clarify on the need to understand if this error would be
reasonable, can you provide a sense of what the delay from an ART read
to trying to calculate a REALTIME value might be?
thanks
-john
From: Thomas Gleixner <hidden> Date: 2015-09-05 08:47:55
On Fri, 4 Sep 2015, Hall, Christopher S wrote:
quoted
Right, but we still do not know how that is going to be used. And
that's the key question. As long as that is not answered all can do is
wild guessing.
It's not wild guessing. We do have it working on other OSs and have
a pretty good idea of how it will work. The DSP firmware will be
largely identical for Linux. I think now, we have a chicken and egg
problem.
You have a totally different problem. You are just refusing to explain
how all that stuff is supposed to work and what kind of functionality
you need exactly.
Is it that hard to describe the technical requirements and the
presumably assbackwards restrictions of the firmware?
Thanks,
tglx
Right, but we still do not know how that is going to be used. And
that's the key question. As long as that is not answered all can do is
wild guessing.
It's not wild guessing. We do have it working on other OSs and have a pretty
good idea of how it will work. The DSP firmware will be largely identical for
Linux. I think now, we have a chicken and egg problem.
You have a totally different problem. You are just refusing to explain how all
that stuff is supposed to work and what kind of functionality you need exactly.
Yeah, so I'm just going to NAK this until things are improved:
NAKed-by: Ingo Molnar [off-list ref]
it's not like we are overly bored in timekeeping and need the extra complexity as
much as possible.
Proper, comprehensive, proactive technical description is needed, with proper
changelogs, not just half-baked notes. If all that is fixed I'll lift my NAK.
Thanks,
Ingo