[ 3.8.y.z extended stable ] Patch "tuntap: correctly linearize skb when zerocopy is used" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Fri Jul 26 00:24:09 UTC 2013
This is a note to let you know that I have just added a patch titled
tuntap: correctly linearize skb when zerocopy is used
to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree
which can be found at:
http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue
This patch is scheduled to be released in version 3.8.13.6.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From 14f258143cbce1242c582ae367282b37b4f23b8c Mon Sep 17 00:00:00 2001
From: Jason Wang <jasowang at redhat.com>
Date: Wed, 10 Jul 2013 13:43:27 +0800
Subject: tuntap: correctly linearize skb when zerocopy is used
[ Upstream commit 3dd5c3308e8b671e8e8882ba972f51cefbe9fd0d ]
Userspace may produce vectors greater than MAX_SKB_FRAGS. When we try to
linearize parts of the skb to let the rest of iov to be fit in
the frags, we need count copylen into linear when calling tun_alloc_skb()
instead of partly counting it into data_len. Since this breaks
zerocopy_sg_from_iovec() since its inner counter assumes nr_frags should
be zero at beginning. This cause nr_frags to be increased wrongly without
setting the correct frags.
This bug were introduced from 0690899b4d4501b3505be069b9a687e68ccbe15b
(tun: experimental zero copy tx support)
Cc: Michael S. Tsirkin <mst at redhat.com>
Signed-off-by: Jason Wang <jasowang at redhat.com>
Acked-by: Michael S. Tsirkin <mst at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
drivers/net/tun.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2a56317..0ebfa18 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1045,7 +1045,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
{
struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
struct sk_buff *skb;
- size_t len = total_len, align = NET_SKB_PAD;
+ size_t len = total_len, align = NET_SKB_PAD, linear;
struct virtio_net_hdr gso = { 0 };
int offset = 0;
int copylen;
@@ -1109,10 +1109,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
copylen = gso.hdr_len;
if (!copylen)
copylen = GOODCOPY_LEN;
- } else
+ linear = copylen;
+ } else {
copylen = len;
+ linear = gso.hdr_len;
+ }
- skb = tun_alloc_skb(tfile, align, copylen, gso.hdr_len, noblock);
+ skb = tun_alloc_skb(tfile, align, copylen, linear, noblock);
if (IS_ERR(skb)) {
if (PTR_ERR(skb) != -EAGAIN)
tun->dev->stats.rx_dropped++;
--
1.8.1.2
More information about the kernel-team
mailing list