Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp39776rwd; Tue, 30 May 2023 15:53:37 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4TYrltZF1+TRwJwoUw0zarm3bGVHiNdSfTfttS49VoUOLReqYuaxPZIQ9NzoBs6Qrz2nzT X-Received: by 2002:a17:902:7043:b0:19d:1834:92b9 with SMTP id h3-20020a170902704300b0019d183492b9mr3495828plt.56.1685487217472; Tue, 30 May 2023 15:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685487217; cv=none; d=google.com; s=arc-20160816; b=StI/mIxnbY2LKqotPDilDW+dI2R7DUZpIaHPiGHBj4k/2hrHamXumso58k5ZdDuETJ n7PrX/zIy5cQD/Vxi6FfT1SBlznBdzddEHLbRok1RQoWwD89P04JXn/TWCIUOcGg7AZY 5jpJZ0a0i99d0d/OECu6rmiVf7Vyea0UJbFbSkk4dbBz8COGFuHMMHsPleSX/Zq4WsY8 +PlYHr3ivpOiSKaCLURIpqUSCZAN8Ql4Zy2OPzi9CeFBlTdjhTkCFHo19vzI0MM3jqVv lm6Yn60KYequphsvOpfOJVbWX1YWcFSuiVzTLCWUTGCOKSXpRlSv7xC7umFRlndC7ihu 5sHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:dkim-signature; bh=6Man/spGGSmYkgVooNC9gTqN+pW4mcKA8KymXFNCDEk=; b=ps0IfQHLYXr5wJxFT+HUrXcpPmyALF/QnLPS5DrCYkDmEugJZdDgaItKiRG0S7tPYx WhdjKsjgPcUAK3bAVv5yG/E8ADfYWs9bau9XrC8LtCDeXaqfobku2r6er8+X65hmMMk/ HnyF80YQMXnDen7oK6ZdeS163uD8zMCQXhiuB/G9nOW7pjURXhwRhUHeRatEZqWmJSFV uGM9WRLyjc9KB8jhVpXgeXHY0577u45gR+qia1W0EiFRUsPJv3xEPWynLNZ4LPMpZOvl VkZb/ubBm/S95Y3rbRVejPmp4NQDKEeh4Zt07HnfvV8gXIvZhDYqEQl/ps+vhW5PsGnp j1zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=eX7AvDVw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cp5-20020a170902e78500b001aaff31bcccsi5816440plb.124.2023.05.30.15.53.22; Tue, 30 May 2023 15:53:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=eX7AvDVw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231740AbjE3WwW (ORCPT + 99 others); Tue, 30 May 2023 18:52:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229620AbjE3WwU (ORCPT ); Tue, 30 May 2023 18:52:20 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21F4CE5; Tue, 30 May 2023 15:52:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1685487139; x=1717023139; h=from:to:cc:subject:in-reply-to:references:date: message-id:mime-version; bh=3KqPLAaPdZRdqqIgS2W0nnEO/sGfCLdma7O0mD98SHg=; b=eX7AvDVwXNukFoWY1iGhLO33+d5CBd50zcIX2SOPT3XSOXVrYRVKZy+v JIs1IcnDOxb/7HoAole0/rLhOXJUmUlfJ8Hl+exS6hgccQ2HYkydQ+jBc qZTp2mAjEDJfu6NoD+uin0lHZLM0kWZVP10RPFur5NDrlHoRvfW8uanS3 zAEncJds3jcsf3HIKyHoNhyWLNaV3JhD2HwsWa2ZLvC2HD08YcUZ9rr8A PMrcYhAWf4STWzcCILnXbA5kkxIsm3GINfO5vDk50t7XiAlXk/wgUTXh0 2KP3+ubvx0Luv7c49J8Toi5OSTaoG3tCPrqv3T00RPWKvfU2aFno1hcVJ w==; X-IronPort-AV: E=McAfee;i="6600,9927,10726"; a="334687242" X-IronPort-AV: E=Sophos;i="6.00,205,1681196400"; d="scan'208";a="334687242" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 May 2023 15:52:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10726"; a="953357490" X-IronPort-AV: E=Sophos;i="6.00,205,1681196400"; d="scan'208";a="953357490" Received: from vcostago-desk1.jf.intel.com (HELO vcostago-desk1) ([10.54.70.17]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 May 2023 15:52:17 -0700 From: Vinicius Costa Gomes To: Vladimir Oltean , netdev@vger.kernel.org Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jamal Hadi Salim , Cong Wang , Jiri Pirko , Kurt Kanzenbach , Gerhard Engleder , Amritha Nambiar , Ferenc Fejes , Xiaoliang Yang , Roger Quadros , Pranavi Somisetty , Harini Katakam , Giuseppe Cavallaro , Alexandre Torgue , Michael Sit Wei Hong , Mohammad Athari Bin Ismail , Oleksij Rempel , Jacob Keller , linux-kernel@vger.kernel.org, Andrew Lunn , Florian Fainelli , Claudiu Manoil , Alexandre Belloni , UNGLinuxDriver@microchip.com, Jesse Brandeburg , Tony Nguyen , Horatiu Vultur , Jose Abreu , Maxime Coquelin , intel-wired-lan@lists.osuosl.org, Muhammad Husaini Zulkifli Subject: Re: [PATCH net-next 3/5] net/sched: taprio: add netlink reporting for offload statistics counters In-Reply-To: <20230530091948.1408477-4-vladimir.oltean@nxp.com> References: <20230530091948.1408477-1-vladimir.oltean@nxp.com> <20230530091948.1408477-4-vladimir.oltean@nxp.com> Date: Tue, 30 May 2023 15:52:17 -0700 Message-ID: <87wn0ptota.fsf@intel.com> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Vladimir Oltean writes: > Offloading drivers may report some additional statistics counters, some > of them even suggested by 802.1Q, like TransmissionOverrun. > > In my opinion we don't have to limit ourselves to reporting counters > only globally to the Qdisc/interface, especially if the device has more > detailed reporting (per traffic class), since the more detailed info is > valuable for debugging and can help identifying who is exceeding its > time slot. > > But on the other hand, some devices may not be able to report both per > TC and global stats. > > So we end up reporting both ways, and use the good old ethtool_put_stat() > strategy to determine which statistics are supported by this NIC. > Statistics which aren't set are simply not reported to netlink. For this > reason, we need something dynamic (a nlattr nest) to be reported through > TCA_STATS_APP, and not something daft like the fixed-size and > inextensible struct tc_codel_xstats. A good model for xstats which are a > nlattr nest rather than a fixed struct seems to be cake. > > # Global stats > $ tc -s qdisc show dev eth0 root > # Per-tc stats > $ tc -s class show dev eth0 > > Signed-off-by: Vladimir Oltean > --- > include/net/pkt_sched.h | 47 ++++++++++++++++---- > include/uapi/linux/pkt_sched.h | 10 +++++ > net/sched/sch_taprio.c | 78 +++++++++++++++++++++++++++++++++- > 3 files changed, 126 insertions(+), 9 deletions(-) > > diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h > index f5fb11da357b..530d33adec88 100644 > --- a/include/net/pkt_sched.h > +++ b/include/net/pkt_sched.h > @@ -188,6 +188,27 @@ struct tc_taprio_caps { > enum tc_taprio_qopt_cmd { > TAPRIO_CMD_REPLACE, > TAPRIO_CMD_DESTROY, > + TAPRIO_CMD_STATS, > + TAPRIO_CMD_TC_STATS, > +}; > + > +/** > + * struct tc_taprio_qopt_stats - IEEE 802.1Qbv statistics > + * @window_drops: Frames that were dropped because they were too large to be > + * transmitted in any of the allotted time windows (open gates) for their > + * traffic class. > + * @tx_overruns: Frames still being transmitted by the MAC after the > + * transmission gate associated with their traffic class has closed. > + * Equivalent to `12.29.1.1.2 TransmissionOverrun` from 802.1Q-2018. > + */ > +struct tc_taprio_qopt_stats { > + u64 window_drops; > + u64 tx_overruns; > +}; > + > +struct tc_taprio_qopt_tc_stats { > + int tc; > + struct tc_taprio_qopt_stats stats; > }; > > struct tc_taprio_sched_entry { > @@ -199,16 +220,26 @@ struct tc_taprio_sched_entry { > }; > > struct tc_taprio_qopt_offload { > - struct tc_mqprio_qopt_offload mqprio; > - struct netlink_ext_ack *extack; > enum tc_taprio_qopt_cmd cmd; > - ktime_t base_time; > - u64 cycle_time; > - u64 cycle_time_extension; > - u32 max_sdu[TC_MAX_QUEUE]; > > - size_t num_entries; > - struct tc_taprio_sched_entry entries[]; > + union { > + /* TAPRIO_CMD_STATS */ > + struct tc_taprio_qopt_stats stats; > + /* TAPRIO_CMD_TC_STATS */ > + struct tc_taprio_qopt_tc_stats tc_stats; > + /* TAPRIO_CMD_REPLACE */ > + struct { > + struct tc_mqprio_qopt_offload mqprio; > + struct netlink_ext_ack *extack; > + ktime_t base_time; > + u64 cycle_time; > + u64 cycle_time_extension; > + u32 max_sdu[TC_MAX_QUEUE]; > + > + size_t num_entries; > + struct tc_taprio_sched_entry entries[]; > + }; > + }; > }; > > #if IS_ENABLED(CONFIG_NET_SCH_TAPRIO) > diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h > index 51a7addc56c6..00f6ff0aff1f 100644 > --- a/include/uapi/linux/pkt_sched.h > +++ b/include/uapi/linux/pkt_sched.h > @@ -1259,6 +1259,16 @@ enum { > TCA_TAPRIO_TC_ENTRY_MAX = (__TCA_TAPRIO_TC_ENTRY_CNT - 1) > }; > > +enum { > + TCA_TAPRIO_OFFLOAD_STATS_PAD = 1, /* u64 */ > + TCA_TAPRIO_OFFLOAD_STATS_WINDOW_DROPS, /* u64 */ > + TCA_TAPRIO_OFFLOAD_STATS_TX_OVERRUNS, /* u64 */ > + > + /* add new constants above here */ > + __TCA_TAPRIO_OFFLOAD_STATS_CNT, > + TCA_TAPRIO_OFFLOAD_STATS_MAX = (__TCA_TAPRIO_OFFLOAD_STATS_CNT - 1) > +}; > + > enum { > TCA_TAPRIO_ATTR_UNSPEC, > TCA_TAPRIO_ATTR_PRIOMAP, /* struct tc_mqprio_qopt */ > diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c > index 06bf4c6355a5..3c4c2c334878 100644 > --- a/net/sched/sch_taprio.c > +++ b/net/sched/sch_taprio.c > @@ -27,6 +27,8 @@ > #include > #include > > +#define TAPRIO_STAT_NOT_SET (~0ULL) > + > #include "sch_mqprio_lib.h" > > static LIST_HEAD(taprio_list); > @@ -2289,6 +2291,72 @@ static int taprio_dump_tc_entries(struct sk_buff *skb, > return -EMSGSIZE; > } > > +static int taprio_put_stat(struct sk_buff *skb, u64 val, u16 attrtype) > +{ > + if (val == TAPRIO_STAT_NOT_SET) > + return 0; > + if (nla_put_u64_64bit(skb, attrtype, val, TCA_TAPRIO_OFFLOAD_STATS_PAD)) > + return -EMSGSIZE; > + return 0; > +} > + > +static int taprio_dump_xstats(struct Qdisc *sch, struct gnet_dump *d, > + struct tc_taprio_qopt_offload *offload, > + struct tc_taprio_qopt_stats *stats) > +{ > + struct net_device *dev = qdisc_dev(sch); > + const struct net_device_ops *ops; > + struct sk_buff *skb = d->skb; > + struct nlattr *xstats; > + int err; > + > + ops = qdisc_dev(sch)->netdev_ops; > + > + /* FIXME I could use qdisc_offload_dump_helper(), but that messes > + * with sch->flags depending on whether the device reports taprio > + * stats, and I'm not sure whether that's a good idea, considering > + * that stats are optional to the offload itself > + */ > + if (!ops->ndo_setup_tc) > + return 0; > + > + memset(stats, 0xff, sizeof(*stats)); The only part that I didn't like, at first, was this, that the initialization of the offload struct is divided into two parts: one to set the command/tc, and one to set the "invalid/not set" value to all stats fields. I was thinking of adding a macro to do initialization of the stats fields, but it has a problem that it won't complain when a new field is added. Your solution should always work. I don't have better suggestions. Acked-by: Vinicius Costa Gomes > + > + err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload); > + if (err == -EOPNOTSUPP) > + return 0; > + if (err) > + return err; > + > + xstats = nla_nest_start(skb, TCA_STATS_APP); > + if (!xstats) > + goto err; > + > + if (taprio_put_stat(skb, stats->window_drops, > + TCA_TAPRIO_OFFLOAD_STATS_WINDOW_DROPS) || > + taprio_put_stat(skb, stats->tx_overruns, > + TCA_TAPRIO_OFFLOAD_STATS_TX_OVERRUNS)) > + goto err_cancel; > + > + nla_nest_end(skb, xstats); > + > + return 0; > + > +err_cancel: > + nla_nest_cancel(skb, xstats); > +err: > + return -EMSGSIZE; > +} > + > +static int taprio_dump_stats(struct Qdisc *sch, struct gnet_dump *d) > +{ > + struct tc_taprio_qopt_offload offload = { > + .cmd = TAPRIO_CMD_STATS, > + }; > + > + return taprio_dump_xstats(sch, d, &offload, &offload.stats); > +} > + > static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb) > { > struct taprio_sched *q = qdisc_priv(sch); > @@ -2389,11 +2457,18 @@ static int taprio_dump_class_stats(struct Qdisc *sch, unsigned long cl, > { > struct netdev_queue *dev_queue = taprio_queue_get(sch, cl); > struct Qdisc *child = dev_queue->qdisc_sleeping; > + struct tc_taprio_qopt_offload offload = { > + .cmd = TAPRIO_CMD_TC_STATS, > + .tc_stats = { > + .tc = cl - 1, > + }, > + }; > > if (gnet_stats_copy_basic(d, NULL, &child->bstats, true) < 0 || > qdisc_qstats_copy(d, child) < 0) > return -1; > - return 0; > + > + return taprio_dump_xstats(sch, d, &offload, &offload.tc_stats.stats); > } > > static void taprio_walk(struct Qdisc *sch, struct qdisc_walker *arg) > @@ -2440,6 +2515,7 @@ static struct Qdisc_ops taprio_qdisc_ops __read_mostly = { > .dequeue = taprio_dequeue, > .enqueue = taprio_enqueue, > .dump = taprio_dump, > + .dump_stats = taprio_dump_stats, > .owner = THIS_MODULE, > }; > > -- > 2.34.1 > -- Vinicius