netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/3] sched: A couple of fixes for sch_cake
@ 2020-06-25 20:12 Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 1/3] sch_cake: don't try to reallocate or unshare skb unconditionally Toke Høiland-Jørgensen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-06-25 20:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, cake

Hi Dave

This series contains a couple of fixes for diffserv handling in sch_cake that
provide a nice speedup (with a somewhat pedantic nit fix tacked on to the end).

Not quite sure about whether this should go to stable; it does provide a nice
speedup, but it's not strictly a fix in the "correctness" sense. I lean towards
including this in stable as well, since our most important consumer of that
(OpenWrt) is likely to backport the series anyway.

-Toke

---

Ilya Ponetayev (1):
      sch_cake: don't try to reallocate or unshare skb unconditionally

Toke Høiland-Jørgensen (2):
      sch_cake: don't call diffserv parsing code when it is not needed
      sch_cake: fix a few style nits


 net/sched/sch_cake.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net 1/3] sch_cake: don't try to reallocate or unshare skb unconditionally
  2020-06-25 20:12 [PATCH net 0/3] sched: A couple of fixes for sch_cake Toke Høiland-Jørgensen
@ 2020-06-25 20:12 ` Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 2/3] sch_cake: don't call diffserv parsing code when it is not needed Toke Høiland-Jørgensen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-06-25 20:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, cake

From: Ilya Ponetayev <i.ponetaev@ndmsystems.com>

cake_handle_diffserv() tries to linearize mac and network header parts of
skb and to make it writable unconditionally. In some cases it leads to full
skb reallocation, which reduces throughput and increases CPU load. Some
measurements of IPv4 forward + NAPT on MIPS router with 580 MHz single-core
CPU was conducted. It appears that on kernel 4.9 skb_try_make_writable()
reallocates skb, if skb was allocated in ethernet driver via so-called
'build skb' method from page cache (it was discovered by strange increase
of kmalloc-2048 slab at first).

Obtain DSCP value via read-only skb_header_pointer() call, and leave
linearization only for DSCP bleaching or ECN CE setting. And, as an
additional optimisation, skip diffserv parsing entirely if it is not needed
by the current configuration.

Fixes: c87b4ecdbe8d ("sch_cake: Make sure we can write the IP header before changing DSCP bits")
Signed-off-by: Ilya Ponetayev <i.ponetaev@ndmsystems.com>
[ fix a few style issues, reflow commit message ]
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 net/sched/sch_cake.c |   41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 60f8ae578819..cae006bef565 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1553,30 +1553,49 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
 
 static u8 cake_handle_diffserv(struct sk_buff *skb, u16 wash)
 {
-	int wlen = skb_network_offset(skb);
+	const int offset = skb_network_offset(skb);
+	u16 *buf, buf_;
 	u8 dscp;
 
 	switch (tc_skb_protocol(skb)) {
 	case htons(ETH_P_IP):
-		wlen += sizeof(struct iphdr);
-		if (!pskb_may_pull(skb, wlen) ||
-		    skb_try_make_writable(skb, wlen))
+		buf = skb_header_pointer(skb, offset, sizeof(buf_), &buf_);
+		if (unlikely(!buf))
 			return 0;
 
-		dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
-		if (wash && dscp)
+		/* ToS is in the second byte of iphdr */
+		dscp = ipv4_get_dsfield((struct iphdr *)buf) >> 2;
+
+		if (wash && dscp) {
+			const int wlen = offset + sizeof(struct iphdr);
+
+			if (!pskb_may_pull(skb, wlen) ||
+			    skb_try_make_writable(skb, wlen))
+				return 0;
+
 			ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, 0);
+		}
+
 		return dscp;
 
 	case htons(ETH_P_IPV6):
-		wlen += sizeof(struct ipv6hdr);
-		if (!pskb_may_pull(skb, wlen) ||
-		    skb_try_make_writable(skb, wlen))
+		buf = skb_header_pointer(skb, offset, sizeof(buf_), &buf_);
+		if (unlikely(!buf))
 			return 0;
 
-		dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
-		if (wash && dscp)
+		/* Traffic class is in the first and second bytes of ipv6hdr */
+		dscp = ipv6_get_dsfield((struct ipv6hdr *)buf) >> 2;
+
+		if (wash && dscp) {
+			const int wlen = offset + sizeof(struct ipv6hdr);
+
+			if (!pskb_may_pull(skb, wlen) ||
+			    skb_try_make_writable(skb, wlen))
+				return 0;
+
 			ipv6_change_dsfield(ipv6_hdr(skb), INET_ECN_MASK, 0);
+		}
+
 		return dscp;
 
 	case htons(ETH_P_ARP):


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 2/3] sch_cake: don't call diffserv parsing code when it is not needed
  2020-06-25 20:12 [PATCH net 0/3] sched: A couple of fixes for sch_cake Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 1/3] sch_cake: don't try to reallocate or unshare skb unconditionally Toke Høiland-Jørgensen
@ 2020-06-25 20:12 ` Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 3/3] sch_cake: fix a few style nits Toke Høiland-Jørgensen
  2020-06-25 23:25 ` [PATCH net 0/3] sched: A couple of fixes for sch_cake David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-06-25 20:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, cake

From: Toke Høiland-Jørgensen <toke@redhat.com>

As a further optimisation of the diffserv parsing codepath, we can skip it
entirely if CAKE is configured to neither use diffserv-based
classification, nor to zero out the diffserv bits.

Fixes: c87b4ecdbe8d ("sch_cake: Make sure we can write the IP header before changing DSCP bits")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 net/sched/sch_cake.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index cae006bef565..094d6e652deb 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1551,7 +1551,7 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
 	return idx + (tin << 16);
 }
 
-static u8 cake_handle_diffserv(struct sk_buff *skb, u16 wash)
+static u8 cake_handle_diffserv(struct sk_buff *skb, bool wash)
 {
 	const int offset = skb_network_offset(skb);
 	u16 *buf, buf_;
@@ -1612,14 +1612,17 @@ static struct cake_tin_data *cake_select_tin(struct Qdisc *sch,
 {
 	struct cake_sched_data *q = qdisc_priv(sch);
 	u32 tin, mark;
+	bool wash;
 	u8 dscp;
 
 	/* Tin selection: Default to diffserv-based selection, allow overriding
-	 * using firewall marks or skb->priority.
+	 * using firewall marks or skb->priority. Call DSCP parsing early if
+	 * wash is enabled, otherwise defer to below to skip unneeded parsing.
 	 */
-	dscp = cake_handle_diffserv(skb,
-				    q->rate_flags & CAKE_FLAG_WASH);
 	mark = (skb->mark & q->fwmark_mask) >> q->fwmark_shft;
+	wash = !!(q->rate_flags & CAKE_FLAG_WASH);
+	if (wash)
+		dscp = cake_handle_diffserv(skb, wash);
 
 	if (q->tin_mode == CAKE_DIFFSERV_BESTEFFORT)
 		tin = 0;
@@ -1633,6 +1636,8 @@ static struct cake_tin_data *cake_select_tin(struct Qdisc *sch,
 		tin = q->tin_order[TC_H_MIN(skb->priority) - 1];
 
 	else {
+		if (!wash)
+			dscp = cake_handle_diffserv(skb, wash);
 		tin = q->tin_index[dscp];
 
 		if (unlikely(tin >= q->tin_cnt))


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 3/3] sch_cake: fix a few style nits
  2020-06-25 20:12 [PATCH net 0/3] sched: A couple of fixes for sch_cake Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 1/3] sch_cake: don't try to reallocate or unshare skb unconditionally Toke Høiland-Jørgensen
  2020-06-25 20:12 ` [PATCH net 2/3] sch_cake: don't call diffserv parsing code when it is not needed Toke Høiland-Jørgensen
