From: Nicolai Buchwitz <nb@tipi-net.de>
To: James Clark <jjc@jclark.com>
Cc: "Théo Lebrun" <theo.lebrun@bootlin.com>,
netdev@vger.kernel.org,
"Richard Cochran" <richardcochran@gmail.com>,
"Conor Dooley" <conor.dooley@microchip.com>,
"Andrew Lunn" <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH net] net: macb: fix ordering around PTP timestamp read
Date: Tue, 08 Sep 2026 11:12:37 +0200 [thread overview]
Message-ID: <efc8c860b90e8f55882241267b0e242d@tipi-net.de> (raw)
In-Reply-To: <20260908053150.28694-1-jjc@jclark.com>
Hi James
On 8.9.2026 07:31, James Clark wrote:
> PTP_SYS_OFFSET_EXTENDED returns system timestamps that do not correctly
> bracket the PHC register read on MACB/GEM. On a Raspberry Pi 5, the
> returned interval can be as short as 37 ns, while an ordered register
> read takes approximately 1 us. This biases the midpoint used by
> phc2sys,
> causing CLOCK_REALTIME to run approximately 0.5 us ahead when
> synchronized
> to the PHC.
>
> gem_tsu_get_time() reads the nanoseconds register using the driver's
> relaxed MMIO accessor. On weakly ordered systems, the subsequent system
> timestamp can be taken before the register read completes.
>
> Add rmb() after the bracketed nanoseconds read in both the normal and
> seconds rollover paths, ensuring that the read completes before the
> post
> timestamp is taken. With the fix, the minimum interval on the same
> Raspberry Pi 5 increases to approximately 1 us.
>
> Fixes: e51bb5c2784c ("net: macb: ptp: Switch to gettimex64()
> interface")
> Signed-off-by: James Clark <jjc@jclark.com>
> ---
> This uses rmb() to preserve the existing accessor and endianness
> handling.
> Would an ordered MMIO accessor be preferable for these two reads?
AFAIU rmb() fits better here. Switching to readl() would also order the
read
on arm64, but only for hw_readl(). hw_readl_native() uses __raw_readl(),
which
has no ordered version, so that path would still need a barrier.
>
> Reproducer:
>
> #include <fcntl.h>
> #include <linux/ptp_clock.h>
> #include <stdio.h>
> #include <sys/ioctl.h>
>
> #define DEVICE "/dev/ptp0"
>
> int main(void)
> {
> struct ptp_sys_offset_extended ex = { .n_samples = 25 };
> long long min = -1;
> int fd = open(DEVICE, O_RDONLY);
>
> if (fd < 0) {
> perror(DEVICE);
> return 1;
> }
> for (int batch = 0; batch < 40; batch++) {
> if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, &ex) < 0) {
> perror("PTP_SYS_OFFSET_EXTENDED");
> return 1;
> }
> for (unsigned int i = 0; i < ex.n_samples; i++) {
> long long bracket = (ex.ts[i][2].sec - ex.ts[i][0].sec) *
> 1000000000LL
> + (long long)ex.ts[i][2].nsec - ex.ts[i][0].nsec;
> if (min < 0 || bracket < min)
> min = bracket;
> }
> }
> printf("min bracket: %lld ns\n", min);
> return 0;
> }
>
> drivers/net/ethernet/cadence/macb_ptp.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/cadence/macb_ptp.c
> b/drivers/net/ethernet/cadence/macb_ptp.c
> index e5195d7da..8209ec190 100644
> --- a/drivers/net/ethernet/cadence/macb_ptp.c
> +++ b/drivers/net/ethernet/cadence/macb_ptp.c
> @@ -51,6 +51,8 @@ static int gem_tsu_get_time(struct ptp_clock_info
> *ptp, struct timespec64 *ts,
> spin_lock_irqsave(&bp->tsu_clk_lock, flags);
> ptp_read_system_prets(sts);
> first = gem_readl(bp, TN);
> + /* Ensure the PHC read completes before taking the post timestamp. */
> + rmb();
> ptp_read_system_postts(sts);
> secl = gem_readl(bp, TSL);
> sech = gem_readl(bp, TSH);
> @@ -63,6 +65,8 @@ static int gem_tsu_get_time(struct ptp_clock_info
> *ptp, struct timespec64 *ts,
> */
> ptp_read_system_prets(sts);
> ts->tv_nsec = gem_readl(bp, TN);
> + /* Ensure the PHC read completes before taking the post timestamp.
> */
nit: comment should be wrapped, to fit in the usual line length
> + rmb();
> ptp_read_system_postts(sts);
> secl = gem_readl(bp, TSL);
> sech = gem_readl(bp, TSH);
Tested-by: Nicolai Buchwitz <nb@tipi-net.de> # Raspberry Pi CM5, min
bracket 37 ns -> 981 ns
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Thanks
Nicolai
next prev parent reply other threads:[~2026-09-08 9:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 5:31 [RFC PATCH net] net: macb: fix ordering around PTP timestamp read James Clark
2026-09-08 9:12 ` Nicolai Buchwitz [this message]
2026-09-09 12:25 ` Théo Lebrun
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=efc8c860b90e8f55882241267b0e242d@tipi-net.de \
--to=nb@tipi-net.de \
--cc=andrew+netdev@lunn.ch \
--cc=conor.dooley@microchip.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=jjc@jclark.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=theo.lebrun@bootlin.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.