All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
To: netdev@vger.kernel.org
Cc: tglx@linutronix.de, jan.altenberg@linutronix.de,
	vinicius.gomes@intel.com, kurt.kanzenbach@linutronix.de,
	henrik@austad.us, richardcochran@gmail.com,
	levi.pearson@harman.com, ilias.apalodimas@linaro.org,
	ivan.khoronzhuk@linaro.org, mlichvar@redhat.com,
	willemb@google.com, jhs@mojatatu.com, xiyou.wangcong@gmail.com,
	jiri@resnulli.us,
	Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Subject: [PATCH v1 net-next 07/14] net/sched: Add HW offloading capability to ETF
Date: Wed, 27 Jun 2018 14:59:43 -0700	[thread overview]
Message-ID: <20180627215950.6719-8-jesus.sanchez-palencia@intel.com> (raw)
In-Reply-To: <20180627215950.6719-1-jesus.sanchez-palencia@intel.com>

Add infra so etf qdisc supports HW offload of time-based transmission.

For hw offload, the time sorted list is still used, so packets are
dequeued always in order of txtime.

Example:

$ tc qdisc replace dev enp2s0 parent root handle 100 mqprio num_tc 3 \
           map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0

$ tc qdisc add dev enp2s0 parent 100:1 etf offload delta 100000 \
	   clockid CLOCK_REALTIME

In this example, the Qdisc will use HW offload for the control of the
transmission time through the network adapter. The hrtimer used for
packets scheduling inside the qdisc will use the clockid CLOCK_REALTIME
as reference and packets leave the Qdisc "delta" (100000) nanoseconds
before their transmission time. Because this will be using HW offload and
since dynamic clocks are not supported by the hrtimer, the system clock
and the PHC clock must be synchronized for this mode to behave as
expected.

Signed-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
---
 include/net/pkt_sched.h        |  5 +++
 include/uapi/linux/pkt_sched.h |  1 +
 net/sched/sch_etf.c            | 71 +++++++++++++++++++++++++++++++++-
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 2466ea143d01..7dc769e5452b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -155,4 +155,9 @@ struct tc_cbs_qopt_offload {
 	s32 sendslope;
 };
 
