]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop virtio_net-do-not-pull-payload-in-skb-head.patch from everywhere
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Apr 2021 10:46:34 +0000 (12:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Apr 2021 10:46:34 +0000 (12:46 +0200)
queue-4.19/series
queue-4.19/virtio_net-do-not-pull-payload-in-skb-head.patch [deleted file]
queue-5.10/series
queue-5.10/virtio_net-do-not-pull-payload-in-skb-head.patch [deleted file]
queue-5.11/series
queue-5.11/virtio_net-do-not-pull-payload-in-skb-head.patch [deleted file]
queue-5.4/series
queue-5.4/virtio_net-do-not-pull-payload-in-skb-head.patch [deleted file]

index 678643c0e5a27d4151d6498f963a626a95c6fa06..74af154b489a38b6ab3e5cf879e6b323c2df9d06 100644 (file)
@@ -25,7 +25,6 @@ usbip-vudc-synchronize-sysfs-code-paths.patch
 usbip-synchronize-event-handler-with-sysfs-code-paths.patch
 i2c-turn-recovery-error-on-init-to-debug.patch
 virtio_net-add-xdp-meta-data-support.patch
-virtio_net-do-not-pull-payload-in-skb-head.patch
 xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch
 regulator-bd9571mwv-fix-avs-and-dvfs-voltage-range.patch
 net-xfrm-localize-sequence-counter-per-network-names.patch
diff --git a/queue-4.19/virtio_net-do-not-pull-payload-in-skb-head.patch b/queue-4.19/virtio_net-do-not-pull-payload-in-skb-head.patch
deleted file mode 100644 (file)
index 7f75137..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-From 643db789bc1379e4788240b472a6096bde5a03a7 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 2 Apr 2021 06:26:02 -0700
-Subject: virtio_net: Do not pull payload in skb->head
-
-From: Eric Dumazet <edumazet@google.com>
-
-[ Upstream commit 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db ]
-
-Xuan Zhuo reported that commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") brought  a ~10% performance drop.
-
-The reason for the performance drop was that GRO was forced
-to chain sk_buff (using skb_shinfo(skb)->frag_list), which
-uses more memory but also cause packet consumers to go over
-a lot of overhead handling all the tiny skbs.
-
-It turns out that virtio_net page_to_skb() has a wrong strategy :
-It allocates skbs with GOOD_COPY_LEN (128) bytes in skb->head, then
-copies 128 bytes from the page, before feeding the packet to GRO stack.
-
-This was suboptimal before commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") because GRO was using 2 frags per MSS,
-meaning we were not packing MSS with 100% efficiency.
-
-Fix is to pull only the ethernet header in page_to_skb()
-
-Then, we change virtio_net_hdr_to_skb() to pull the missing
-headers, instead of assuming they were already pulled by callers.
-
-This fixes the performance regression, but could also allow virtio_net
-to accept packets with more than 128bytes of headers.
-
-Many thanks to Xuan Zhuo for his report, and his tests/help.
-
-Fixes: 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs")
-Reported-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Link: https://www.spinics.net/lists/netdev/msg731397.html
-Co-Developed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Jason Wang <jasowang@redhat.com>
-Cc: virtualization@lists.linux-foundation.org
-Acked-by: Jason Wang <jasowang@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/virtio_net.c   | 10 +++++++---
- include/linux/virtio_net.h | 14 +++++++++-----
- 2 files changed, 16 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
-index 0b1c6a8906b9..06ddf009f833 100644
---- a/drivers/net/virtio_net.c
-+++ b/drivers/net/virtio_net.c
-@@ -413,9 +413,13 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
-       offset += hdr_padded_len;
-       p += hdr_padded_len;
--      copy = len;
--      if (copy > skb_tailroom(skb))
--              copy = skb_tailroom(skb);
-+      /* Copy all frame if it fits skb->head, otherwise
-+       * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
-+       */
-+      if (len <= skb_tailroom(skb))
-+              copy = len;
-+      else
-+              copy = ETH_HLEN + metasize;
-       skb_put_data(skb, p, copy);
-       if (metasize) {
-diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
-index a1829139ff4a..8f48264f5dab 100644
---- a/include/linux/virtio_net.h
-+++ b/include/linux/virtio_net.h
-@@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
-       skb_reset_mac_header(skb);
-       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
--              u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
--              u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
-+              u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
-+
-+              if (!pskb_may_pull(skb, needed))
-+                      return -EINVAL;
-               if (!skb_partial_csum_set(skb, start, off))
-                       return -EINVAL;
-               p_off = skb_transport_offset(skb) + thlen;
--              if (p_off > skb_headlen(skb))
-+              if (!pskb_may_pull(skb, p_off))
-                       return -EINVAL;
-       } else {
-               /* gso packets without NEEDS_CSUM do not set transport_offset.
-@@ -102,14 +106,14 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
-                       }
-                       p_off = keys.control.thoff + thlen;
--                      if (p_off > skb_headlen(skb) ||
-+                      if (!pskb_may_pull(skb, p_off) ||
-                           keys.basic.ip_proto != ip_proto)
-                               return -EINVAL;
-                       skb_set_transport_header(skb, keys.control.thoff);
-               } else if (gso_type) {
-                       p_off = thlen;
--                      if (p_off > skb_headlen(skb))
-+                      if (!pskb_may_pull(skb, p_off))
-                               return -EINVAL;
-               }
-       }
--- 
-2.30.2
-
index 116e5acd29fe8b144f3b5fdc1ddb0002ed7fffbe..a9bb66fad77292cc6e5f1f4048b55f7f320318f1 100644 (file)
@@ -52,7 +52,6 @@ bpf-refcount-task-stack-in-bpf_get_task_stack.patch
 bpf-sockmap-fix-sk-prot-unhash-op-reset.patch
 bpf-sockmap-fix-incorrect-fwd_alloc-accounting.patch
 net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch
-virtio_net-do-not-pull-payload-in-skb-head.patch
 i40e-fix-sparse-warning-missing-error-code-err.patch
 i40e-fix-sparse-error-vsi-netdev-could-be-null.patch
 i40e-fix-sparse-error-uninitialized-symbol-ring.patch
diff --git a/queue-5.10/virtio_net-do-not-pull-payload-in-skb-head.patch b/queue-5.10/virtio_net-do-not-pull-payload-in-skb-head.patch
deleted file mode 100644 (file)
index 614b1fc..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db Mon Sep 17 00:00:00 2001
-From: Eric Dumazet <edumazet@google.com>
-Date: Fri, 2 Apr 2021 06:26:02 -0700
-Subject: virtio_net: Do not pull payload in skb->head
-
-From: Eric Dumazet <edumazet@google.com>
-
-commit 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db upstream.
-
-Xuan Zhuo reported that commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") brought  a ~10% performance drop.
-
-The reason for the performance drop was that GRO was forced
-to chain sk_buff (using skb_shinfo(skb)->frag_list), which
-uses more memory but also cause packet consumers to go over
-a lot of overhead handling all the tiny skbs.
-
-It turns out that virtio_net page_to_skb() has a wrong strategy :
-It allocates skbs with GOOD_COPY_LEN (128) bytes in skb->head, then
-copies 128 bytes from the page, before feeding the packet to GRO stack.
-
-This was suboptimal before commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") because GRO was using 2 frags per MSS,
-meaning we were not packing MSS with 100% efficiency.
-
-Fix is to pull only the ethernet header in page_to_skb()
-
-Then, we change virtio_net_hdr_to_skb() to pull the missing
-headers, instead of assuming they were already pulled by callers.
-
-This fixes the performance regression, but could also allow virtio_net
-to accept packets with more than 128bytes of headers.
-
-Many thanks to Xuan Zhuo for his report, and his tests/help.
-
-Fixes: 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs")
-Reported-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Link: https://www.spinics.net/lists/netdev/msg731397.html
-Co-Developed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Jason Wang <jasowang@redhat.com>
-Cc: virtualization@lists.linux-foundation.org
-Acked-by: Jason Wang <jasowang@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/net/virtio_net.c   |   10 +++++++---
- include/linux/virtio_net.h |   14 +++++++++-----
- 2 files changed, 16 insertions(+), 8 deletions(-)
-
---- a/drivers/net/virtio_net.c
-+++ b/drivers/net/virtio_net.c
-@@ -406,9 +406,13 @@ static struct sk_buff *page_to_skb(struc
-       offset += hdr_padded_len;
-       p += hdr_padded_len;
--      copy = len;
--      if (copy > skb_tailroom(skb))
--              copy = skb_tailroom(skb);
-+      /* Copy all frame if it fits skb->head, otherwise
-+       * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
-+       */
-+      if (len <= skb_tailroom(skb))
-+              copy = len;
-+      else
-+              copy = ETH_HLEN + metasize;
-       skb_put_data(skb, p, copy);
-       if (metasize) {
---- a/include/linux/virtio_net.h
-+++ b/include/linux/virtio_net.h
-@@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(
-       skb_reset_mac_header(skb);
-       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
--              u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
--              u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
-+              u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
-+
-+              if (!pskb_may_pull(skb, needed))
-+                      return -EINVAL;
-               if (!skb_partial_csum_set(skb, start, off))
-                       return -EINVAL;
-               p_off = skb_transport_offset(skb) + thlen;
--              if (p_off > skb_headlen(skb))
-+              if (!pskb_may_pull(skb, p_off))
-                       return -EINVAL;
-       } else {
-               /* gso packets without NEEDS_CSUM do not set transport_offset.
-@@ -102,14 +106,14 @@ retry:
-                       }
-                       p_off = keys.control.thoff + thlen;
--                      if (p_off > skb_headlen(skb) ||
-+                      if (!pskb_may_pull(skb, p_off) ||
-                           keys.basic.ip_proto != ip_proto)
-                               return -EINVAL;
-                       skb_set_transport_header(skb, keys.control.thoff);
-               } else if (gso_type) {
-                       p_off = thlen;
--                      if (p_off > skb_headlen(skb))
-+                      if (!pskb_may_pull(skb, p_off))
-                               return -EINVAL;
-               }
-       }
index 59753f29309f1da9258260c5da49a1c81522b915..ea54cefbc4ed0e0fa4b80cdf32df07fab6c4b834 100644 (file)
@@ -59,7 +59,6 @@ bpf-refcount-task-stack-in-bpf_get_task_stack.patch
 bpf-sockmap-fix-sk-prot-unhash-op-reset.patch
 bpf-sockmap-fix-incorrect-fwd_alloc-accounting.patch
 net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch
-virtio_net-do-not-pull-payload-in-skb-head.patch
 i40e-fix-sparse-warning-missing-error-code-err.patch
 i40e-fix-sparse-error-vsi-netdev-could-be-null.patch
 i40e-fix-sparse-error-uninitialized-symbol-ring.patch
diff --git a/queue-5.11/virtio_net-do-not-pull-payload-in-skb-head.patch b/queue-5.11/virtio_net-do-not-pull-payload-in-skb-head.patch
deleted file mode 100644 (file)
index 614b1fc..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db Mon Sep 17 00:00:00 2001
-From: Eric Dumazet <edumazet@google.com>
-Date: Fri, 2 Apr 2021 06:26:02 -0700
-Subject: virtio_net: Do not pull payload in skb->head
-
-From: Eric Dumazet <edumazet@google.com>
-
-commit 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db upstream.
-
-Xuan Zhuo reported that commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") brought  a ~10% performance drop.
-
-The reason for the performance drop was that GRO was forced
-to chain sk_buff (using skb_shinfo(skb)->frag_list), which
-uses more memory but also cause packet consumers to go over
-a lot of overhead handling all the tiny skbs.
-
-It turns out that virtio_net page_to_skb() has a wrong strategy :
-It allocates skbs with GOOD_COPY_LEN (128) bytes in skb->head, then
-copies 128 bytes from the page, before feeding the packet to GRO stack.
-
-This was suboptimal before commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") because GRO was using 2 frags per MSS,
-meaning we were not packing MSS with 100% efficiency.
-
-Fix is to pull only the ethernet header in page_to_skb()
-
-Then, we change virtio_net_hdr_to_skb() to pull the missing
-headers, instead of assuming they were already pulled by callers.
-
-This fixes the performance regression, but could also allow virtio_net
-to accept packets with more than 128bytes of headers.
-
-Many thanks to Xuan Zhuo for his report, and his tests/help.
-
-Fixes: 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs")
-Reported-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Link: https://www.spinics.net/lists/netdev/msg731397.html
-Co-Developed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Jason Wang <jasowang@redhat.com>
-Cc: virtualization@lists.linux-foundation.org
-Acked-by: Jason Wang <jasowang@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/net/virtio_net.c   |   10 +++++++---
- include/linux/virtio_net.h |   14 +++++++++-----
- 2 files changed, 16 insertions(+), 8 deletions(-)
-
---- a/drivers/net/virtio_net.c
-+++ b/drivers/net/virtio_net.c
-@@ -406,9 +406,13 @@ static struct sk_buff *page_to_skb(struc
-       offset += hdr_padded_len;
-       p += hdr_padded_len;
--      copy = len;
--      if (copy > skb_tailroom(skb))
--              copy = skb_tailroom(skb);
-+      /* Copy all frame if it fits skb->head, otherwise
-+       * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
-+       */
-+      if (len <= skb_tailroom(skb))
-+              copy = len;
-+      else
-+              copy = ETH_HLEN + metasize;
-       skb_put_data(skb, p, copy);
-       if (metasize) {
---- a/include/linux/virtio_net.h
-+++ b/include/linux/virtio_net.h
-@@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(
-       skb_reset_mac_header(skb);
-       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
--              u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
--              u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
-+              u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
-+
-+              if (!pskb_may_pull(skb, needed))
-+                      return -EINVAL;
-               if (!skb_partial_csum_set(skb, start, off))
-                       return -EINVAL;
-               p_off = skb_transport_offset(skb) + thlen;
--              if (p_off > skb_headlen(skb))
-+              if (!pskb_may_pull(skb, p_off))
-                       return -EINVAL;
-       } else {
-               /* gso packets without NEEDS_CSUM do not set transport_offset.
-@@ -102,14 +106,14 @@ retry:
-                       }
-                       p_off = keys.control.thoff + thlen;
--                      if (p_off > skb_headlen(skb) ||
-+                      if (!pskb_may_pull(skb, p_off) ||
-                           keys.basic.ip_proto != ip_proto)
-                               return -EINVAL;
-                       skb_set_transport_header(skb, keys.control.thoff);
-               } else if (gso_type) {
-                       p_off = thlen;
--                      if (p_off > skb_headlen(skb))
-+                      if (!pskb_may_pull(skb, p_off))
-                               return -EINVAL;
-               }
-       }
index d18cac1aeaf023c423eea29d03f53a22a9bd13a2..69feefc2bd96d53108c2e0982906fccdbd081eb5 100644 (file)
@@ -39,7 +39,6 @@ usbip-vudc-synchronize-sysfs-code-paths.patch
 usbip-synchronize-event-handler-with-sysfs-code-paths.patch
 i2c-turn-recovery-error-on-init-to-debug.patch
 virtio_net-add-xdp-meta-data-support.patch
-virtio_net-do-not-pull-payload-in-skb-head.patch
 net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch
 net-dsa-lantiq_gswip-configure-all-remaining-gswip_m.patch
 xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch
diff --git a/queue-5.4/virtio_net-do-not-pull-payload-in-skb-head.patch b/queue-5.4/virtio_net-do-not-pull-payload-in-skb-head.patch
deleted file mode 100644 (file)
index bffbc5f..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-From 5c71c936f47778846f8b084e2ca396f74230575d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 2 Apr 2021 06:26:02 -0700
-Subject: virtio_net: Do not pull payload in skb->head
-
-From: Eric Dumazet <edumazet@google.com>
-
-[ Upstream commit 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db ]
-
-Xuan Zhuo reported that commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") brought  a ~10% performance drop.
-
-The reason for the performance drop was that GRO was forced
-to chain sk_buff (using skb_shinfo(skb)->frag_list), which
-uses more memory but also cause packet consumers to go over
-a lot of overhead handling all the tiny skbs.
-
-It turns out that virtio_net page_to_skb() has a wrong strategy :
-It allocates skbs with GOOD_COPY_LEN (128) bytes in skb->head, then
-copies 128 bytes from the page, before feeding the packet to GRO stack.
-
-This was suboptimal before commit 3226b158e67c ("net: avoid 32 x truesize
-under-estimation for tiny skbs") because GRO was using 2 frags per MSS,
-meaning we were not packing MSS with 100% efficiency.
-
-Fix is to pull only the ethernet header in page_to_skb()
-
-Then, we change virtio_net_hdr_to_skb() to pull the missing
-headers, instead of assuming they were already pulled by callers.
-
-This fixes the performance regression, but could also allow virtio_net
-to accept packets with more than 128bytes of headers.
-
-Many thanks to Xuan Zhuo for his report, and his tests/help.
-
-Fixes: 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs")
-Reported-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Link: https://www.spinics.net/lists/netdev/msg731397.html
-Co-Developed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Jason Wang <jasowang@redhat.com>
-Cc: virtualization@lists.linux-foundation.org
-Acked-by: Jason Wang <jasowang@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/virtio_net.c   | 10 +++++++---
- include/linux/virtio_net.h | 14 +++++++++-----
- 2 files changed, 16 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
-index b67460864b3c..d8ee001d8e8e 100644
---- a/drivers/net/virtio_net.c
-+++ b/drivers/net/virtio_net.c
-@@ -406,9 +406,13 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
-       offset += hdr_padded_len;
-       p += hdr_padded_len;
--      copy = len;
--      if (copy > skb_tailroom(skb))
--              copy = skb_tailroom(skb);
-+      /* Copy all frame if it fits skb->head, otherwise
-+       * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
-+       */
-+      if (len <= skb_tailroom(skb))
-+              copy = len;
-+      else
-+              copy = ETH_HLEN + metasize;
-       skb_put_data(skb, p, copy);
-       if (metasize) {
-diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
-index 98775d7fa696..b465f8f3e554 100644
---- a/include/linux/virtio_net.h
-+++ b/include/linux/virtio_net.h
-@@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
-       skb_reset_mac_header(skb);
-       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
--              u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
--              u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
-+              u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
-+              u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
-+
-+              if (!pskb_may_pull(skb, needed))
-+                      return -EINVAL;
-               if (!skb_partial_csum_set(skb, start, off))
-                       return -EINVAL;
-               p_off = skb_transport_offset(skb) + thlen;
--              if (p_off > skb_headlen(skb))
-+              if (!pskb_may_pull(skb, p_off))
-                       return -EINVAL;
-       } else {
-               /* gso packets without NEEDS_CSUM do not set transport_offset.
-@@ -102,14 +106,14 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
-                       }
-                       p_off = keys.control.thoff + thlen;
--                      if (p_off > skb_headlen(skb) ||
-+                      if (!pskb_may_pull(skb, p_off) ||
-                           keys.basic.ip_proto != ip_proto)
-                               return -EINVAL;
-                       skb_set_transport_header(skb, keys.control.thoff);
-               } else if (gso_type) {
-                       p_off = thlen;
--                      if (p_off > skb_headlen(skb))
-+                      if (!pskb_may_pull(skb, p_off))
-                               return -EINVAL;
-               }
-       }
--- 
-2.30.2
-