@ 2020-06-25 20:12 ` Toke Høiland-Jørgensen
  2020-06-25 23:25 ` [PATCH net 0/3] sched: A couple of fixes for sch_cake David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-06-25 20:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, cake

From: Toke Høiland-Jørgensen <toke@redhat.com>

I spotted a few nits when comparing the in-tree version of sch_cake with
the out-of-tree one: A redundant error variable declaration shadowing an
outer declaration, and an indentation alignment issue. Fix both of these.

Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 net/sched/sch_cake.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 094d6e652deb..ca813697728e 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -2715,7 +2715,7 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
 	qdisc_watchdog_init(&q->watchdog, sch);
 
 	if (opt) {
-		int err = cake_change(sch, opt, extack);
+		err = cake_change(sch, opt, extack);
 
 		if (err)
 			return err;
@@ -3032,7 +3032,7 @@ static int cake_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 			PUT_STAT_S32(BLUE_TIMER_US,
 				     ktime_to_us(
 					     ktime_sub(now,
-						     flow->cvars.blue_timer)));
+						       flow->cvars.blue_timer)));
 		}
 		if (flow->cvars.dropping) {
 			PUT_STAT_S32(DROP_NEXT_US,


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net 0/3] sched: A couple of fixes for sch_cake
  2020-06-25 20:12 [PATCH net 0/3] sched: A couple of fixes for sch_cake Toke Høiland-Jørgensen
                   ` (2 preceding siblings ...)
  2020-06-25 20:12 ` [PATCH net 3/3] sch_cake: fix a few style nits Toke Høiland-Jørgensen
@ 2020-06-25 23:25 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2020-06-25 23:25 UTC (permalink / raw)
  To: toke; +Cc: netdev, cake

From: Toke Høiland-Jørgensen <toke@redhat.com>
Date: Thu, 25 Jun 2020 22:12:06 +0200

> This series contains a couple of fixes for diffserv handling in sch_cake that
> provide a nice speedup (with a somewhat pedantic nit fix tacked on to the end).
> 
> Not quite sure about whether this should go to stable; it does provide a nice
> speedup, but it's not strictly a fix in the "correctness" sense. I lean towards
> including this in stable as well, since our most important consumer of that
> (OpenWrt) is likely to backport the series anyway.

Series applied and queued up for -stable, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-06-25 23:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-25 20:12 [PATCH net 0/3] sched: A couple of fixes for sch_cake Toke Høiland-Jørgensen
2020-06-25 20:12 ` [PATCH net 1/3] sch_cake: don't try to reallocate or unshare skb unconditionally Toke Høiland-Jørgensen
2020-06-25 20:12 ` [PATCH net 2/3] sch_cake: don't call diffserv parsing code when it is not needed Toke Høiland-Jørgensen
2020-06-25 20:12 ` [PATCH net 3/3] sch_cake: fix a few style nits Toke Høiland-Jørgensen
2020-06-25 23:25 ` [PATCH net 0/3] sched: A couple of fixes for sch_cake David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).