diff options
author | Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 2020-01-18 15:35:38 +0000 |
---|---|---|
committer | Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 2020-06-30 16:09:18 +0100 |
commit | d59dc14515c812ba4c4101958bdc5dba37ab34cb (patch) | |
tree | a6170b6f3a687bcb7e79236f4b08f4b8d0448b89 /target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch | |
parent | 77cd8f64ca261bfb3cf5a905fb2f227981934613 (diff) | |
download | upstream-d59dc14515c812ba4c4101958bdc5dba37ab34cb.tar.gz upstream-d59dc14515c812ba4c4101958bdc5dba37ab34cb.tar.bz2 upstream-d59dc14515c812ba4c4101958bdc5dba37ab34cb.zip |
kernel: cake: backport upstream tweaks & fixes
From upstream:
b8392808eb3f sch_cake: add RFC 8622 LE PHB support to CAKE diffserv handling
3f608f0c4136 sch_cake: fix a few style nits
8c95eca0bb8c sch_cake: don't call diffserv parsing code when it is not needed
9208d2863ac6 sch_cake: don't try to reallocate or unshare skb unconditionally
From netdev not yet accepted:
sch_cake: fix IP protocol handling in the presence of VLAN tags
The VLAN tag handling is actually wider than just cake so upstream are
working out how to fix it generically. We fix it here just for cake.
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Diffstat (limited to 'target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch')
-rw-r--r-- | target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch b/target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch new file mode 100644 index 0000000000..a36095c26c --- /dev/null +++ b/target/linux/generic/backport-5.4/396-5.8-sch_cake-don-t-try-to-reallocate-or-unshare-skb-unco.patch @@ -0,0 +1,96 @@ +From 9208d2863ac689a563b92f2161d8d1e7127d0add Mon Sep 17 00:00:00 2001 +From: Ilya Ponetayev <i.ponetaev@ndmsystems.com> +Date: Thu, 25 Jun 2020 22:12:07 +0200 +Subject: [PATCH] sch_cake: don't try to reallocate or unshare skb + unconditionally +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> +--- + net/sched/sch_cake.c | 41 ++++++++++++++++++++++++++++++----------- + 1 file changed, 30 insertions(+), 11 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1553,30 +1553,49 @@ static unsigned int cake_drop(struct Qdi + + 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): |