mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yuan Wang <yuan1.wang@intel.com>
To: David Woodhouse <dwmw@amazon.co.uk>,
	Miroslav Lichvar <mlichvar@redhat.com>,
	John Stultz <jstultz@google.com>,
	Thomas Gleixner <tglx@kernel.org>
Cc: jie.wang@intel.com, yifan2.li@intel.com, junxiao.chang@intel.com,
	Stephen Boyd <sboyd@kernel.org>,
	Richard Cochran <richardcochran@gmail.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 0/1] timekeeping: Don't charge NTP frequency changes to ntp_error
Date: Thu,  5 Nov 2026 11:21:49 +0800	[thread overview]
Message-ID: <20261105032150.1763572-1-yuan1.wang@intel.com> (raw)

From: Jie Wang <jie.wang@intel.com>

Hi,

Since b7befd6d9120 ("timekeeping: Account for monotonicity adjustment in
ntp_error") we see phc2sys take minutes, instead of seconds, to settle
CLOCK_REALTIME back to a few tens of ns after the PHC it follows is
stepped. The PHC itself (ptp4l) recovers as fast as before; only the
PHC -> CLOCK_REALTIME loop is affected.

Setup: two Intel i226 NICs back to back, gPTP (802.1AS profile, L2 P2P),
ptp4l + "phc2sys -O 0 -c CLOCK_REALTIME -s <if>" on both ends, PREEMPT_RT,
HZ=1000, TSC clocksource. The grandmaster's PHC is stepped by +1s with
"testptp -t 1". Time until |phc2sys offset| stays below 100ns:

                                 GM phc2sys      slave phc2sys  slave ptp4l
  v7.0 (before the series)         51-56s (test team, slave side)
  v7.2.7    (b7befd6d9120 only)    257-386s        79-333s        33-34s
  v7.2.7 + revert of b7befd6d9120  32s             40-42s         34-35s
  v7.3      (whole series)         207/>361/>413s  79-293s        34-35s
  v7.3 + revert of the series      32s             40-41s         34-35s
  v7.3 + this patch                32s             40-41s         34-35s

  (">" = not settled before the next step 400s later)

What happens: after the step phc2sys slews CLOCK_REALTIME at up to 10%
(ADJ_TICK + ADJ_FREQUENCY) and then backs off by several percent per
second. Since b7befd6d9120 every one of these base-rate changes adds
offset * mult_adj to ntp_error - up to a tick's worth of cycles times the
frequency change, i.e. tens of microseconds per update. ntp_error is only
repaid by the +1 mult dither (a few hundred ppb here), so CLOCK_REALTIME
keeps moving on its own for minutes after phc2sys has converged, and the
servo keeps chasing it.

That correction is the one c2cda2a5bda9 ("timekeeping/ntp: Don't align
NTP frequency adjustments to ticks") removed in 2018: it makes the clock
behave as if a new frequency had been applied at the start of the tick
rather than when adjtimex() was called. As far as I can tell the v7 series
discussion didn't revisit that trade-off.

I think both views are right for different callers:

 - A new base rate set from user space (ADJ_FREQUENCY/ADJ_TICK) belongs to
   an external servo (chrony, ptp4l, phc2sys) that measures the clock
   directly. Any phase effect is seen and corrected by that servo; booking
   it in ntp_error as well makes the kernel pay it back a second time,
   slowly.

 - The kernel's own adjustments - the mult/mult+1 dither and the
   skew_delta bias that delivers time_offset/time_adjust - have a phase
   target inside the kernel, and there the compensation from b7befd6d9120
   is what keeps the delivered phase exact.

So the patch keeps the compensation for the dither and skew changes, but
applies a new NTP base rate without charging ntp_error, as before
b7befd6d9120.

Open question, mainly for David: if timekeeping_set_reference() (ffclock
branch) changes tick_length, it would now also be applied "at the time of
the update". If that path needs the as-if-at-tick semantics, I'd suggest
it delivers the phase through time_offset (which the series now makes
exact) or passes an explicit flag down to timekeeping_adjust(); happy to
rework the patch either way.

The patch doesn't change the kernel-internal slews. An adjtime()
(ADJ_OFFSET_SINGLESHOT) of +5000us with no servo running, measured as
CLOCK_REALTIME - CLOCK_MONOTONIC_RAW, settles 10-12s later at:
  v7.3:              5009255ns (+9.3us)
  v7.3 + this patch: 5001024ns (+1.0us)
(one run each, so I'd read that as "not worse" rather than "better"; the
residual error in both cases looks worth a separate look). Steady-state
phc2sys lock before the step is the same on all three 7.3 kernels
(7-10ns rms on the GM).

phc2sys -S (step instead of slew) avoids the problem on an unpatched
kernel - a step clears ntp_error - but steps are usually not acceptable
on TSN systems once the schedule is running, so that is only a
workaround.

This fixes a 7.2 regression, so it probably wants
Cc stable list once the approach is agreed.

Jie Wang (1):
  timekeeping: Don't charge NTP frequency changes to ntp_error

 kernel/time/timekeeping.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)


base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
-- 
2.43.0


             reply	other threads:[~2026-11-05  3:21 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05  3:21 Yuan Wang [this message]
2026-11-05  3:21 ` [RFC PATCH 1/1] " Yuan Wang
     [not found] ` <cd23df8dde221a908233b5dfde548383991b4537.camel@amazon.co.uk>
2026-11-05 16:29   ` [RFC PATCH 0/1] " David Woodhouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261105032150.1763572-1-yuan1.wang@intel.com \
    --to=yuan1.wang@intel.com \
    --cc=dwmw@amazon.co.uk \
    --cc=jie.wang@intel.com \
    --cc=jstultz@google.com \
    --cc=junxiao.chang@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mlichvar@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=sboyd@kernel.org \
    --cc=tglx@kernel.org \
    --cc=yifan2.li@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®