+struct tc_etf_qopt_offload {
+	u8 enable;
+	s32 queue;
+};
+
 #endif
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 9d6fd2004a03..efad482e69d2 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -941,6 +941,7 @@ struct tc_etf_qopt {
 	__s32 clockid;
 	__u32 flags;
 #define TC_ETF_DEADLINE_MODE_ON	BIT(0)
+#define TC_ETF_OFFLOAD_ON	BIT(1)
 };
 
 enum {
diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c
index 5f01a285f399..cd6cb5b69228 100644
--- a/net/sched/sch_etf.c
+++ b/net/sched/sch_etf.c
@@ -20,8 +20,10 @@
 #include <net/sock.h>
 
 #define DEADLINE_MODE_IS_ON(x) ((x)->flags & TC_ETF_DEADLINE_MODE_ON)
+#define OFFLOAD_IS_ON(x) ((x)->flags & TC_ETF_OFFLOAD_ON)
 
 struct etf_sched_data {
+	bool offload;
 	bool deadline_mode;
 	int clockid;
 	int queue;
@@ -45,6 +47,9 @@ static inline int validate_input_params(struct tc_etf_qopt *qopt,
 	 *	* Dynamic clockids are not supported.
 	 *
 	 *	* Delta must be a positive integer.
+	 *
+	 * Also note that for the HW offload case, we must
+	 * expect that system clocks have been synchronized to PHC.
 	 */
 	if (qopt->clockid < 0) {
 		NL_SET_ERR_MSG(extack, "Dynamic clockids are not supported");
@@ -226,6 +231,56 @@ static struct sk_buff *etf_dequeue_timesortedlist(struct Qdisc *sch)
 	return skb;
 }
 
+static void etf_disable_offload(struct net_device *dev,
+				struct etf_sched_data *q)
+{
+	struct tc_etf_qopt_offload etf = { };
+	const struct net_device_ops *ops;
+	int err;
+
+	if (!q->offload)
+		return;
+
+	ops = dev->netdev_ops;
+	if (!ops->ndo_setup_tc)
+		return;
+
+	etf.queue = q->queue;
+	etf.enable = 0;
+
+	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
+	if (err < 0)
+		pr_warn("Couldn't disable ETF offload for queue %d\n",
+			etf.queue);
+}
+
+static int etf_enable_offload(struct net_device *dev, struct etf_sched_data *q,
+			      struct netlink_ext_ack *extack)
+{
+	const struct net_device_ops *ops = dev->netdev_ops;
+	struct tc_etf_qopt_offload etf = { };
+	int err;
+
+	if (q->offload)
+		return 0;
+
+	if (!ops->ndo_setup_tc) {
+		NL_SET_ERR_MSG(extack, "Specified device does not support ETF offload");
+		return -EOPNOTSUPP;
+	}
+
+	etf.queue = q->queue;
+	etf.enable = 1;
+
+	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
+	if (err < 0) {
+		NL_SET_ERR_MSG(extack, "Specified device failed to setup ETF hardware offload");
+		return err;
+	}
+
+	return 0;
+}
+
 static int etf_init(struct Qdisc *sch, struct nlattr *opt,
 		    struct netlink_ext_ack *extack)
 {
@@ -252,8 +307,9 @@ static int etf_init(struct Qdisc *sch, struct nlattr *opt,
 
 	qopt = nla_data(tb[TCA_ETF_PARMS]);
 
-	pr_debug("delta %d clockid %d deadline %s\n",
+	pr_debug("delta %d clockid %d offload %s deadline %s\n",
 		 qopt->delta, qopt->clockid,
+		 OFFLOAD_IS_ON(qopt) ? "on" : "off",
 		 DEADLINE_MODE_IS_ON(qopt) ? "on" : "off");
 
 	err = validate_input_params(qopt, extack);
@@ -262,9 +318,16 @@ static int etf_init(struct Qdisc *sch, struct nlattr *opt,
 
 	q->queue = sch->dev_queue - netdev_get_tx_queue(dev, 0);
 
+	if (OFFLOAD_IS_ON(qopt)) {
+		err = etf_enable_offload(dev, q, extack);
+		if (err < 0)
+			return err;
+	}
+
 	/* Everything went OK, save the parameters used. */
 	q->delta = qopt->delta;
 	q->clockid = qopt->clockid;
+	q->offload = OFFLOAD_IS_ON(qopt);
 	q->deadline_mode = DEADLINE_MODE_IS_ON(qopt);
 
 	switch (q->clockid) {
@@ -327,10 +390,13 @@ static void etf_reset(struct Qdisc *sch)
 static void etf_destroy(struct Qdisc *sch)
 {
 	struct etf_sched_data *q = qdisc_priv(sch);
+	struct net_device *dev = qdisc_dev(sch);
 
 	/* Only cancel watchdog if it's been initialized. */
 	if (q->watchdog.qdisc == sch)
 		qdisc_watchdog_cancel(&q->watchdog);
+
+	etf_disable_offload(dev, q);
 }
 
 static int etf_dump(struct Qdisc *sch, struct sk_buff *skb)
@@ -345,6 +411,9 @@ static int etf_dump(struct Qdisc *sch, struct sk_buff *skb)
 
 	opt.delta = q->delta;
 	opt.clockid = q->clockid;
+	if (q->offload)
+		opt.flags |= TC_ETF_OFFLOAD_ON;
+
 	if (q->deadline_mode)
 		opt.flags |= TC_ETF_DEADLINE_MODE_ON;
 
-- 
2.17.1

  parent reply	other threads:[~2018-06-27 22:04 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-27 21:59 [PATCH v1 net-next 00/14] Scheduled packet Transmission: ETF Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 01/14] net: Clear skb->tstamp only on the forwarding path Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 02/14] net: Add a new socket option for a future transmit time Jesus Sanchez-Palencia
2018-06-27 22:16   ` Eric Dumazet
2018-06-27 23:07     ` Jesus Sanchez-Palencia
2018-06-28  0:05       ` Eric Dumazet
2018-06-28  2:16   ` kbuild test robot
2018-06-28 14:26   ` Willem de Bruijn
2018-06-28 14:40     ` Willem de Bruijn
2018-06-28 18:33       ` Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 03/14] net: ipv4: Hook into time based transmission Jesus Sanchez-Palencia
2018-06-28 14:26   ` Willem de Bruijn
2018-06-27 21:59 ` [PATCH v1 net-next 04/14] net: packet: " Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 05/14] net/sched: Allow creating a Qdisc watchdog with other clocks Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 06/14] net/sched: Introduce the ETF Qdisc Jesus Sanchez-Palencia
2018-06-27 21:59 ` Jesus Sanchez-Palencia [this message]
2018-06-27 21:59 ` [PATCH v1 net-next 08/14] igb: Refactor igb_configure_cbs() Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 09/14] igb: Only change Tx arbitration when CBS is on Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 10/14] igb: Refactor igb_offload_cbs() Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 11/14] igb: Add support for ETF offload Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 12/14] igb: Only call skb_tx_timestamp after descriptors are ready Jesus Sanchez-Palencia
2018-06-27 23:56   ` Eric Dumazet
2018-06-28 17:12     ` Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 13/14] net/sched: Enforce usage of CLOCK_TAI for sch_etf Jesus Sanchez-Palencia
2018-06-28 14:26   ` Willem de Bruijn
2018-06-28 17:11     ` Jesus Sanchez-Palencia
2018-06-27 21:59 ` [PATCH v1 net-next 14/14] net/sched: Make etf report drops on error_queue Jesus Sanchez-Palencia
2018-06-28 14:27   ` Willem de Bruijn
2018-06-29 17:48     ` Jesus Sanchez-Palencia
2018-06-29 18:49       ` Willem de Bruijn
2018-06-29 20:14         ` Jesus Sanchez-Palencia

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180627215950.6719-8-jesus.sanchez-palencia@intel.com \
    --to=jesus.sanchez-palencia@intel.com \
    --cc=henrik@austad.us \
    --cc=ilias.apalodimas@linaro.org \
    --cc=ivan.khoronzhuk@linaro.org \
    --cc=jan.altenberg@linutronix.de \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=kurt.kanzenbach@linutronix.de \
    --cc=levi.pearson@harman.com \
    --cc=mlichvar@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=vinicius.gomes@intel.com \
    --cc=willemb@google.com \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.