From patchwork Sun May 1 11:18:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833632 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 989AAC433EF for ; Sun, 1 May 2022 11:18:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345559AbiEALWN (ORCPT ); Sun, 1 May 2022 07:22:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345385AbiEALWL (ORCPT ); Sun, 1 May 2022 07:22:11 -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 2F75758396 for ; Sun, 1 May 2022 04:18:46 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id g6so23204260ejw.1 for ; Sun, 01 May 2022 04:18:46 -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=2+tgQ3MW5K8CiRl7KCQ7JglXb9SN1XdyiSu4v/rkzws=; b=RhCcW6zsDjjnj38vly49lDDbQ+MKyu2EgCvLtYtfRVWTppj/jXXi495VZ0CoZPLJyv hJZ2GLm0zJ+xBhrkbTzF7vdDsHQXjsHyAiN883K2m1F9C5V+zfkFwDqBcu22X4p+dYqR goSku95VX1gxVZ4Xh33rf36cDtfnSUs7uwyHCK3RUdKh1arN2cKKrOPEW1f2Rj4XpMxb mnpEATXDHz8qoea7Xxf+aFyuD96QzggTApd4qPARxgWDE7a0zdnw48Q+XzjodYrsRwg8 lntzJ15McAZxyoeLetR1Tpom/st+tz3RTpe+Jv7H9OwvK78L5Qvh/xB+9XiHBj6pBI2p JL+A== 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=2+tgQ3MW5K8CiRl7KCQ7JglXb9SN1XdyiSu4v/rkzws=; b=17+1g+eOgrEJz0SMrcRxUcft0zT0gi8GyuCJkSHzb1LTKBk7yGMuNDHkRf51FPe/l2 t31SkWse8sZd/EG8HhipF+hYSYGcZyuD9Z4vNpxU5lPCIh/uVXLzbyWW+I1CmlNMKPwX 1BIh1tUSaTwvha45OeFHXwOJe5CkQFsY+tWKNoh6iAdEl39vJDHc+PmZMSCiAQmB5BgE D4feZ3GwxJafTVs3kl84jM4PlNZlQDNxZvQBk3d+hdzryUsAUt4iL32ftNVK3y0Dzn2k TwMfy2ygV7pOzMkBOU5wvGvbvVKqZmOuTMhswtqHEHZI9WLVtRvJYes4uta4nJ43bURR /2aA== X-Gm-Message-State: AOAM532J5nf5gbhxBEuWzIroHkrWerLA+DTuYLWV/BsyErXnt1kTYQ/L ViBm1AV7e1Sg0OWUOwyAffYuug== X-Google-Smtp-Source: ABdhPJwIpFissKA3YPGaabaNc3wBSCK9cjEz740BU6APVMxtIPU5yIJeVwwkYCuIQI1+ezDkqEKIcQ== X-Received: by 2002:a17:906:f85:b0:6d6:e97b:d276 with SMTP id q5-20020a1709060f8500b006d6e97bd276mr6908194ejj.431.1651403924720; Sun, 01 May 2022 04:18:44 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:44 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 1/6] ptp: Add cycles support for virtual clocks Date: Sun, 1 May 2022 13:18:31 +0200 Message-Id: <20220501111836.10910-2-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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 Sun May 1 11:18:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833633 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 D8E85C433EF for ; Sun, 1 May 2022 11:18:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345594AbiEALWQ (ORCPT ); Sun, 1 May 2022 07:22:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345546AbiEALWM (ORCPT ); Sun, 1 May 2022 07:22:12 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B1FC5838B for ; Sun, 1 May 2022 04:18:47 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id k27so13756632edk.4 for ; Sun, 01 May 2022 04:18:47 -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=qhxJ8TkbsGQ2o/H5s5bVuFWnK8y7lni9lVUTJ46OVMo=; b=bAyhFQiyZaX/HUrZBI2x0ALy2XXJB+ThfPrs6GxgpACr9BPTXNqUUOETCXOyhlh7Pz M3iR5llVyhhyCet6FkXNw9t05ULkUK1gyq2/DAh1iZjmZa1+gVBDJGxNmNz3CRZFCRzm aqRYHGNGaKhb+85vUgbQBpoH+lgH6UDs37LIG7I7JSEil8wzUCPJEwxSuEM1z4Jeysoy UTMGK6mEE+AswhY04KxFvPCJITE4PP3N9J6mmEM+5UbK+s3AhyAfVL+PoILG1LNsiVYW NAtdHHXM7xXPWMJlpfuWcv7E2Ql9RKKMeEOamEXPKSCLWSUz7cHHHJWN4D8l7E4f5r/6 IhgA== 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=qhxJ8TkbsGQ2o/H5s5bVuFWnK8y7lni9lVUTJ46OVMo=; b=KwyZLPBUHevEW8qw9PWk68P+JjetMxklsQDZl1ZMdNCiKG5j47GqdxNwePoalkRPqg j+Pndk9hTWxq+teWIXQVO+RQUgYjeG79gOuX5JjtSvlDbzg75JyI1p08Lg9lEigSVUrz pm31BF+yyhDETq6XNo6dpOIQ7ihpA/uc0MfjKOv2ZZ6CFac1AI3Rmy6xuT80tY7a0FjY GSBY6VOH0F4Cs1W0Ld8kq9jHIollE6JQczAosPvUNbhilki1BonlGCYkwkyMOzK7glPH 6xHExyEfgfYMHb6QwD9ApbnTqTTgQ2mOZjOpMZdmKtMhndvNoJ7KYdtc1gbhFBLE1N6k E3cQ== X-Gm-Message-State: AOAM532hcRLOPeTmwirkutE83K7iVbyWu0uK64l7+lKirqyHSuS+6wyU 9IkyzwfBhYsnseC79y6jWo7FLQ== X-Google-Smtp-Source: ABdhPJzvAriITX0OwgujwDSkJEdvW4OzDBWqD4Ye6sfPYXipb2d72aPIdRfVm0MeAJFCSL1zpw5xfA== X-Received: by 2002:aa7:db48:0:b0:425:f93a:de5b with SMTP id n8-20020aa7db48000000b00425f93ade5bmr8345142edt.169.1651403926172; Sun, 01 May 2022 04:18:46 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:45 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 2/6] ptp: Request cycles for TX timestamp Date: Sun, 1 May 2022 13:18:32 +0200 Message-Id: <20220501111836.10910-3-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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 | 5 +++++ net/core/skbuff.c | 5 +++++ net/socket.c | 11 ++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 3270cb72e4d8..fa03e02b761d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -615,6 +615,11 @@ enum { /* device driver is going to provide hardware time stamp */ SKBTX_IN_PROGRESS = 1 << 2, + /* generate hardware time stamp based on cycles if supported, flag is + * used only for TX path + */ + SKBTX_HW_TSTAMP_USE_CYCLES = 1 << 3, + /* generate wifi status information (where possible) */ SKBTX_WIFI_STATUS = 1 << 4, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b92e93dcaa91..62d6d143dd70 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4841,6 +4841,11 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags & SKBTX_ANY_TSTAMP; skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; + } else { + /* Do not clone SKBTX_HW_TSTAMP_USE_CYCLES flag to enable reuse + * of the same bit in RX path. + */ + skb_shinfo(skb)->tx_flags &= ~SKBTX_HW_TSTAMP_USE_CYCLES; } if (hwtstamps) 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 Sun May 1 11:18:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833634 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 28BF7C433FE for ; Sun, 1 May 2022 11:18:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345600AbiEALWR (ORCPT ); Sun, 1 May 2022 07:22:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345385AbiEALWO (ORCPT ); Sun, 1 May 2022 07:22:14 -0400 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B98258397 for ; Sun, 1 May 2022 04:18:49 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id g6so23204350ejw.1 for ; Sun, 01 May 2022 04:18:49 -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=51XC0LQQxOXxXqMObA872OrbYtGY07NzWyYDzgulOfgAnOnRZx7WiknwSo2WkEuTlk 7gNtq2p0t68o6UMgwNNbH2Y09HO5HoL01WF25LbonqRhGCHnFWipRmJDI9bwRe83yRDF YQyDHoNqVmt1SAFbgsGGd5UR3tUHNrInEl44zh4WglHkX1lWQ+KzHbkSSGHbq1GfwHTm LltqudPjDEld67Pft3ru4iZklg8uQhpi9Pf4nVJaFnwrWzaI/zjK3O28aRnS+Ek5c+sF PkoDR5mqcfWHNVBC0ZuXsyNrSkzyISA5OWBwccKjxGJ5ZQUA3HUBj0CGpSZKmnEEz6EO YMoA== 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=L2DsY8gNC3LYz0bESmRaPJQCBwUf/yj1j72VVqGhvOqps9rqp2Y4XmBvlL4KQ7Znx1 rLPJhP+2HUj0g7vqwlx3nN1xGq76iWgP4QRDXqgsrpOXmEAztfZj3H/mXwjd7TSEO2st /VOey9C7iQYAIaM0BgstSVQc3yDTP30H8mlv8fLTzFON/tk/ZVdT47RPcmP/l2V0kOT8 5UgUnEx7GwnJwO3yRP0bKc2w8phE4E0+mY4pqXDCN9JltPuzrtQZgWaCcdZK46ImjY1N 8+AB5dLZd57Aaa2TOjf3OlA57KsWnwANBQ2NYqAWNbP8NZnUW24te1+lTh8zxU3Ll8RW A9KQ== X-Gm-Message-State: AOAM532qYb3AaaJjludMEP+py5UrIm2XiN6Jj/xa7mRRFSGQFUNYOI/b u+UBr7gvRvBFgLBxCdRf++aWSA== X-Google-Smtp-Source: ABdhPJzDxhCLEBT5IjkNjqsLCTXOqSiQeqOZ53pOiLnCdh2uRLDSDzEiKGvS3zVRGQj4BVYyf+O8Gw== X-Received: by 2002:a17:907:62a9:b0:6da:7953:4df0 with SMTP id nd41-20020a17090762a900b006da79534df0mr6969617ejc.316.1651403927693; Sun, 01 May 2022 04:18:47 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:47 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 3/6] ptp: Pass hwtstamp to ptp_convert_timestamp() Date: Sun, 1 May 2022 13:18:33 +0200 Message-Id: <20220501111836.10910-4-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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 Sun May 1 11:18:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833635 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 92132C433F5 for ; Sun, 1 May 2022 11:19:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345695AbiEALWX (ORCPT ); Sun, 1 May 2022 07:22:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345582AbiEALWQ (ORCPT ); Sun, 1 May 2022 07:22:16 -0400 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92B6F5839D for ; Sun, 1 May 2022 04:18:50 -0700 (PDT) Received: by mail-ej1-x62f.google.com with SMTP id g6so23204408ejw.1 for ; Sun, 01 May 2022 04:18:50 -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=zLKxszwrDFN/dR0IJoh4fSrQHIouGtTLadQ9gaYTD34=; b=lQ+915JJej8dDOVn2KNr5OptN5uur4+DqK7SbBzCYwOvFDWHEs/zPrMfqw00/iun0m MFVYG/Q6KbiRELem5Ok7XVXp68TEkKb8KD44kMslWHgrDyUDD/j4iVIZPRFQ3FC5Dd+W adwMdqQpQIFZ+uM+7zf9cz2E3sxmz4Zou1z8yFXOg9ZsXFegmZ/kaDP0vpyOWKlhd9ax 5er5loF1AoAgBunWjpKGPcF4pIFn3ZtzOWf4TN8ZoDih4lDcumxV9Jobn7EIJjgvH/Ho MELx4xDtmwxtrxLRe866RKqLZUryO32OZO6VH8bm/u3at9BOe233611paaQ2fGKYNH9V KPeA== 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=zLKxszwrDFN/dR0IJoh4fSrQHIouGtTLadQ9gaYTD34=; b=dHuGU6jSGqrt11QJI03PTz0CbgCU/1BpxAY/SKLC3KGEClZqKptjAhdSMgb3XBJraP PduyUfbX1U62z/VsKokNk5woii3mK27wagnv6n5a9R8YvYMQGDi/mGOWAKaoFQtv4gUw 8Chm7hq75/XrkvlpoMo02f6oL9xYM3be0cfxOZREVjIKrY9QcC6QlVfUTKaKORUCJ8ko vr28VLq0bP1W32RiG0XhFFJTSk1loZ3ed32k1J4RWKOjFSo/vDnbm3MEiDANa4dBKXxv jeCMC6/oNmM7sjJq2525RmsABjNxcTL10zCMno83BMVoxFjNOO2OXU3LZmFPo0QG+Rdl qqLg== X-Gm-Message-State: AOAM532N+/xVUUWHQ1mL0DRoK8dZRCuzvwZK6Sx9mDJgs0+7TbMIDk+c 6AXnWDwtKI6Wtl5twxFsWZF4tg== X-Google-Smtp-Source: ABdhPJw8uiwWNRD0DFQQmxGQgdg/63aysIme+woIHrKXD2i+/tgqW1b0iIuNM9D2S2H8AwaDA6M3JQ== X-Received: by 2002:a17:907:9687:b0:6f3:6b4a:cb9b with SMTP id hd7-20020a170907968700b006f36b4acb9bmr7088748ejc.603.1651403929134; Sun, 01 May 2022 04:18:49 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:48 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 4/6] ptp: Support late timestamp determination Date: Sun, 1 May 2022 13:18:34 +0200 Message-Id: <20220501111836.10910-5-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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. Signed-off-by: Gerhard Engleder --- include/linux/netdevice.h | 21 ++++++++++++++++++++ include/linux/skbuff.h | 16 ++++++++++++--- net/socket.c | 42 +++++++++++++++++++++++++++++---------- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4aba92a4042a..47dca9adfb17 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); }; /** @@ -4738,6 +4747,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 fa03e02b761d..732b995fe54e 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 */ @@ -620,6 +625,11 @@ enum { */ SKBTX_HW_TSTAMP_USE_CYCLES = 1 << 3, + /* determine hardware time stamp based on time or cycles, flag is used + * only for RX path + */ + SKBTX_HW_TSTAMP_NETDEV = 1 << 3, + /* generate wifi status information (where possible) */ SKBTX_WIFI_STATUS = 1 << 4, diff --git a/net/socket.c b/net/socket.c index 0f680c7d968a..ee81e25e9b98 100644 --- a/net/socket.c +++ b/net/socket.c @@ -805,7 +805,8 @@ 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 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 +816,15 @@ 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 == -1) { + 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(); + } else { + 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 +844,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + struct net_device *orig_dev; + int if_index = -1; ktime_t hwtstamp; /* Race occurred between timestamp enabling and packet @@ -887,18 +894,33 @@ 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 (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) { + 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, + sk->sk_tsflags & + SOF_TIMESTAMPING_BIND_PHC); + } else { + hwtstamp = shhwtstamps->hwtstamp; + } + rcu_read_unlock(); + } else { + hwtstamp = shhwtstamps->hwtstamp; + } + if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(&shhwtstamps->hwtstamp, + hwtstamp = ptp_convert_timestamp(&hwtstamp, sk->sk_bind_phc); - else - hwtstamp = shhwtstamps->hwtstamp; 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 Sun May 1 11:18:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833637 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 D81ADC433EF for ; Sun, 1 May 2022 11:19:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345716AbiEALWZ (ORCPT ); Sun, 1 May 2022 07:22:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345629AbiEALWR (ORCPT ); Sun, 1 May 2022 07:22:17 -0400 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 185B3583A1 for ; Sun, 1 May 2022 04:18:52 -0700 (PDT) Received: by mail-ed1-x52a.google.com with SMTP id a21so13769476edb.1 for ; Sun, 01 May 2022 04:18:52 -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=0zq9xRvCzkWBQI5fSrd7bckEJpq28r5hzcGjbCVkbmI=; b=I2pZvEVmcDtM+hBOl1d94PfJjfi94MRGBSfJ8+Oaxe7vdTnrDEOwRYQsQwhbMpOLyo XmgWz8NLPsHpOjjbsoUSwO2ys5Pgi59PomiBIHnH3eB5w1ceqvDMldF16jCDIys++a2B +NodPfb6PgmhcDQsKUSYeH2lHu7Eg5/f/lXoLK6ZekO21l4PmXwJpORWbROw7GW/66Qm PVlm4otx8c1RwPj4l6UNu1h1YOQQpy8o6JLR+q/VrXa7NlM0ylMzV0ni2vbactPCc9XY elir2OrNlgVNdaENMfpNilghZhIM1Q4nGPx/BmkWwsNSMBPxOjTz8Dm13D8iETa8Cbj4 ZTYg== 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=0zq9xRvCzkWBQI5fSrd7bckEJpq28r5hzcGjbCVkbmI=; b=kdCUa1QEhoIaV5uBQ8IyrrgacT4/ukNKGZN/Fhkf8FjMxk+IBjk3qfJXkF3/4Whuyo wYZ39VseCuEfc4CUXbw2P1GUYUf0Yxwenlh6rVP8cufhVlXb6bZW9HYxpglGIg7hjIa7 xUxKTWPr3Kd7qxzFUzwAjnB8b2aZWWKBhndS2j4cg5z9eY2Wp+af8VaivSbUA96YbK0j fntnMPPeyR20dtZIfr/cv8Rq0JX/mydoJdqOH877tkjdhi/8dtAARxyvkpD35rfTHaAq J+ozpMw7n1M1NyIzDHMmjBYgwdhOqqGUvfVcMleCQCDvIN38j9qG2mEApnwPUVuoDrXu 28Dg== X-Gm-Message-State: AOAM532nprX9L8nhuL9ab+YDCMFkQU53tGhYNLTk3R4jfyAbbvX82v2S sLmofNxkmIYERJ6aWt2+Wfk8aA== X-Google-Smtp-Source: ABdhPJyz5PmDdDxM4SRBiT7HL61bLM/YL956b5IsKPheUPXXMEMAxl4Cw73XuhBGXjKJQRsNIGKElQ== X-Received: by 2002:aa7:da4a:0:b0:425:d676:9684 with SMTP id w10-20020aa7da4a000000b00425d6769684mr8393511eds.248.1651403930630; Sun, 01 May 2022 04:18:50 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:50 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 5/6] ptp: Speed up vclock lookup Date: Sun, 1 May 2022 13:18:35 +0200 Message-Id: <20220501111836.10910-6-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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 Sun May 1 11:18:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12833636 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 A271EC433EF for ; Sun, 1 May 2022 11:19:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345685AbiEALWY (ORCPT ); Sun, 1 May 2022 07:22:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345385AbiEALWT (ORCPT ); Sun, 1 May 2022 07:22:19 -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 8B286583A6 for ; Sun, 1 May 2022 04:18:53 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id g20so13747591edw.6 for ; Sun, 01 May 2022 04:18:53 -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=75BqDTGnuTZlUVn6Dx3YWDzsyduqpsEZcUPdW+8+MNe5LRfw8rAAKOtVJVtn9B+2LW u+E/KYN+yFOdcUnwu+tovbBDFpoM5kwToW+I8HNQl1jEWbeOEXEar8pGonvqwn7c0bvq JqMLpKKy4IEH/jN4fcpvvAms56ty224vRCg7S9EvHPyOA79seRuA25ySxkQcbqynbesC Dnx/QN86CIN6oVEDZKzuVBypMt4WEzm7m7asrbusLe1AdX2DFevIs8akWS0WWU+X5WLD UKdvU872pKE1TcLedu/znsxNn6AnzHKaIVjSiDiKStSfG+DF3G47G5Tc/butFvR6fqyC wA/Q== 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=l+Ppl3wZdtwmI9Lqm6Kdit4VNEV1xPsdMWNarSF3Jey1veOcDsvlaJSpHCnW+1SiPb WJspvugD+KgDggEBogsbppbhpXRVeeSgtV+fp0y0y2OKCTRe00GF3xjSlKlumPJFZ/SY StTZho12JBx5K8YGHwZrkCvyWXmPWJ+4o82PN9J0Bl2Ga+kgZisylA2uHDm2yUIoOHkk J97mp8+CBVt7w3+3AFM/wkOhf22QsleHDK4q+DRVzbCiXjl4bG0y+NPHPAMh0hl0Rr8x T5960dP//6brgpp8HhZc6+IMZ0VBilIIUEvNaYL6ngha9FTt7ogo4entY8AuLdsdjiuw 6wOw== X-Gm-Message-State: AOAM530wuyjgYH2ZRCD+G3KtxeIVa4jSMvkueBNxP4OvMHjK6g2fmEiX fKiC1jPsxZmh4JGhlzj61R/2vw== X-Google-Smtp-Source: ABdhPJyX2CwyLBgyClZHhyBlXlxYcUFsikuc2zhC2hSr8DVclwHnul/O2pLze3//tnbzrH7gfwwrIA== X-Received: by 2002:aa7:d8d2:0:b0:425:e22b:35c0 with SMTP id k18-20020aa7d8d2000000b00425e22b35c0mr8431393eds.181.1651403932098; Sun, 01 May 2022 04:18:52 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id mm29-20020a170906cc5d00b006f3ef214dcesm2508630ejb.52.2022.05.01.04.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 May 2022 04:18:51 -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, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v3 6/6] tsnep: Add free running cycle counter support Date: Sun, 1 May 2022 13:18:36 +0200 Message-Id: <20220501111836.10910-7-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220501111836.10910-1-gerhard@engleder-embedded.com> References: <20220501111836.10910-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 --- 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);