From patchwork Wed Dec 9 14:37:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geva, Erez" X-Patchwork-Id: 11961797 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 X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35414C4361B for ; Wed, 9 Dec 2020 15:55:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0053F22B47 for ; Wed, 9 Dec 2020 15:55:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732041AbgLIPze (ORCPT ); Wed, 9 Dec 2020 10:55:34 -0500 Received: from goliath.siemens.de ([192.35.17.28]:45088 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729877AbgLIPz2 (ORCPT ); Wed, 9 Dec 2020 10:55:28 -0500 X-Greylist: delayed 4530 seconds by postgrey-1.27 at vger.kernel.org; Wed, 09 Dec 2020 10:55:21 EST Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id 0B9EbVs3007322 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 9 Dec 2020 15:37:31 +0100 Received: from tsnlaptop.atstm41.nbgm.siemens.de ([144.145.220.34]) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id 0B9EbGp3002581; Wed, 9 Dec 2020 15:37:28 +0100 From: Erez Geva To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Alexey Kuznetsov , Arnd Bergmann , Cong Wang , "David S . Miller" , Hideaki YOSHIFUJI , Jakub Kicinski , Jamal Hadi Salim , Jiri Pirko , Alexei Starovoitov , Colin Ian King , Daniel Borkmann , Eric Dumazet , Eyal Birger , "Gustavo A . R . Silva" , Jakub Sitnicki , John Ogness , Jon Rosen , Kees Cook , Mao Wenan , Marc Kleine-Budde , Martin KaFai Lau , Matthieu Baerts , Andrei Vagin , Dmitry Safonov <0x7f454c46@gmail.com>, "Eric W . Biederman" , Ingo Molnar , John Stultz , Miaohe Lin , Michal Kubecek , Or Cohen , Oleg Nesterov , Peter Zijlstra , Richard Cochran , Stefan Schmidt , Willem de Bruijn , Xie He , Stephen Boyd , Thomas Gleixner , Vladis Dronov , Sebastian Andrzej Siewior , Frederic Weisbecker Cc: Vinicius Costa Gomes , Vedang Patel , Ines Molzahn , Simon Sudler , Andreas Meisinger , Andreas Bucher , Henning Schild , Jan Kiszka , Andreas Zirkler , Ermin Sakic , An Ninh Nguyen , Michael Saenger , Bernd Maehringer , Gisela Greinert , Erez Geva , Erez Geva Subject: [PATCH 3/3] The TC ETF Qdisc pass the hardware timestamp to the interface driver. Date: Wed, 9 Dec 2020 15:37:06 +0100 Message-Id: <20201209143707.13503-4-erez.geva.ext@siemens.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201209143707.13503-1-erez.geva.ext@siemens.com> References: <20201209143707.13503-1-erez.geva.ext@siemens.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The ETF pass the TX sending hardware timestamp to the network interface driver. - Add new flag to the ETF Qdisc setting that mandate the use of the hardware timestamp in a socket's buffer. - The ETF Qdisc pass the TX sending hardware timestamp to the network interface driver. Signed-off-by: Erez Geva --- include/uapi/linux/pkt_sched.h | 1 + net/sched/sch_etf.c | 59 +++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index 9e7c2c607845..51e2b57bfa81 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -1056,6 +1056,7 @@ struct tc_etf_qopt { #define TC_ETF_DEADLINE_MODE_ON _BITUL(0) #define TC_ETF_OFFLOAD_ON _BITUL(1) #define TC_ETF_SKIP_SOCK_CHECK _BITUL(2) +#define TC_ETF_USE_HW_TIMESTAMP _BITUL(3) }; enum { diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c index c48f91075b5c..67eace3e180f 100644 --- a/net/sched/sch_etf.c +++ b/net/sched/sch_etf.c @@ -23,11 +23,13 @@ #define DEADLINE_MODE_IS_ON(x) ((x)->flags & TC_ETF_DEADLINE_MODE_ON) #define OFFLOAD_IS_ON(x) ((x)->flags & TC_ETF_OFFLOAD_ON) #define SKIP_SOCK_CHECK_IS_SET(x) ((x)->flags & TC_ETF_SKIP_SOCK_CHECK) +#define USE_HW_TIMESTAMP(x) ((x)->flags & TC_ETF_USE_HW_TIMESTAMP) struct etf_sched_data { bool offload; bool deadline_mode; bool skip_sock_check; + bool use_hw_timestamp; int clockid; int queue; s32 delta; /* in ns */ @@ -75,7 +77,7 @@ static inline int validate_input_params(struct tc_etf_qopt *qopt, static bool is_packet_valid(struct Qdisc *sch, struct sk_buff *nskb) { struct etf_sched_data *q = qdisc_priv(sch); - ktime_t txtime = nskb->tstamp; + ktime_t hwtxtime, txtime = nskb->tstamp; struct sock *sk = nskb->sk; ktime_t now; @@ -88,6 +90,9 @@ static bool is_packet_valid(struct Qdisc *sch, struct sk_buff *nskb) if (!sock_flag(sk, SOCK_TXTIME)) return false; + if (!q->use_hw_timestamp != !sock_flag(sk, SOCK_HW_TXTIME)) + return false; + /* We don't perform crosstimestamping. * Drop if packet's clockid differs from qdisc's. */ @@ -99,7 +104,11 @@ static bool is_packet_valid(struct Qdisc *sch, struct sk_buff *nskb) skip: now = q->get_time(); - if (ktime_before(txtime, now) || ktime_before(txtime, q->last)) + if (q->use_hw_timestamp) + hwtxtime = skb_hwtstamps(nskb)->hwtstamp; + else + hwtxtime = txtime; + if (ktime_before(txtime, now) || ktime_before(hwtxtime, q->last)) return false; return true; @@ -173,16 +182,33 @@ static int etf_enqueue_timesortedlist(struct sk_buff *nskb, struct Qdisc *sch, return qdisc_drop(nskb, sch, to_free); } - while (*p) { - struct sk_buff *skb; + if (q->use_hw_timestamp) { + ktime_t hwtxtime = skb_hwtstamps(nskb)->hwtstamp; + + while (*p) { + struct sk_buff *skb; - parent = *p; - skb = rb_to_skb(parent); - if (ktime_compare(txtime, skb->tstamp) >= 0) { - p = &parent->rb_right; - leftmost = false; - } else { - p = &parent->rb_left; + parent = *p; + skb = rb_to_skb(parent); + if (ktime_compare(hwtxtime, skb_hwtstamps(skb)->hwtstamp) >= 0) { + p = &parent->rb_right; + leftmost = false; + } else { + p = &parent->rb_left; + } + } + } else { + while (*p) { + struct sk_buff *skb; + + parent = *p; + skb = rb_to_skb(parent); + if (ktime_compare(txtime, skb->tstamp) >= 0) { + p = &parent->rb_right; + leftmost = false; + } else { + p = &parent->rb_left; + } } } rb_link_node(&nskb->rbnode, parent, p); @@ -245,6 +271,10 @@ static void timesortedlist_remove(struct Qdisc *sch, struct sk_buff *skb) qdisc_bstats_update(sch, skb); + /* Pass hardware time to driver and to last */ + if (q->use_hw_timestamp) + skb->tstamp = skb_hwtstamps(skb)->hwtstamp; + q->last = skb->tstamp; sch->q.qlen--; @@ -393,6 +423,10 @@ static int etf_init(struct Qdisc *sch, struct nlattr *opt, q->offload = OFFLOAD_IS_ON(qopt); q->deadline_mode = DEADLINE_MODE_IS_ON(qopt); q->skip_sock_check = SKIP_SOCK_CHECK_IS_SET(qopt); + q->use_hw_timestamp = USE_HW_TIMESTAMP(qopt); + /* deadline mode can not coexist with using hardware time */ + if (q->use_hw_timestamp && q->deadline_mode) + return -EOPNOTSUPP; switch (q->clockid) { case CLOCK_REALTIME: @@ -484,6 +518,9 @@ static int etf_dump(struct Qdisc *sch, struct sk_buff *skb) if (q->skip_sock_check) opt.flags |= TC_ETF_SKIP_SOCK_CHECK; + if (q->use_hw_timestamp) + opt.flags |= TC_ETF_USE_HW_TIMESTAMP; + if (nla_put(skb, TCA_ETF_PARMS, sizeof(opt), &opt)) goto nla_put_failure;