From patchwork Fri May 6 20:01:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841564 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC01CC433FE for ; Fri, 6 May 2022 20:02:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1392467AbiEFUFt (ORCPT ); Fri, 6 May 2022 16:05:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1392454AbiEFUFs (ORCPT ); Fri, 6 May 2022 16:05:48 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DB0A5AECB for ; Fri, 6 May 2022 13:02:04 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id p4so9896501edx.0 for ; Fri, 06 May 2022 13:02:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XGpN7a6Vx43ZcT87nIB7JrFLuOFS7p8mtZShmRyK89U=; b=bCA5SnLGOrJcym2QHDBdP4mS9ruU+HsSrWGKv/cAeugIayU1/lo8zjt3UXR2UnWgn7 TtSeNvtgeIL3T/RkH623S9GJlzkgH2pU9r+Ut8jsiVDXOwbzElJO9pcK+c1Ce/2wZjdU A8oQkE76kwJ29aquTiI0Auz3yHppTkrNpQlGIt0j0vp7wCWTZXO8zw0+Br9l0ReeDhB1 RJbmJycMEyyAGE1rcPFz8jb84pNrTA0FjAib7QF2NH7AkDGlCpgCJPwZq1BpakuL3XGn yH2DRmTtm2YiPLf7jGoNdD9ObUkFZIjeGjOPuCNr/7X74dcD6xfZzWTnscOeDsmeC87B h0eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XGpN7a6Vx43ZcT87nIB7JrFLuOFS7p8mtZShmRyK89U=; b=SLxQiGSWuc0VWKlKc914IvRx2qnmSCokTEz+rDw+dGpFxD40DL6GYis5OpmJHJutxp /MH0yOTuDJB6Ff92mXhW7oitEg++nzetVmUzXkMEjw8V+5lXGbRA94BaQqB70QdKOgYu F2DlfB4MW9Q7ZyZ09sDxdhEoou9nKm/uBXfPqnJW8O+AzswDUMhPk9yasCZWijFYsowy CoKrLtpJMw8rrbixFkLU0FKAEr9YYAOhm4ytJ4Jtb/3IvuBbP5hjIDonWLqHSn1qXhU/ WHt/un0Iy5/lv/tY7LLpP1ZE+h8qxn/h8to52ZXr3E4KJZGiKkyisnREFQ48ODPE47Vl g/pQ== X-Gm-Message-State: AOAM530ch+zGvx8q6G2MN1jNmEXBbWS1Anb/6hlLXsV+Nuem4Oc1bnCN HBJhoMnae+yQ7fPWU3cKntr9RA== X-Google-Smtp-Source: ABdhPJyqhepoXHo/Ff3bjsa8htbvtv8z2yP/F1zmkKHBzD3tzuG+5DkHrUHvjabDKmJJ/cxskEr7Yg== X-Received: by 2002:a05:6402:50a:b0:426:16c3:4283 with SMTP id m10-20020a056402050a00b0042616c34283mr5264794edv.371.1651867322030; Fri, 06 May 2022 13:02:02 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:01 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 1/6] ptp: Add cycles support for virtual clocks Date: Fri, 6 May 2022 22:01:37 +0200 Message-Id: <20220506200142.3329-2-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org ptp vclocks require a free running time for their timecounter. Currently only a physical clock forced to free running is supported. If vclocks are used, then the physical clock cannot be synchronized anymore. The synchronized time is not available in hardware in this case. As a result, timed transmission with TAPRIO hardware support is not possible anymore. If hardware would support a free running time additionally to the physical clock, then the physical clock does not need to be forced to free running. Thus, the physical clocks can still be synchronized while vclocks are in use. The physical clock could be used to synchronize the time domain of the TSN network and trigger TAPRIO. In parallel vclocks can be used to synchronize other time domains. Introduce support for a free running cycle counter called cycles to physical clocks. Rework ptp vclocks to use this free running cycle counter. Default implementation is based on time of physical clock. Thus, behavior of ptp vclocks based on physical clocks without free running cycle counter is identical to previous behavior. Signed-off-by: Gerhard Engleder Acked-by: Richard Cochran --- drivers/ptp/ptp_clock.c | 31 +++++++++++++++++++++++++++---- drivers/ptp/ptp_private.h | 10 ++++++++++ drivers/ptp/ptp_sysfs.c | 11 +++++++---- drivers/ptp/ptp_vclock.c | 13 +++++-------- include/linux/ptp_clock_kernel.h | 31 +++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index b6f2cfd15dd2..688cde320bb0 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -77,8 +77,8 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - if (ptp_vclock_in_use(ptp)) { - pr_err("ptp: virtual clock in use\n"); + if (ptp_clock_freerun(ptp)) { + pr_err("ptp: physical clock is free running\n"); return -EBUSY; } @@ -103,8 +103,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) struct ptp_clock_info *ops; int err = -EOPNOTSUPP; - if (ptp_vclock_in_use(ptp)) { - pr_err("ptp: virtual clock in use\n"); + if (ptp_clock_freerun(ptp)) { + pr_err("ptp: physical clock is free running\n"); return -EBUSY; } @@ -178,6 +178,14 @@ static void ptp_clock_release(struct device *dev) kfree(ptp); } +static int ptp_getcycles64(struct ptp_clock_info *info, struct timespec64 *ts) +{ + if (info->getcyclesx64) + return info->getcyclesx64(info, ts, NULL); + else + return info->gettime64(info, ts); +} + static void ptp_aux_kworker(struct kthread_work *work) { struct ptp_clock *ptp = container_of(work, struct ptp_clock, @@ -225,6 +233,21 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, mutex_init(&ptp->n_vclocks_mux); init_waitqueue_head(&ptp->tsev_wq); + if (ptp->info->getcycles64 || ptp->info->getcyclesx64) { + ptp->has_cycles = true; + if (!ptp->info->getcycles64 && ptp->info->getcyclesx64) + ptp->info->getcycles64 = ptp_getcycles64; + } else { + /* Free running cycle counter not supported, use time. */ + ptp->info->getcycles64 = ptp_getcycles64; + + if (ptp->info->gettimex64) + ptp->info->getcyclesx64 = ptp->info->gettimex64; + + if (ptp->info->getcrosststamp) + ptp->info->getcrosscycles = ptp->info->getcrosststamp; + } + if (ptp->info->do_aux_work) { kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index dba6be477067..ab47c10b3874 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -52,6 +52,7 @@ struct ptp_clock { int *vclock_index; struct mutex n_vclocks_mux; /* protect concurrent n_vclocks access */ bool is_virtual_clock; + bool has_cycles; }; #define info_to_vclock(d) container_of((d), struct ptp_vclock, info) @@ -96,6 +97,15 @@ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) return in_use; } +/* Check if ptp clock shall be free running */ +static inline bool ptp_clock_freerun(struct ptp_clock *ptp) +{ + if (ptp->has_cycles) + return false; + + return ptp_vclock_in_use(ptp); +} + extern struct class *ptp_class; /* diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 9233bfedeb17..f30b0a439470 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -231,10 +231,13 @@ static ssize_t n_vclocks_store(struct device *dev, *(ptp->vclock_index + ptp->n_vclocks - i) = -1; } - if (num == 0) - dev_info(dev, "only physical clock in use now\n"); - else - dev_info(dev, "guarantee physical clock free running\n"); + /* Need to inform about changed physical clock behavior */ + if (!ptp->has_cycles) { + if (num == 0) + dev_info(dev, "only physical clock in use now\n"); + else + dev_info(dev, "guarantee physical clock free running\n"); + } ptp->n_vclocks = num; mutex_unlock(&ptp->n_vclocks_mux); diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index cb179a3ea508..3a095eab9cc5 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -68,7 +68,7 @@ static int ptp_vclock_gettimex(struct ptp_clock_info *ptp, int err; u64 ns; - err = pptp->info->gettimex64(pptp->info, &pts, sts); + err = pptp->info->getcyclesx64(pptp->info, &pts, sts); if (err) return err; @@ -104,7 +104,7 @@ static int ptp_vclock_getcrosststamp(struct ptp_clock_info *ptp, int err; u64 ns; - err = pptp->info->getcrosststamp(pptp->info, xtstamp); + err = pptp->info->getcrosscycles(pptp->info, xtstamp); if (err) return err; @@ -143,10 +143,7 @@ static u64 ptp_vclock_read(const struct cyclecounter *cc) struct ptp_clock *ptp = vclock->pclock; struct timespec64 ts = {}; - if (ptp->info->gettimex64) - ptp->info->gettimex64(ptp->info, &ts, NULL); - else - ptp->info->gettime64(ptp->info, &ts); + ptp->info->getcycles64(ptp->info, &ts); return timespec64_to_ns(&ts); } @@ -168,11 +165,11 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock) vclock->pclock = pclock; vclock->info = ptp_vclock_info; - if (pclock->info->gettimex64) + if (pclock->info->getcyclesx64) vclock->info.gettimex64 = ptp_vclock_gettimex; else vclock->info.gettime64 = ptp_vclock_gettime; - if (pclock->info->getcrosststamp) + if (pclock->info->getcrosscycles) vclock->info.getcrosststamp = ptp_vclock_getcrosststamp; vclock->cc = ptp_vclock_cc; diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index e8cc8b6bbf50..ad309202cf9f 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -108,6 +108,32 @@ struct ptp_system_timestamp { * @settime64: Set the current time on the hardware clock. * parameter ts: Time value to set. * + * @getcycles64: Reads the current free running cycle counter from the hardware + * clock. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @gettime64 or @gettimex64 will be used as default + * implementation. + * parameter ts: Holds the result. + * + * @getcyclesx64: Reads the current free running cycle counter from the + * hardware clock and optionally also the system clock. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @gettimex64 will be used as default implementation if + * available. + * parameter ts: Holds the PHC timestamp. + * parameter sts: If not NULL, it holds a pair of timestamps + * from the system clock. The first reading is made right before + * reading the lowest bits of the PHC timestamp and the second + * reading immediately follows that. + * + * @getcrosscycles: Reads the current free running cycle counter from the + * hardware clock and system clock simultaneously. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @getcrosststamp will be used as default implementation if + * available. + * parameter cts: Contains timestamp (device,system) pair, + * where system time is realtime and monotonic. + * * @enable: Request driver to enable or disable an ancillary feature. * parameter request: Desired resource to enable or disable. * parameter on: Caller passes one to enable or zero to disable. @@ -155,6 +181,11 @@ struct ptp_clock_info { int (*getcrosststamp)(struct ptp_clock_info *ptp, struct system_device_crosststamp *cts); int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts); + int (*getcycles64)(struct ptp_clock_info *ptp, struct timespec64 *ts); + int (*getcyclesx64)(struct ptp_clock_info *ptp, struct timespec64 *ts, + struct ptp_system_timestamp *sts); + int (*getcrosscycles)(struct ptp_clock_info *ptp, + struct system_device_crosststamp *cts); int (*enable)(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on); int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, From patchwork Fri May 6 20:01:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841565 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 978EEC433F5 for ; Fri, 6 May 2022 20:02:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1392475AbiEFUFv (ORCPT ); Fri, 6 May 2022 16:05:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377267AbiEFUFt (ORCPT ); Fri, 6 May 2022 16:05:49 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5567B5F8D7 for ; Fri, 6 May 2022 13:02:05 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id y3so16318706ejo.12 for ; Fri, 06 May 2022 13:02:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qCsNwD6N23cm0Ctz+SSIq1fYoVaai4S5HfuNlZ+jRow=; b=F0BU5UrNmhWK/luvKeJ1wxsC1L+7xYqXb334tJNv7CeMnkG2ukxseOm+l/lX0Ib3pZ 2Wu3IQjdvfxZMmiLjFegTnVE6Bgr0FAgt0QnHS4sUWsqk7k73ErCAltWJFpnuSB1IfDQ OM86E/8dTAWznqM/0+nabhQrPiBMc+Gmjn2vvdscxVUb5H5SVLxpSHWUR2FFMXcti7qf 2/ngqSrB6VL/qR6Ex/n3E8NH1KzB2We7O5uUw9hydElHdEUi6d1EWIVaOnWhiel8FT+g BzOmfUt9KigLoJYAtT5MxP9f+A41eze5nS9N5pQMTTeoXgoQTwRL8sRjxu1op2buN4Vc qG+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qCsNwD6N23cm0Ctz+SSIq1fYoVaai4S5HfuNlZ+jRow=; b=KUsKRMa7N3CzWaE5vl50D8PzRraDF5vM7SnV1HlT+Ts3nNF9uEnSplL1EF/i89LeCr pW8OycsgsU5YaPY0Sa2or2lg++INlVPcwKDq6iyza/fLwuaKC/27VvLrOjxbyuoSkXuo OLWC6NqthDcsDLioqLw6RY9NiUQVF2UvyzseXEsEUuvv+r9F/AGL8pRUO8LKkHLiCxrC cjvprptJpRlvZFEoLAHetQ6irE8K3oGMv+y7C77R1yK39jMCxxnrufyMwld7ZZNb3p4H eGtVs5VcJGe2x+1Xho0qtSnmMgLav6BRBUIP1Edv/+OT/uzJnhiGUd+LH81brTCuoqAw 03fg== X-Gm-Message-State: AOAM530YoVFKFSGDWJgbfUikUL5rcdHAhT6HArdi+iIP7koz4WDDkK/3 eJRvidTfZW9lVM1gnSmOVE/StA== X-Google-Smtp-Source: ABdhPJxQ/d3Sv9gi2O4ujiX7gArSmh8SNgGGt9acEP1EpuqHK/8LXXnU/cAx/OnoC1NU6nLSqIrKLA== X-Received: by 2002:a17:907:3f95:b0:6f4:f45a:9f66 with SMTP id hr21-20020a1709073f9500b006f4f45a9f66mr4397567ejc.544.1651867323816; Fri, 06 May 2022 13:02:03 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:03 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 2/6] ptp: Request cycles for TX timestamp Date: Fri, 6 May 2022 22:01:38 +0200 Message-Id: <20220506200142.3329-3-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The free running cycle counter of physical clocks called cycles shall be used for hardware timestamps to enable synchronisation. Introduce new flag SKBTX_HW_TSTAMP_USE_CYCLES, which signals driver to provide a TX timestamp based on cycles if cycles are supported. Signed-off-by: Gerhard Engleder Acked-by: Richard Cochran --- include/linux/skbuff.h | 7 ++++++- net/socket.c | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5c2599e3fe7d..4d49503bdc4d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -615,6 +615,9 @@ enum { /* device driver is going to provide hardware time stamp */ SKBTX_IN_PROGRESS = 1 << 2, + /* generate hardware time stamp based on cycles if supported */ + SKBTX_HW_TSTAMP_USE_CYCLES = 1 << 3, + /* generate wifi status information (where possible) */ SKBTX_WIFI_STATUS = 1 << 4, @@ -624,7 +627,9 @@ enum { #define SKBTX_ANY_SW_TSTAMP (SKBTX_SW_TSTAMP | \ SKBTX_SCHED_TSTAMP) -#define SKBTX_ANY_TSTAMP (SKBTX_HW_TSTAMP | SKBTX_ANY_SW_TSTAMP) +#define SKBTX_ANY_TSTAMP (SKBTX_HW_TSTAMP | \ + SKBTX_HW_TSTAMP_USE_CYCLES | \ + SKBTX_ANY_SW_TSTAMP) /* Definitions for flags in struct skb_shared_info */ enum { diff --git a/net/socket.c b/net/socket.c index f0c39c874665..5c1c5e6100e1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -683,9 +683,18 @@ void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) { u8 flags = *tx_flags; - if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) + if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) { flags |= SKBTX_HW_TSTAMP; + /* PTP hardware clocks can provide a free running cycle counter + * as a time base for virtual clocks. Tell driver to use the + * free running cycle counter for timestamp if socket is bound + * to virtual clock. + */ + if (tsflags & SOF_TIMESTAMPING_BIND_PHC) + flags |= SKBTX_HW_TSTAMP_USE_CYCLES; + } + if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) flags |= SKBTX_SW_TSTAMP; From patchwork Fri May 6 20:01:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841566 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E2B3C433F5 for ; Fri, 6 May 2022 20:02:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1392539AbiEFUF5 (ORCPT ); Fri, 6 May 2022 16:05:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1392501AbiEFUFv (ORCPT ); Fri, 6 May 2022 16:05:51 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F2F285F8D7 for ; Fri, 6 May 2022 13:02:06 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id i27so16350617ejd.9 for ; Fri, 06 May 2022 13:02:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=y1Dm+O/mM+AJLj+sXxq233PXJNN3alKJLc+V3CdaMRc=; b=vSXvwbQKckFNygZafx7S46AMCff80YbBjiR/slRIf0VL5L9WW/2maB1Se8188GPBMU U1EgiAVorpvBoSwmoFXrBhD39OnuF8TB7ReybtcZcIi0Ij5dBtey5kwQKgE16rVQqRl3 akyK66VVeupIpWtqOsZVpePYCp/WkM1sXBO4PmKUdgyKdVz/tQinfSP6FR1xAIXEv8bz AkHUk79fdPzTUKE/mMMybC/TyAzf5kwFoEmpCywZkcpcxMal6ZspEA2xJ99NWKyKX9/l s34v7vkufFSZ4GgsuHNY0qsgG0QlUrEb5iQUxvfAKvAhOYmi9CdekcM4tI3igvtDW66n vt0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=y1Dm+O/mM+AJLj+sXxq233PXJNN3alKJLc+V3CdaMRc=; b=23Zcc3nZzhaR5/7jhOAEiMKVzpn1pmjJTtMGO+BScvs9jyzjqc1TRDDX9wD1rkh3je 2rw7ZimPRbbIsuVVoHnmH3coFNbqMK/fhspVhdeiFQZqzGKxCUC0SZ0rowFD3qHqZ0gw iO6z8GSu/LIEzp8kn7/vec0BbFvj0oQ5vuVkjVHaikQilKwUYtQ8fBnqu8jnbuPUgE2g dHwcD0j4ogk+IJ/NhvRwtbzB5sv8apz8pvhAJPdF6SqWfr2cb0OnN6KOHyVbg+U97y3H LNXxc36lO3+8cOX6VyKHuuZXDUb4WJjdW63Q12AxnU8jNroQQi/x3yQ86YNAT5HgwkRi iDMg== X-Gm-Message-State: AOAM531ybF865EfouswjFvRoTUQX2Aq2Xw1pLEfatDgaERqMkzWkRLH+ X4og+IrOwl/DO4SesCt/u/Or2g== X-Google-Smtp-Source: ABdhPJwdrWG5RyjKQ60szhv50mVY33uzwJgdjcwfu8Rw4ZO2yuKOX1cK7zdnfr42TkS0883uuP19vg== X-Received: by 2002:a17:906:7013:b0:6f3:a9c3:6045 with SMTP id n19-20020a170906701300b006f3a9c36045mr4573268ejj.158.1651867325489; Fri, 06 May 2022 13:02:05 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:05 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 3/6] ptp: Pass hwtstamp to ptp_convert_timestamp() Date: Fri, 6 May 2022 22:01:39 +0200 Message-Id: <20220506200142.3329-4-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org ptp_convert_timestamp() converts only the timestamp hwtstamp, which is a field of the argument with the type struct skb_shared_hwtstamps *. So a pointer to the hwtstamp field of this structure is sufficient. Rework ptp_convert_timestamp() to use an argument of type ktime_t *. This allows to add additional timestamp manipulation stages before the call of ptp_convert_timestamp(). Signed-off-by: Gerhard Engleder Acked-by: Richard Cochran --- drivers/ptp/ptp_vclock.c | 5 ++--- include/linux/ptp_clock_kernel.h | 7 +++---- net/socket.c | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index 3a095eab9cc5..c30bcce2bb43 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -232,8 +232,7 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index) } EXPORT_SYMBOL(ptp_get_vclocks_index); -ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, - int vclock_index) +ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index) { char name[PTP_CLOCK_NAME_LEN] = ""; struct ptp_vclock *vclock; @@ -255,7 +254,7 @@ ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, vclock = info_to_vclock(ptp->info); - ns = ktime_to_ns(hwtstamps->hwtstamp); + ns = ktime_to_ns(*hwtstamp); spin_lock_irqsave(&vclock->lock, flags); ns = timecounter_cyc2time(&vclock->tc, ns); diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index ad309202cf9f..92b44161408e 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -384,17 +384,16 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index); /** * ptp_convert_timestamp() - convert timestamp to a ptp vclock time * - * @hwtstamps: skb_shared_hwtstamps structure pointer + * @hwtstamp: timestamp * @vclock_index: phc index of ptp vclock. * * Returns converted timestamp, or 0 on error. */ -ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, - int vclock_index); +ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index); #else static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index) { return 0; } -static inline ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, +static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index) { return 0; } diff --git a/net/socket.c b/net/socket.c index 5c1c5e6100e1..0f680c7d968a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -888,7 +888,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(shhwtstamps, + hwtstamp = ptp_convert_timestamp(&shhwtstamps->hwtstamp, sk->sk_bind_phc); else hwtstamp = shhwtstamps->hwtstamp; From patchwork Fri May 6 20:01:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841567 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0526CC433F5 for ; Fri, 6 May 2022 20:02:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1392523AbiEFUGC (ORCPT ); Fri, 6 May 2022 16:06:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1392485AbiEFUGB (ORCPT ); Fri, 6 May 2022 16:06:01 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F5D95F8C3 for ; Fri, 6 May 2022 13:02:17 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id gh6so16432548ejb.0 for ; Fri, 06 May 2022 13:02:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iVpcVd0AG8Qe/siFxqPItCTauXIAj/GtOoZ8PYCyTE4=; b=EpQsnl/4njl0PeNQG/BTsxgwTcy3d+KJ+oNRro1ONq5xQ2K47gZ9y4DpL1pLAByt+/ KPw17TAJkYe7WTXlf98dAOQGeAEJ/6lx9XfZBLulEYyR4CgBK51xys9s/HyQ2RROsyM4 Nx62Ze6FkKWmYt3pcQ1f9u6NWHwTVrmqwfisQmVL/doYYPBEXK6xBiKIr7tNoiyHh0Kf +gQ0I6NfvigwaCwSr88n6uCzPYXoSAGEmKKfalr89BmqsxQ82NahWbHPb6sHeIlXqMdL wvr/P8Nu/2TtNsVWAUVnPpHeRfoFyOklNF4NPZqg1LF7k6WHk4l8nmoko8f20kF1qQz5 mzWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iVpcVd0AG8Qe/siFxqPItCTauXIAj/GtOoZ8PYCyTE4=; b=X8NegNw0kmroTR0UByDNNn9lwWQ0AqPUJscLrJ1UTY6hP4YPuMEx1NFgUa6Two0Duu RiC9frCPTX+5R05N7svfu+HY27X341b4gP4owz8zuV+mmoO5vMX/ESlXITLW48otirR5 aLBg5cMLftNxG8v6UeF+OSSM2jwB/B8XOhMAITFMrvsdMZ4gEkIx3XdEkEW1dcFBFfA2 da1K257j4UHkgoxtP4c+ocDAKsL4J220AN2jWtATvxw8mIZg6M9L4eWxmgaVk5LdECqW VQpi9ZRb9PtP1y4xBXO3nYsIg2pMtYDUOmy6Tqk+aLFD2HUfg7jBsCvFNSu/Ay2FkYGO dRdw== X-Gm-Message-State: AOAM532SVJqiXL0Fo3GbKPq4ePmSN+rAKiUxviRf5dJE8EZvCnwNaM/b jncAJ05Ma7LOO79pHolMgZVbng== X-Google-Smtp-Source: ABdhPJymzoUwFcmP2ccMnDWK95Lmqx2Etz3/sGKKlDE0XaOsvS469Xd9x8j6VgtHbz7H4X/qBznnVw== X-Received: by 2002:a17:907:2064:b0:6f4:3f07:c76e with SMTP id qp4-20020a170907206400b006f43f07c76emr4527619ejb.462.1651867335949; Fri, 06 May 2022 13:02:15 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:15 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 4/6] ptp: Support late timestamp determination Date: Fri, 6 May 2022 22:01:40 +0200 Message-Id: <20220506200142.3329-5-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org If a physical clock supports a free running cycle counter, then timestamps shall be based on this time too. For TX it is known in advance before the transmission if a timestamp based on the free running cycle counter is needed. For RX it is impossible to know which timestamp is needed before the packet is received and assigned to a socket. Support late timestamp determination by a network device. Therefore, an address/cookie is stored within the new netdev_data field of struct skb_shared_hwtstamps. This address/cookie is provided to a new network device function called ndo_get_tstamp(), which returns a timestamp based on the normal/adjustable time or based on the free running cycle counter. If function is not supported, then timestamp handling is not changed. This mechanism is intended for RX, but TX use is also possible. Signed-off-by: Gerhard Engleder Acked-by: Jonathan Lemon Acked-by: Richard Cochran --- include/linux/netdevice.h | 21 +++++++++++++++++ include/linux/skbuff.h | 14 ++++++++--- net/socket.c | 49 +++++++++++++++++++++++++++++++-------- 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8cf0ac616cb9..efd136b2d177 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1356,6 +1356,12 @@ struct netdev_net_notifier { * The caller must be under RCU read context. * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); * Get the forwarding path to reach the real device from the HW destination address + * ktime_t (*ndo_get_tstamp)(struct net_device *dev, + * const struct skb_shared_hwtstamps *hwtstamps, + * bool cycles); + * Get hardware timestamp based on normal/adjustable time or free running + * cycle counter. This function is required if physical clock supports a + * free running cycle counter. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1578,6 +1584,9 @@ struct net_device_ops { struct net_device * (*ndo_get_peer_dev)(struct net_device *dev); int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); + ktime_t (*ndo_get_tstamp)(struct net_device *dev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles); }; /** @@ -4761,6 +4770,18 @@ static inline void netdev_rx_csum_fault(struct net_device *dev, void net_enable_timestamp(void); void net_disable_timestamp(void); +static inline ktime_t netdev_get_tstamp(struct net_device *dev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles) +{ + const struct net_device_ops *ops = dev->netdev_ops; + + if (ops->ndo_get_tstamp) + return ops->ndo_get_tstamp(dev, hwtstamps, cycles); + + return hwtstamps->hwtstamp; +} + static inline netdev_tx_t __netdev_start_xmit(const struct net_device_ops *ops, struct sk_buff *skb, struct net_device *dev, bool more) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4d49503bdc4d..878b2631324c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -588,8 +588,10 @@ static inline bool skb_frag_must_loop(struct page *p) /** * struct skb_shared_hwtstamps - hardware time stamps - * @hwtstamp: hardware time stamp transformed into duration - * since arbitrary point in time + * @hwtstamp: hardware time stamp transformed into duration + * since arbitrary point in time + * @netdev_data: address/cookie of network device driver used as + * reference to actual hardware time stamp * * Software time stamps generated by ktime_get_real() are stored in * skb->tstamp. @@ -601,7 +603,10 @@ static inline bool skb_frag_must_loop(struct page *p) * &skb_shared_info. Use skb_hwtstamps() to get a pointer. */ struct skb_shared_hwtstamps { - ktime_t hwtstamp; + union { + ktime_t hwtstamp; + void *netdev_data; + }; }; /* Definitions for tx_flags in struct skb_shared_info */ @@ -621,6 +626,9 @@ enum { /* generate wifi status information (where possible) */ SKBTX_WIFI_STATUS = 1 << 4, + /* determine hardware time stamp based on time or cycles */ + SKBTX_HW_TSTAMP_NETDEV = 1 << 5, + /* generate software time stamp when entering packet scheduling */ SKBTX_SCHED_TSTAMP = 1 << 6, }; diff --git a/net/socket.c b/net/socket.c index 0f680c7d968a..6ee634c01eca 100644 --- a/net/socket.c +++ b/net/socket.c @@ -805,7 +805,28 @@ static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) return skb->tstamp && !false_tstamp && skb_is_err_queue(skb); } -static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb) +static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index) +{ + bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC; + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + struct net_device *orig_dev; + ktime_t hwtstamp; + + rcu_read_lock(); + orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); + if (orig_dev) { + *if_index = orig_dev->ifindex; + hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, cycles); + } else { + hwtstamp = shhwtstamps->hwtstamp; + } + rcu_read_unlock(); + + return hwtstamp; +} + +static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, + int if_index) { struct scm_ts_pktinfo ts_pktinfo; struct net_device *orig_dev; @@ -815,11 +836,14 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb) memset(&ts_pktinfo, 0, sizeof(ts_pktinfo)); - rcu_read_lock(); - orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); - if (orig_dev) - ts_pktinfo.if_index = orig_dev->ifindex; - rcu_read_unlock(); + if (!if_index) { + rcu_read_lock(); + orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); + if (orig_dev) + if_index = orig_dev->ifindex; + rcu_read_unlock(); + } + ts_pktinfo.if_index = if_index; ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb); put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO, @@ -839,6 +863,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + int if_index; ktime_t hwtstamp; /* Race occurred between timestamp enabling and packet @@ -887,18 +912,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, if (shhwtstamps && (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { - if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(&shhwtstamps->hwtstamp, - sk->sk_bind_phc); + if_index = 0; + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) + hwtstamp = get_timestamp(sk, skb, &if_index); else hwtstamp = shhwtstamps->hwtstamp; + if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) + hwtstamp = ptp_convert_timestamp(&hwtstamp, + sk->sk_bind_phc); + if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { empty = 0; if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && !skb_is_err_queue(skb)) - put_ts_pktinfo(msg, skb); + put_ts_pktinfo(msg, skb, if_index); } } if (!empty) { From patchwork Fri May 6 20:01:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841568 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1ACAC433F5 for ; Fri, 6 May 2022 20:02:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1390742AbiEFUGT (ORCPT ); Fri, 6 May 2022 16:06:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1392566AbiEFUGE (ORCPT ); Fri, 6 May 2022 16:06:04 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E715D5F8C3 for ; Fri, 6 May 2022 13:02:19 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id kq17so16388195ejb.4 for ; Fri, 06 May 2022 13:02:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xoVsRGejc7SLTpulyc05jnVi3zahQUiuPmNIltw8heM=; b=xDUui9fcqirnMiIQzuI/5wo90GL76WVLQEJMSke/dv/Y9P8px4QCotZ7bkaEVJQ4LP lO0HJv0WoKa51wHQ5A4wWocKGnf+b2C4MZWGB/46Oft3o4gq4OtZAoRtP+3PDMlctIag u3DTr1DP2n6yOFHYQiZx452Kyc+oXdW6ed1QMnKRWdiJx1DQqPuTjbKO9IO42EqU5i5z wdgo1LcMP55W2WdG/YEo17McawPTXFWzI3iK07fiTl34lSW7TLshUrGVp9+jgSUFA2fd lfU7hzNEuJkAkG+OdACU66bQ02uzHpao3NMQ522Z8LosZMoyO1h/IWKcixe0F4FXkeMF LUcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xoVsRGejc7SLTpulyc05jnVi3zahQUiuPmNIltw8heM=; b=oWDWmnyLDgUs2aSqf/vOWqYzt9uIftCt6AeWgFSxgu78lO8UOcnXSbdBOG1ewHfIIv Ujj8/O+27VvcrkAfbk7Srt6Sz2/RiZunDUrUam1TDbeUTpVVtaX6MjpLzDKB5dpz5gg6 RhKnQTD+C+2z8F7WSYn5Pt9rs961IiyqLRq9ar2iyGgfKF/9iTClGmjANJQ4khAEIGpq MhXaUDw7Amry0MD/hEdgWf427KNn694tKxjSvbGfZuDNAvgmaxLdiZ1PLg1YBLdPdLv0 pGQwxHtsJW5LBOqh7SAaScVsdon8nLAvxTMGMCqv7O9NZSIBM48iso6hTHISXAjdgi0G J6QA== X-Gm-Message-State: AOAM5313QqHy7glpeowcjuleLlwX1SzptImZlXkafSX25OJ05e1czQlT iadhMwPfm12Wvm4lfj3pc3simQ== X-Google-Smtp-Source: ABdhPJxERB7WBKs358mL5A+qWxnO8Ul5y7PT4SEX8uDDz1vXqmyq4DKz+AHg24ShL8yn+qIpw2zjAA== X-Received: by 2002:a17:907:6d24:b0:6f4:bc43:e7d1 with SMTP id sa36-20020a1709076d2400b006f4bc43e7d1mr4376145ejc.581.1651867338453; Fri, 06 May 2022 13:02:18 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:18 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 5/6] ptp: Speed up vclock lookup Date: Fri, 6 May 2022 22:01:41 +0200 Message-Id: <20220506200142.3329-6-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org ptp_convert_timestamp() is called in the RX path of network messages. The current implementation takes ~5000ns on 1.2GHz A53. This is too much for the hot path of packet processing. Introduce hash table for fast vclock lookup in ptp_convert_timestamp(). The execution time of ptp_convert_timestamp() is reduced to ~700ns on 1.2GHz A53. Signed-off-by: Gerhard Engleder Acked-by: Richard Cochran --- drivers/ptp/ptp_private.h | 1 + drivers/ptp/ptp_vclock.c | 66 ++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index ab47c10b3874..77918a2c6701 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -63,6 +63,7 @@ struct ptp_vclock { struct ptp_clock *pclock; struct ptp_clock_info info; struct ptp_clock *clock; + struct hlist_node vclock_hash_node; struct cyclecounter cc; struct timecounter tc; spinlock_t lock; /* protects tc/cc */ diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index c30bcce2bb43..1c0ed4805c0a 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -5,6 +5,7 @@ * Copyright 2021 NXP */ #include +#include #include "ptp_private.h" #define PTP_VCLOCK_CC_SHIFT 31 @@ -13,6 +14,32 @@ #define PTP_VCLOCK_FADJ_DENOMINATOR 15625ULL #define PTP_VCLOCK_REFRESH_INTERVAL (HZ * 2) +/* protects vclock_hash addition/deletion */ +static DEFINE_SPINLOCK(vclock_hash_lock); + +static DEFINE_READ_MOSTLY_HASHTABLE(vclock_hash, 8); + +static void ptp_vclock_hash_add(struct ptp_vclock *vclock) +{ + spin_lock(&vclock_hash_lock); + + hlist_add_head_rcu(&vclock->vclock_hash_node, + &vclock_hash[vclock->clock->index % HASH_SIZE(vclock_hash)]); + + spin_unlock(&vclock_hash_lock); +} + +static void ptp_vclock_hash_del(struct ptp_vclock *vclock) +{ + spin_lock(&vclock_hash_lock); + + hlist_del_init_rcu(&vclock->vclock_hash_node); + + spin_unlock(&vclock_hash_lock); + + synchronize_rcu(); +} + static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) { struct ptp_vclock *vclock = info_to_vclock(ptp); @@ -176,6 +203,8 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock) snprintf(vclock->info.name, PTP_CLOCK_NAME_LEN, "ptp%d_virt", pclock->index); + INIT_HLIST_NODE(&vclock->vclock_hash_node); + spin_lock_init(&vclock->lock); vclock->clock = ptp_clock_register(&vclock->info, &pclock->dev); @@ -187,11 +216,15 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock) timecounter_init(&vclock->tc, &vclock->cc, 0); ptp_schedule_worker(vclock->clock, PTP_VCLOCK_REFRESH_INTERVAL); + ptp_vclock_hash_add(vclock); + return vclock; } void ptp_vclock_unregister(struct ptp_vclock *vclock) { + ptp_vclock_hash_del(vclock); + ptp_clock_unregister(vclock->clock); kfree(vclock); } @@ -234,34 +267,29 @@ EXPORT_SYMBOL(ptp_get_vclocks_index); ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index) { - char name[PTP_CLOCK_NAME_LEN] = ""; + unsigned int hash = vclock_index % HASH_SIZE(vclock_hash); struct ptp_vclock *vclock; - struct ptp_clock *ptp; unsigned long flags; - struct device *dev; u64 ns; + u64 vclock_ns = 0; - snprintf(name, PTP_CLOCK_NAME_LEN, "ptp%d", vclock_index); - dev = class_find_device_by_name(ptp_class, name); - if (!dev) - return 0; + ns = ktime_to_ns(*hwtstamp); - ptp = dev_get_drvdata(dev); - if (!ptp->is_virtual_clock) { - put_device(dev); - return 0; - } + rcu_read_lock(); - vclock = info_to_vclock(ptp->info); + hlist_for_each_entry_rcu(vclock, &vclock_hash[hash], vclock_hash_node) { + if (vclock->clock->index != vclock_index) + continue; - ns = ktime_to_ns(*hwtstamp); + spin_lock_irqsave(&vclock->lock, flags); + vclock_ns = timecounter_cyc2time(&vclock->tc, ns); + spin_unlock_irqrestore(&vclock->lock, flags); + break; + } - spin_lock_irqsave(&vclock->lock, flags); - ns = timecounter_cyc2time(&vclock->tc, ns); - spin_unlock_irqrestore(&vclock->lock, flags); + rcu_read_unlock(); - put_device(dev); - return ns_to_ktime(ns); + return ns_to_ktime(vclock_ns); } EXPORT_SYMBOL(ptp_convert_timestamp); #endif From patchwork Fri May 6 20:01:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12841569 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4DD5C4332F for ; Fri, 6 May 2022 20:02:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1392604AbiEFUGV (ORCPT ); Fri, 6 May 2022 16:06:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1392578AbiEFUGG (ORCPT ); Fri, 6 May 2022 16:06:06 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EB1D60AA3 for ; Fri, 6 May 2022 13:02:22 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id g23so9859754edy.13 for ; Fri, 06 May 2022 13:02:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+5h3vX/uenadcWCVCAzeCC1leutd8xV6aDGFHYcrbP8=; b=hW78uJckmdYar4F9Ge7M2Gyhf4EhCdGmDhIfqzfZkvS3OnNqe9ztZKGoi2DYZgan0A rk3U8UmQwtmDDr4DLV1w/QvsW87C+t8kr4DGH0oqUWXiGas0jWGRrfhFF61yJmAoRhyn 5uPMzNSBiCx7uK37mAzakQU0ElCcs7sdkG6O7kelgeLBypVQ5sdXQjsD4eHnyJPm21F0 7TnJqxvCbQcdqsn6k+VIVSpNATszOqMmpC0QiLSWkXl09o7IWz1ooQSy0bdI1vAZKKdo q84SBJ2p7snfSF8G0kOzjKmWKrZWyPMy/ql+oUtaS1urpGm9oQL2kwygfoE+q+Ip1cTo W08g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+5h3vX/uenadcWCVCAzeCC1leutd8xV6aDGFHYcrbP8=; b=6r6vu/CuOEb06Uks4L/sU0VlrEizKxJEVG5fMHcy383cl14MfOsJfDzh5tWY+bEOYM w0+bUjKmK14fznxD33yly9qx6IMjmVV0houONt5yJEwwMzTX8pt32pcMy0XQQPWP6mbC Cl6sWmwkDnajRLaxjRhJ3EaE04wLRQgATcNJn2bSjDp46fiJWgrcTrBUdXQB7aaX7V1n R5/WqGp8oOElKnl5LUbWRXddn3QlKqvbdqcJ8F8rUIK9jr61yxqfLRbtu3SCaseeAJ/2 weklueORIqOho94wDlkTL8yxVmk8xBjUFlw4fqufvQVd4sLBm2KG9UjS2FOFpbNOD0/A MaxA== X-Gm-Message-State: AOAM532wnqtJzWaCPDjBxC6c8KAveeOkeRYL+3jtFpmNnQ0eACQ2Y0Nc n7kOwV1ISXAi9+WW+orPStNo4A== X-Google-Smtp-Source: ABdhPJzkLlmrOeaOiuSsFSci6pSgQmVtoF5dtlGG5wEozepniq94L2BXVufKkvRpoVfrxtsnpUFX/A== X-Received: by 2002:a05:6402:370b:b0:41d:8508:20af with SMTP id ek11-20020a056402370b00b0041d850820afmr5310370edb.16.1651867341058; Fri, 06 May 2022 13:02:21 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:237:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id w5-20020a056402268500b0042617ba6389sm2719887edd.19.2022.05.06.13.02.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 13:02:20 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, willemb@google.com, kafai@fb.com, jonathan.lemon@gmail.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v4 6/6] tsnep: Add free running cycle counter support Date: Fri, 6 May 2022 22:01:42 +0200 Message-Id: <20220506200142.3329-7-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220506200142.3329-1-gerhard@engleder-embedded.com> References: <20220506200142.3329-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The TSN endpoint Ethernet MAC supports a free running counter additionally to its clock. This free running counter can be read and hardware timestamps are supported. As the name implies, this counter cannot be set and its frequency cannot be adjusted. Add free running cycle counter support based on this free running counter to physical clock. This also requires hardware time stamps based on that free running counter. Signed-off-by: Gerhard Engleder Acked-by: Jonathan Lemon --- drivers/net/ethernet/engleder/tsnep_hw.h | 9 ++++-- drivers/net/ethernet/engleder/tsnep_main.c | 33 ++++++++++++++++++---- drivers/net/ethernet/engleder/tsnep_ptp.c | 28 ++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/engleder/tsnep_hw.h b/drivers/net/ethernet/engleder/tsnep_hw.h index 71cc8577d640..916ceac3ada2 100644 --- a/drivers/net/ethernet/engleder/tsnep_hw.h +++ b/drivers/net/ethernet/engleder/tsnep_hw.h @@ -43,6 +43,10 @@ #define ECM_RESET_CHANNEL 0x00000100 #define ECM_RESET_TXRX 0x00010000 +/* counter */ +#define ECM_COUNTER_LOW 0x0028 +#define ECM_COUNTER_HIGH 0x002C + /* control and status */ #define ECM_STATUS 0x0080 #define ECM_LINK_MODE_OFF 0x01000000 @@ -190,7 +194,8 @@ struct tsnep_tx_desc { /* tsnep TX descriptor writeback */ struct tsnep_tx_desc_wb { __le32 properties; - __le32 reserved1[3]; + __le32 reserved1; + __le64 counter; __le64 timestamp; __le32 dma_delay; __le32 reserved2; @@ -221,7 +226,7 @@ struct tsnep_rx_desc_wb { /* tsnep RX inline meta */ struct tsnep_rx_inline { - __le64 reserved; + __le64 counter; __le64 timestamp; }; diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c index 49c93aa38862..cb069a0af7b9 100644 --- a/drivers/net/ethernet/engleder/tsnep_main.c +++ b/drivers/net/ethernet/engleder/tsnep_main.c @@ -470,8 +470,15 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) (__le32_to_cpu(entry->desc_wb->properties) & TSNEP_DESC_EXTENDED_WRITEBACK_FLAG)) { struct skb_shared_hwtstamps hwtstamps; - u64 timestamp = - __le64_to_cpu(entry->desc_wb->timestamp); + u64 timestamp; + + if (skb_shinfo(entry->skb)->tx_flags & + SKBTX_HW_TSTAMP_USE_CYCLES) + timestamp = + __le64_to_cpu(entry->desc_wb->counter); + else + timestamp = + __le64_to_cpu(entry->desc_wb->timestamp); memset(&hwtstamps, 0, sizeof(hwtstamps)); hwtstamps.hwtstamp = ns_to_ktime(timestamp); @@ -704,11 +711,11 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi, skb_hwtstamps(skb); struct tsnep_rx_inline *rx_inline = (struct tsnep_rx_inline *)skb->data; - u64 timestamp = - __le64_to_cpu(rx_inline->timestamp); + skb_shinfo(skb)->tx_flags |= + SKBTX_HW_TSTAMP_NETDEV; memset(hwtstamps, 0, sizeof(*hwtstamps)); - hwtstamps->hwtstamp = ns_to_ktime(timestamp); + hwtstamps->netdev_data = rx_inline; } skb_pull(skb, TSNEP_RX_INLINE_METADATA_SIZE); skb->protocol = eth_type_trans(skb, @@ -1010,6 +1017,21 @@ static int tsnep_netdev_set_mac_address(struct net_device *netdev, void *addr) return 0; } +static ktime_t tsnep_netdev_get_tstamp(struct net_device *netdev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles) +{ + struct tsnep_rx_inline *rx_inline = hwtstamps->netdev_data; + u64 timestamp; + + if (cycles) + timestamp = __le64_to_cpu(rx_inline->counter); + else + timestamp = __le64_to_cpu(rx_inline->timestamp); + + return ns_to_ktime(timestamp); +} + static const struct net_device_ops tsnep_netdev_ops = { .ndo_open = tsnep_netdev_open, .ndo_stop = tsnep_netdev_close, @@ -1019,6 +1041,7 @@ static const struct net_device_ops tsnep_netdev_ops = { .ndo_get_stats64 = tsnep_netdev_get_stats64, .ndo_set_mac_address = tsnep_netdev_set_mac_address, + .ndo_get_tstamp = tsnep_netdev_get_tstamp, .ndo_setup_tc = tsnep_tc_setup, }; diff --git a/drivers/net/ethernet/engleder/tsnep_ptp.c b/drivers/net/ethernet/engleder/tsnep_ptp.c index eaad453d487e..54fbf0126815 100644 --- a/drivers/net/ethernet/engleder/tsnep_ptp.c +++ b/drivers/net/ethernet/engleder/tsnep_ptp.c @@ -175,6 +175,33 @@ static int tsnep_ptp_settime64(struct ptp_clock_info *ptp, return 0; } +static int tsnep_ptp_getcyclesx64(struct ptp_clock_info *ptp, + struct timespec64 *ts, + struct ptp_system_timestamp *sts) +{ + struct tsnep_adapter *adapter = container_of(ptp, struct tsnep_adapter, + ptp_clock_info); + u32 high_before; + u32 low; + u32 high; + u64 counter; + + /* read high dword twice to detect overrun */ + high = ioread32(adapter->addr + ECM_COUNTER_HIGH); + do { + ptp_read_system_prets(sts); + low = ioread32(adapter->addr + ECM_COUNTER_LOW); + ptp_read_system_postts(sts); + high_before = high; + high = ioread32(adapter->addr + ECM_COUNTER_HIGH); + } while (high != high_before); + counter = (((u64)high) << 32) | ((u64)low); + + *ts = ns_to_timespec64(counter); + + return 0; +} + int tsnep_ptp_init(struct tsnep_adapter *adapter) { int retval = 0; @@ -192,6 +219,7 @@ int tsnep_ptp_init(struct tsnep_adapter *adapter) adapter->ptp_clock_info.adjtime = tsnep_ptp_adjtime; adapter->ptp_clock_info.gettimex64 = tsnep_ptp_gettimex64; adapter->ptp_clock_info.settime64 = tsnep_ptp_settime64; + adapter->ptp_clock_info.getcyclesx64 = tsnep_ptp_getcyclesx64; spin_lock_init(&adapter->ptp_lock);