From 158d3b65d58b98c5e03241ebbff712cb4402b8f1 Mon Sep 17 00:00:00 2001 From: Justin M. Forbes Date: Feb 14 2013 21:31:34 +0000 Subject: Linux v3.7.8 --- diff --git a/kernel.spec b/kernel.spec index a5fc883..12f40a8 100644 --- a/kernel.spec +++ b/kernel.spec @@ -62,7 +62,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 202 +%global baserelease 201 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -74,7 +74,7 @@ Summary: The Linux kernel %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 7 +%define stable_update 8 # Is it a -stable RC? %define stable_rc 0 # Set rpm version accordingly @@ -781,16 +781,10 @@ Patch22233: 8139cp-re-enable-interrupts-after-tx-timeout.patch #rhbz 892428 Patch22238: brcmsmac-updates-rhbz892428.patch -#rhbz 863424 -Patch22239: Revert-iwlwifi-fix-the-reclaimed-packet-tracking-upon.patch - #rhbz 799564 Patch22240: Input-increase-struct-ps2dev-cmdbuf-to-8-bytes.patch Patch22241: Input-add-support-for-Cypress-PS2-Trackpads.patch -#rhbz 903881 -Patch22246: rtlwifi-Fix-scheduling-while-atomic-bug.patch - #rhbz 892811 Patch22247: ath9k_rx_dma_stop_check.patch @@ -801,8 +795,6 @@ Patch23000: silence-brcmsmac-warning.patch Patch23100: validate-pud-largepage.patch -Patch23200: net_37.mbox - #rhbz 909591 Patch21255: usb-cypress-supertop.patch @@ -1521,16 +1513,10 @@ ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch #rhbz 892428 ApplyPatch brcmsmac-updates-rhbz892428.patch -#rhbz 863424 -ApplyPatch Revert-iwlwifi-fix-the-reclaimed-packet-tracking-upon.patch - #rhbz 799564 ApplyPatch Input-increase-struct-ps2dev-cmdbuf-to-8-bytes.patch ApplyPatch Input-add-support-for-Cypress-PS2-Trackpads.patch -#rhbz 903881 -ApplyPatch rtlwifi-Fix-scheduling-while-atomic-bug.patch - #rhbz 892811 ApplyPatch ath9k_rx_dma_stop_check.patch @@ -1538,8 +1524,6 @@ ApplyPatch silence-brcmsmac-warning.patch ApplyPatch validate-pud-largepage.patch -ApplyPatch net_37.mbox - #rhbz 906309 910848 CVE-2013-0228 ApplyPatch xen-dont-assume-ds-is-usable-in-xen_iret-for-32-bit-PVOPS.patch @@ -2409,6 +2393,9 @@ fi # ||----w | # || || %changelog +* Thu Feb 14 2013 Justin M. Forbes - 3.7.8-201 +- Linux v3.7.8 + * Thu Feb 14 2013 Adam Jackson - i915: Hush asserts during TV detection, just useless noise - i915: Fix LVDS downclock to not cripple performance (#901951) diff --git a/net_37.mbox b/net_37.mbox deleted file mode 100644 index 742400e..0000000 --- a/net_37.mbox +++ /dev/null @@ -1,2939 +0,0 @@ -From 3e79c606d6a4504e2608cf03b6d4dd0c6b6dc008 Mon Sep 17 00:00:00 2001 -From: Cong Wang -Date: Mon, 7 Jan 2013 21:17:00 +0000 -Subject: [PATCH 01/44] net: prevent setting ttl=0 via IP_TTL - -[ Upstream commit c9be4a5c49cf51cc70a993f004c5bb30067a65ce ] - -A regression is introduced by the following commit: - - commit 4d52cfbef6266092d535237ba5a4b981458ab171 - Author: Eric Dumazet - Date: Tue Jun 2 00:42:16 2009 -0700 - - net: ipv4/ip_sockglue.c cleanups - - Pure cleanups - -but it is not a pure cleanup... - - - if (val != -1 && (val < 1 || val>255)) - + if (val != -1 && (val < 0 || val > 255)) - -Since there is no reason provided to allow ttl=0, change it back. - -Reported-by: nitin padalia -Cc: nitin padalia -Cc: Eric Dumazet -Cc: David S. Miller -Signed-off-by: Cong Wang -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller ---- - net/ipv4/ip_sockglue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c -index 14bbfcf..e95d72b 100644 ---- a/net/ipv4/ip_sockglue.c -+++ b/net/ipv4/ip_sockglue.c -@@ -590,7 +590,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, - case IP_TTL: - if (optlen < 1) - goto e_inval; -- if (val != -1 && (val < 0 || val > 255)) -+ if (val != -1 && (val < 1 || val > 255)) - goto e_inval; - inet->uc_ttl = val; - break; --- -1.7.11.7 - - -From a91ced21d91a2b96ccd2b6e4524df45ff8c9201c Mon Sep 17 00:00:00 2001 -From: Romain Kuntz -Date: Wed, 9 Jan 2013 15:02:26 +0100 -Subject: [PATCH 02/44] ipv6: fix the noflags test in - addrconf_get_prefix_route - -[ Upstream commit 85da53bf1c336bb07ac038fb951403ab0478d2c5 ] - -The tests on the flags in addrconf_get_prefix_route() does no make -much sense: the 'noflags' parameter contains the set of flags that -must not match with the route flags, so the test must be done -against 'noflags', and not against 'flags'. - -Signed-off-by: Romain Kuntz -Acked-by: YOSHIFUJI Hideaki -Signed-off-by: David S. Miller ---- - net/ipv6/addrconf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 0424e4e..a468a36 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -1723,7 +1723,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, - continue; - if ((rt->rt6i_flags & flags) != flags) - continue; -- if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0)) -+ if ((rt->rt6i_flags & noflags) != 0) - continue; - dst_hold(&rt->dst); - break; --- -1.7.11.7 - - -From 43a18605f87a654eb6673ffb8ff99df13420d544 Mon Sep 17 00:00:00 2001 -From: Stanislaw Gruszka -Date: Thu, 10 Jan 2013 23:19:10 +0000 -Subject: [PATCH 03/44] net, wireless: overwrite default_ethtool_ops - -[ Upstream commit d07d7507bfb4e23735c9b83e397c43e1e8a173e8 ] - -Since: - -commit 2c60db037034d27f8c636403355d52872da92f81 -Author: Eric Dumazet -Date: Sun Sep 16 09:17:26 2012 +0000 - - net: provide a default dev->ethtool_ops - -wireless core does not correctly assign ethtool_ops. - -After alloc_netdev*() call, some cfg80211 drivers provide they own -ethtool_ops, but some do not. For them, wireless core provide generic -cfg80211_ethtool_ops, which is assigned in NETDEV_REGISTER notify call: - - if (!dev->ethtool_ops) - dev->ethtool_ops = &cfg80211_ethtool_ops; - -But after Eric's commit, dev->ethtool_ops is no longer NULL (on cfg80211 -drivers without custom ethtool_ops), but points to &default_ethtool_ops. - -In order to fix the problem, provide function which will overwrite -default_ethtool_ops and use it by wireless core. - -Signed-off-by: Stanislaw Gruszka -Acked-by: Johannes Berg -Acked-by: Ben Hutchings -Signed-off-by: David S. Miller ---- - include/linux/netdevice.h | 3 +++ - net/core/dev.c | 8 ++++++++ - net/wireless/core.c | 3 +-- - 3 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index a848ffc..825fb7e 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -60,6 +60,9 @@ struct wireless_dev; - #define SET_ETHTOOL_OPS(netdev,ops) \ - ( (netdev)->ethtool_ops = (ops) ) - -+extern void netdev_set_default_ethtool_ops(struct net_device *dev, -+ const struct ethtool_ops *ops); -+ - /* hardware address assignment types */ - #define NET_ADDR_PERM 0 /* address is permanent (default) */ - #define NET_ADDR_RANDOM 1 /* address is generated randomly */ -diff --git a/net/core/dev.c b/net/core/dev.c -index e5942bf..3470794 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -6012,6 +6012,14 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) - - static const struct ethtool_ops default_ethtool_ops; - -+void netdev_set_default_ethtool_ops(struct net_device *dev, -+ const struct ethtool_ops *ops) -+{ -+ if (dev->ethtool_ops == &default_ethtool_ops) -+ dev->ethtool_ops = ops; -+} -+EXPORT_SYMBOL_GPL(netdev_set_default_ethtool_ops); -+ - /** - * alloc_netdev_mqs - allocate network device - * @sizeof_priv: size of private data to allocate space for -diff --git a/net/wireless/core.c b/net/wireless/core.c -index 3f72530..d1531e5 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -856,8 +856,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, - /* allow mac80211 to determine the timeout */ - wdev->ps_timeout = -1; - -- if (!dev->ethtool_ops) -- dev->ethtool_ops = &cfg80211_ethtool_ops; -+ netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops); - - if ((wdev->iftype == NL80211_IFTYPE_STATION || - wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || --- -1.7.11.7 - - -From 10a209641c46d1b7fab2e45148ac83a2e3ec9bab Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Sun, 13 Jan 2013 18:21:51 +0000 -Subject: [PATCH 04/44] tcp: fix a panic on UP machines in - reqsk_fastopen_remove - -[ Upstream commit cce894bb824429fd312706c7012acae43e725865 ] - -spin_is_locked() on a non !SMP build is kind of useless. - -BUG_ON(!spin_is_locked(xx)) is guaranteed to crash. - -Just remove this check in reqsk_fastopen_remove() as -the callers do hold the socket lock. - -Reported-by: Ketan Kulkarni -Signed-off-by: Eric Dumazet -Cc: Jerry Chu -Cc: Yuchung Cheng -Cc: Dave Taht -Acked-by: H.K. Jerry Chu -Signed-off-by: David S. Miller ---- - net/core/request_sock.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/net/core/request_sock.c b/net/core/request_sock.c -index c31d9e8..4425148 100644 ---- a/net/core/request_sock.c -+++ b/net/core/request_sock.c -@@ -186,8 +186,6 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, - struct fastopen_queue *fastopenq = - inet_csk(lsk)->icsk_accept_queue.fastopenq; - -- BUG_ON(!spin_is_locked(&sk->sk_lock.slock) && !sock_owned_by_user(sk)); -- - tcp_sk(sk)->fastopen_rsk = NULL; - spin_lock_bh(&fastopenq->lock); - fastopenq->qlen--; --- -1.7.11.7 - - -From d9c9e8ef86d318c97b88dc4efcf46530a0b46543 Mon Sep 17 00:00:00 2001 -From: Stephen Hemminger -Date: Wed, 16 Jan 2013 09:55:57 -0800 -Subject: [PATCH 05/44] MAINTAINERS: Stephen Hemminger email change - -[ Upstream commit adbbf69d1a54abf424e91875746a610dcc80017d ] - -I changed my email because the vyatta.com mail server is now -redirected to brocade.com; and the Brocade mail system -is not friendly to Linux desktop users. - -Signed-off-by: Stephen Hemminger -Signed-off-by: David S. Miller ---- - MAINTAINERS | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 9386a63..4eb1deb 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2898,7 +2898,7 @@ S: Maintained - F: drivers/net/ethernet/i825xx/eexpress.* - - ETHERNET BRIDGE --M: Stephen Hemminger -+M: Stephen Hemminger - L: bridge@lists.linux-foundation.org - L: netdev@vger.kernel.org - W: http://www.linuxfoundation.org/en/Net:Bridge -@@ -4739,7 +4739,7 @@ S: Maintained - - MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) - M: Mirko Lindner --M: Stephen Hemminger -+M: Stephen Hemminger - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/ethernet/marvell/sk* -@@ -4993,7 +4993,7 @@ S: Supported - F: drivers/infiniband/hw/nes/ - - NETEM NETWORK EMULATOR --M: Stephen Hemminger -+M: Stephen Hemminger - L: netem@lists.linux-foundation.org - S: Maintained - F: net/sched/sch_netem.c --- -1.7.11.7 - - -From bb1e86b0fd4ee8fa047dee973bad46363420a80a Mon Sep 17 00:00:00 2001 -From: Romain KUNTZ -Date: Wed, 16 Jan 2013 12:47:40 +0000 -Subject: [PATCH 06/44] ipv6: fix header length calculation in - ip6_append_data() - -[ Upstream commit 7efdba5bd9a2f3e2059beeb45c9fa55eefe1bced ] - -Commit 299b0767 (ipv6: Fix IPsec slowpath fragmentation problem) -has introduced a error in the header length calculation that -provokes corrupted packets when non-fragmentable extensions -headers (Destination Option or Routing Header Type 2) are used. - -rt->rt6i_nfheader_len is the length of the non-fragmentable -extension header, and it should be substracted to -rt->dst.header_len, and not to exthdrlen, as it was done before -commit 299b0767. - -This patch reverts to the original and correct behavior. It has -been successfully tested with and without IPsec on packets -that include non-fragmentable extensions headers. - -Signed-off-by: Romain Kuntz -Acked-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - net/ipv6/ip6_output.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index aece3e7..8dea314 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -1279,10 +1279,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, - if (dst_allfrag(rt->dst.path)) - cork->flags |= IPCORK_ALLFRAG; - cork->length = 0; -- exthdrlen = (opt ? opt->opt_flen : 0) - rt->rt6i_nfheader_len; -+ exthdrlen = (opt ? opt->opt_flen : 0); - length += exthdrlen; - transhdrlen += exthdrlen; -- dst_exthdrlen = rt->dst.header_len; -+ dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len; - } else { - rt = (struct rt6_info *)cork->dst; - fl6 = &inet->cork.fl.u.ip6; --- -1.7.11.7 - - -From f6296b4042c585592d4251b423f9d2bc6bfdf2cb Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Thu, 17 Jan 2013 13:30:49 -0800 -Subject: [PATCH 07/44] macvlan: fix macvlan_get_size() - -[ Upstream commit 01fe944f1024bd4e5c327ddbe8d657656b66af2f ] - -commit df8ef8f3aaa (macvlan: add FDB bridge ops and macvlan flags) -forgot to update macvlan_get_size() after the addition of -IFLA_MACVLAN_FLAGS - -Signed-off-by: Eric Dumazet -Cc: John Fastabend -Signed-off-by: David S. Miller ---- - drivers/net/macvlan.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index 68a43fe..d3fb97d 100644 ---- a/drivers/net/macvlan.c -+++ b/drivers/net/macvlan.c -@@ -822,7 +822,10 @@ static int macvlan_changelink(struct net_device *dev, - - static size_t macvlan_get_size(const struct net_device *dev) - { -- return nla_total_size(4); -+ return (0 -+ + nla_total_size(4) /* IFLA_MACVLAN_MODE */ -+ + nla_total_size(2) /* IFLA_MACVLAN_FLAGS */ -+ ); - } - - static int macvlan_fill_info(struct sk_buff *skb, --- -1.7.11.7 - - -From e8002481da092b921028dfb8c82873f5b8f378d3 Mon Sep 17 00:00:00 2001 -From: Rob Herring -Date: Wed, 16 Jan 2013 13:36:37 +0000 -Subject: [PATCH 08/44] net: calxedaxgmac: throw away overrun frames - -[ Upstream commit d6fb3be544b46a7611a3373fcaa62b5b0be01888 ] - -The xgmac driver assumes 1 frame per descriptor. If a frame larger than -the descriptor's buffer size is received, the frame will spill over into -the next descriptor. So check for received frames that span more than one -descriptor and discard them. This prevents a crash if we receive erroneous -large packets. - -Signed-off-by: Rob Herring -Cc: netdev@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/calxeda/xgmac.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c -index 16814b3..e29c1b6 100644 ---- a/drivers/net/ethernet/calxeda/xgmac.c -+++ b/drivers/net/ethernet/calxeda/xgmac.c -@@ -546,6 +546,10 @@ static int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) - return -1; - } - -+ /* All frames should fit into a single buffer */ -+ if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG)) -+ return -1; -+ - /* Check if packet has checksum already */ - if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && - !(ext_status & RXDESC_IP_PAYLOAD_MASK)) --- -1.7.11.7 - - -From cea9757b2a648469443228917fb352b0d06d215d Mon Sep 17 00:00:00 2001 -From: Yan Burman -Date: Thu, 17 Jan 2013 05:30:42 +0000 -Subject: [PATCH 09/44] net/mlx4_en: Fix bridged vSwitch configuration for non - SRIOV mode - -[ Upstream commit 213815a1e6ae70b9648483b110bc5081795f99e8 ] - -Commit 5b4c4d36860e "mlx4_en: Allow communication between functions on -same host" introduced a regression under which a bridge acting as vSwitch -whose uplink is an mlx4 Ethernet device become non-operative in native -(non sriov) mode. This happens since broadcast ARP requests sent by VMs -were loopback-ed by the HW and hence the bridge learned VM source MACs -on both the VM and the uplink ports. - -The fix is to place the DMAC in the send WQE only under SRIOV/eSwitch -configuration or when the device is in selftest. - -Reviewed-by: Or Gerlitz -Signed-off-by: Yan Burman -Signed-off-by: Amir Vadai -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mellanox/mlx4/en_tx.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c -index b35094c..fc1ac65 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c -@@ -629,10 +629,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) - ring->tx_csum++; - } - -- /* Copy dst mac address to wqe */ -- ethh = (struct ethhdr *)skb->data; -- tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); -- tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); -+ if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) { -+ /* Copy dst mac address to wqe. This allows loopback in eSwitch, -+ * so that VFs and PF can communicate with each other -+ */ -+ ethh = (struct ethhdr *)skb->data; -+ tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); -+ tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); -+ } -+ - /* Handle LSO (TSO) packets */ - if (lso_header_size) { - /* Mark opcode as LSO */ --- -1.7.11.7 - - -From 71558617a4904a27b7dd35dfb82c9029b87af357 Mon Sep 17 00:00:00 2001 -From: Or Gerlitz -Date: Thu, 17 Jan 2013 05:30:43 +0000 -Subject: [PATCH 10/44] net/mlx4_core: Set number of msix vectors under SRIOV - mode to firmware defaults - -[ Upstream commit ca4c7b35f75492de7fbf5ee95be07481c348caee ] - -The lines - - if (mlx4_is_mfunc(dev)) { - nreq = 2; - } else { - -which hard code the number of requested msi-x vectors under multi-function -mode to two can be removed completely, since the firmware sets num_eqs and -reserved_eqs appropriately Thus, the code line: - - nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, nreq); - -is by itself sufficient and correct for all cases. Currently, for mfunc -mode num_eqs = 32 and reserved_eqs = 28, hence four vectors will be enabled. - -This triples (one vector is used for the async events and commands EQ) the -horse power provided for processing of incoming packets on netdev RSS scheme, -IO initiators/targets commands processing flows, etc. - -Reviewed-by: Jack Morgenstein -Signed-off-by: Amir Vadai -Signed-off-by: Or Gerlitz -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mellanox/mlx4/main.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c -index 2aa80af..d4b3935 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/main.c -+++ b/drivers/net/ethernet/mellanox/mlx4/main.c -@@ -1702,15 +1702,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) - int i; - - if (msi_x) { -- /* In multifunction mode each function gets 2 msi-X vectors -- * one for data path completions anf the other for asynch events -- * or command completions */ -- if (mlx4_is_mfunc(dev)) { -- nreq = 2; -- } else { -- nreq = min_t(int, dev->caps.num_eqs - -- dev->caps.reserved_eqs, nreq); -- } -+ nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, -+ nreq); - - entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); - if (!entries) --- -1.7.11.7 - - -From 9e1626d8ecc01327036f8ad064a326a2ad31ae93 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Sat, 19 Jan 2013 16:10:37 +0000 -Subject: [PATCH 11/44] tcp: fix incorrect LOCKDROPPEDICMPS counter -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit b74aa930ef49a3c0d8e4c1987f89decac768fb2c ] - -commit 563d34d057 (tcp: dont drop MTU reduction indications) -added an error leading to incorrect accounting of -LINUX_MIB_LOCKDROPPEDICMPS - -If socket is owned by the user, we want to increment -this SNMP counter, unless the message is a -(ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED) one. - -Reported-by: Maciej Żenczykowski -Signed-off-by: Eric Dumazet -Cc: Neal Cardwell -Signed-off-by: Maciej Żenczykowski -Acked-by: Neal Cardwell -Signed-off-by: David S. Miller ---- - net/ipv4/tcp_ipv4.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index bc3cb46..e637770 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -380,11 +380,10 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) - * We do take care of PMTU discovery (RFC1191) special case : - * we can receive locally generated ICMP messages while socket is held. - */ -- if (sock_owned_by_user(sk) && -- type != ICMP_DEST_UNREACH && -- code != ICMP_FRAG_NEEDED) -- NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); -- -+ if (sock_owned_by_user(sk)) { -+ if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) -+ NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); -+ } - if (sk->sk_state == TCP_CLOSE) - goto out; - --- -1.7.11.7 - - -From 67ee774cb516f0fe5259760c59a807de18fd78d8 Mon Sep 17 00:00:00 2001 -From: Tilman Schmidt -Date: Mon, 21 Jan 2013 11:57:21 +0000 -Subject: [PATCH 12/44] isdn/gigaset: fix zero size border case in debug dump - -[ Upstream commit d721a1752ba544df8d7d36959038b26bc92bdf80 ] - -If subtracting 12 from l leaves zero we'd do a zero size allocation, -leading to an oops later when we try to set the NUL terminator. - -Reported-by: Dan Carpenter -Signed-off-by: Tilman Schmidt -Signed-off-by: David S. Miller ---- - drivers/isdn/gigaset/capi.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c -index 68452b7..03a0a01 100644 ---- a/drivers/isdn/gigaset/capi.c -+++ b/drivers/isdn/gigaset/capi.c -@@ -248,6 +248,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, - CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l, - CAPIMSG_CONTROL(data)); - l -= 12; -+ if (l <= 0) -+ return; - dbgline = kmalloc(3 * l, GFP_ATOMIC); - if (!dbgline) - return; --- -1.7.11.7 - - -From a7640c96407dd3f44a8f709f9ae880bc6211b04b Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Tue, 22 Jan 2013 06:33:05 +0000 -Subject: [PATCH 13/44] netxen: fix off by one bug in - netxen_release_tx_buffer() - -[ Upstream commit a05948f296ce103989b28a2606e47d2e287c3c89 ] - -Christoph Paasch found netxen could trigger a BUG in its dismantle -phase, in netxen_release_tx_buffer(), using full size TSO packets. - -cmd_buf->frag_count includes the skb->data part, so the loop must -start at index 1 instead of 0, or else we can make an out -of bound access to cmd_buff->frag_array[MAX_SKB_FRAGS + 2] - -Christoph provided the fixes in netxen_map_tx_skb() function. -In case of a dma mapping error, its better to clear the dma fields -so that we don't try to unmap them again in netxen_release_tx_buffer() - -Reported-by: Christoph Paasch -Signed-off-by: Eric Dumazet -Tested-by: Christoph Paasch -Cc: Sony Chacko -Cc: Rajesh Borundia -Signed-off-by: Christoph Paasch -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 2 +- - drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c -index bc165f4..695667d 100644 ---- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c -+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c -@@ -144,7 +144,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter) - buffrag->length, PCI_DMA_TODEVICE); - buffrag->dma = 0ULL; - } -- for (j = 0; j < cmd_buf->frag_count; j++) { -+ for (j = 1; j < cmd_buf->frag_count; j++) { - buffrag++; - if (buffrag->dma) { - pci_unmap_page(adapter->pdev, buffrag->dma, -diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -index df45061..1b55ca1 100644 ---- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -@@ -1963,10 +1963,12 @@ unwind: - while (--i >= 0) { - nf = &pbuf->frag_array[i+1]; - pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); -+ nf->dma = 0ULL; - } - - nf = &pbuf->frag_array[0]; - pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); -+ nf->dma = 0ULL; - - out_err: - return -ENOMEM; --- -1.7.11.7 - - -From 6aaa957c972243891f2edb3905765deffa37dbff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= -Date: Mon, 21 Jan 2013 22:30:35 +0000 -Subject: [PATCH 14/44] r8169: remove the obsolete and incorrect AMD - workaround -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 5d0feaff230c0abfe4a112e6f09f096ed99e0b2d ] - -This was introduced in commit 6dccd16 "r8169: merge with version -6.001.00 of Realtek's r8169 driver". I did not find the version -6.001.00 online, but in 6.002.00 or any later r8169 from Realtek -this hunk is no longer present. - -Also commit 05af214 "r8169: fix Ethernet Hangup for RTL8110SC -rev d" claims to have fixed this issue otherwise. - -The magic compare mask of 0xfffe000 is dubious as it masks -parts of the Reserved part, and parts of the VLAN tag. But this -does not make much sense as the VLAN tag parts are perfectly -valid there. In matter of fact this seems to be triggered with -any VLAN tagged packet as RxVlanTag bit is matched. I would -suspect 0xfffe0000 was intended to test reserved part only. - -Finally, this hunk is evil as it can cause more packets to be -handled than what was NAPI quota causing net/core/dev.c: -net_rx_action(): WARN_ON_ONCE(work > weight) to trigger, and -mess up the NAPI state causing device to hang. - -As result, any system using VLANs and having high receive -traffic (so that NAPI poll budget limits rtl_rx) would result -in device hang. - -Signed-off-by: Timo Teräs -Acked-by: Francois Romieu -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/realtek/r8169.c | 7 ------- - 1 file changed, 7 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c -index 927aa33..6afe74e 100644 ---- a/drivers/net/ethernet/realtek/r8169.c -+++ b/drivers/net/ethernet/realtek/r8169.c -@@ -6064,13 +6064,6 @@ process_pkt: - tp->rx_stats.bytes += pkt_size; - u64_stats_update_end(&tp->rx_stats.syncp); - } -- -- /* Work around for AMD plateform. */ -- if ((desc->opts2 & cpu_to_le32(0xfffe000)) && -- (tp->mac_version == RTL_GIGA_MAC_VER_05)) { -- desc->opts2 = 0; -- cur_rx++; -- } - } - - count = cur_rx - tp->cur_rx; --- -1.7.11.7 - - -From 24d7fa8b3e9f8f9834e8af9f13a49647cbfda7a2 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Fri, 25 Jan 2013 07:44:41 +0000 -Subject: [PATCH 15/44] net: loopback: fix a dst refcounting issue - -[ Upstream commit 794ed393b707f01858f5ebe2ae5eabaf89d00022 ] - -Ben Greear reported crashes in ip_rcv_finish() on a stress -test involving many macvlans. - -We tracked the bug to a dst use after free. ip_rcv_finish() -was calling dst->input() and got garbage for dst->input value. - -It appears the bug is in loopback driver, lacking -a skb_dst_force() before calling netif_rx(). - -As a result, a non refcounted dst, normally protected by a -RCU read_lock section, was escaping this section and could -be freed before the packet being processed. - - [] loopback_xmit+0x64/0x83 - [] dev_hard_start_xmit+0x26c/0x35e - [] dev_queue_xmit+0x2c4/0x37c - [] ? dev_hard_start_xmit+0x35e/0x35e - [] ? eth_header+0x28/0xb6 - [] neigh_resolve_output+0x176/0x1a7 - [] ip_finish_output2+0x297/0x30d - [] ? ip_finish_output2+0x137/0x30d - [] ip_finish_output+0x63/0x68 - [] ip_output+0x61/0x67 - [] dst_output+0x17/0x1b - [] ip_local_out+0x1e/0x23 - [] ip_queue_xmit+0x315/0x353 - [] ? ip_send_unicast_reply+0x2cc/0x2cc - [] tcp_transmit_skb+0x7ca/0x80b - [] tcp_connect+0x53c/0x587 - [] ? getnstimeofday+0x44/0x7d - [] ? ktime_get_real+0x11/0x3e - [] tcp_v4_connect+0x3c2/0x431 - [] __inet_stream_connect+0x84/0x287 - [] ? inet_stream_connect+0x22/0x49 - [] ? _local_bh_enable_ip+0x84/0x9f - [] ? local_bh_enable+0xd/0x11 - [] ? lock_sock_nested+0x6e/0x79 - [] ? inet_stream_connect+0x22/0x49 - [] inet_stream_connect+0x33/0x49 - [] sys_connect+0x75/0x98 - -This bug was introduced in linux-2.6.35, in commit -7fee226ad2397b (net: add a noref bit on skb dst) - -skb_dst_force() is enforced in dev_queue_xmit() for devices having a -qdisc. - -Reported-by: Ben Greear -Signed-off-by: Eric Dumazet -Tested-by: Ben Greear -Signed-off-by: David S. Miller ---- - drivers/net/loopback.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c -index 81f8f9e..fcbf680 100644 ---- a/drivers/net/loopback.c -+++ b/drivers/net/loopback.c -@@ -77,6 +77,11 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, - - skb_orphan(skb); - -+ /* Before queueing this packet to netif_rx(), -+ * make sure dst is refcounted. -+ */ -+ skb_dst_force(skb); -+ - skb->protocol = eth_type_trans(skb, dev); - - /* it's OK to use per_cpu_ptr() because BHs are off */ --- -1.7.11.7 - - -From f6d1707cdb200b651c019f693d636154cce43248 Mon Sep 17 00:00:00 2001 -From: Pravin B Shelar -Date: Wed, 23 Jan 2013 11:45:42 +0000 -Subject: [PATCH 16/44] IP_GRE: Fix kernel panic in IP_GRE with GRE csum. - -[ Upstream commit 5465740ace36f179de5bb0ccb5d46ddeb945e309 ] - -Due to IP_GRE GSO support, GRE can recieve non linear skb which -results in panic in case of GRE_CSUM. Following patch fixes it by -using correct csum API. - -Bug introduced in commit 6b78f16e4bdde3936b (gre: add GSO support) - -Signed-off-by: Pravin B Shelar -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller ---- - net/ipv4/ip_gre.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c -index 7240f8e..07538a7 100644 ---- a/net/ipv4/ip_gre.c -+++ b/net/ipv4/ip_gre.c -@@ -972,8 +972,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev - ptr--; - } - if (tunnel->parms.o_flags&GRE_CSUM) { -+ int offset = skb_transport_offset(skb); -+ - *ptr = 0; -- *(__sum16 *)ptr = ip_compute_csum((void *)(iph+1), skb->len - sizeof(struct iphdr)); -+ *(__sum16 *)ptr = csum_fold(skb_checksum(skb, offset, -+ skb->len - offset, -+ 0)); - } - } - --- -1.7.11.7 - - -From 443811a0868d9d9815f4bbe1aabea6be7f25f906 Mon Sep 17 00:00:00 2001 -From: Cong Wang -Date: Sun, 27 Jan 2013 21:14:08 +0000 -Subject: [PATCH 17/44] pktgen: correctly handle failures when adding a device - -[ Upstream commit 604dfd6efc9b79bce432f2394791708d8e8f6efc ] - -The return value of pktgen_add_device() is not checked, so -even if we fail to add some device, for example, non-exist one, -we still see "OK:...". This patch fixes it. - -After this patch, I got: - - # echo "add_device non-exist" > /proc/net/pktgen/kpktgend_0 - -bash: echo: write error: No such device - # cat /proc/net/pktgen/kpktgend_0 - Running: - Stopped: - Result: ERROR: can not add device non-exist - # echo "add_device eth0" > /proc/net/pktgen/kpktgend_0 - # cat /proc/net/pktgen/kpktgend_0 - Running: - Stopped: eth0 - Result: OK: add_device=eth0 - -(Candidate for -stable) - -Cc: David S. Miller -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller ---- - net/core/pktgen.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/net/core/pktgen.c b/net/core/pktgen.c -index d1dc14c..21350db 100644 ---- a/net/core/pktgen.c -+++ b/net/core/pktgen.c -@@ -1795,10 +1795,13 @@ static ssize_t pktgen_thread_write(struct file *file, - return -EFAULT; - i += len; - mutex_lock(&pktgen_thread_lock); -- pktgen_add_device(t, f); -+ ret = pktgen_add_device(t, f); - mutex_unlock(&pktgen_thread_lock); -- ret = count; -- sprintf(pg_result, "OK: add_device=%s", f); -+ if (!ret) { -+ ret = count; -+ sprintf(pg_result, "OK: add_device=%s", f); -+ } else -+ sprintf(pg_result, "ERROR: can not add device %s", f); - goto out; - } - --- -1.7.11.7 - - -From 9159b16b6d82f3051602f0ee51701458a6a58432 Mon Sep 17 00:00:00 2001 -From: Marcelo Ricardo Leitner -Date: Tue, 29 Jan 2013 22:26:08 +0000 -Subject: [PATCH 18/44] ipv6: do not create neighbor entries for local - delivery - -[ Upstream commit bd30e947207e2ea0ff2c08f5b4a03025ddce48d3 ] - -They will be created at output, if ever needed. This avoids creating -empty neighbor entries when TPROXYing/Forwarding packets for addresses -that are not even directly reachable. - -Note that IPv4 already handles it this way. No neighbor entries are -created for local input. - -Tested by myself and customer. - -Signed-off-by: Jiri Pirko -Signed-off-by: Marcelo Ricardo Leitner -Signed-off-by: David S. Miller ---- - net/ipv6/route.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index b1e6cf0..b140ef2 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -872,7 +872,7 @@ restart: - dst_hold(&rt->dst); - read_unlock_bh(&table->tb6_lock); - -- if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP)) -+ if (!rt->n && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL))) - nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); - else if (!(rt->dst.flags & DST_HOST)) - nrt = rt6_alloc_clone(rt, &fl6->daddr); --- -1.7.11.7 - - -From aaf884494fda8734dcd8f42602e646e2238d01f6 Mon Sep 17 00:00:00 2001 -From: "David S. Miller" -Date: Tue, 29 Jan 2013 22:58:04 -0500 -Subject: [PATCH 19/44] via-rhine: Fix bugs in NAPI support. - -[ Upstream commit 559bcac35facfed49ab4f408e162971612dcfdf3 ] - -1) rhine_tx() should use dev_kfree_skb() not dev_kfree_skb_irq() - -2) rhine_slow_event_task's NAPI triggering logic is racey, it - should just hit the interrupt mask register. This is the - same as commit 7dbb491878a2c51d372a8890fa45a8ff80358af1 - ("r8169: avoid NAPI scheduling delay.") made to fix the same - problem in the r8169 driver. From Francois Romieu. - -Reported-by: Jamie Gloudon -Tested-by: Jamie Gloudon -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/via/via-rhine.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c -index 0459c09..046526e0 100644 ---- a/drivers/net/ethernet/via/via-rhine.c -+++ b/drivers/net/ethernet/via/via-rhine.c -@@ -1802,7 +1802,7 @@ static void rhine_tx(struct net_device *dev) - rp->tx_skbuff[entry]->len, - PCI_DMA_TODEVICE); - } -- dev_kfree_skb_irq(rp->tx_skbuff[entry]); -+ dev_kfree_skb(rp->tx_skbuff[entry]); - rp->tx_skbuff[entry] = NULL; - entry = (++rp->dirty_tx) % TX_RING_SIZE; - } -@@ -2011,11 +2011,7 @@ static void rhine_slow_event_task(struct work_struct *work) - if (intr_status & IntrPCIErr) - netif_warn(rp, hw, dev, "PCI error\n"); - -- napi_disable(&rp->napi); -- rhine_irq_disable(rp); -- /* Slow and safe. Consider __napi_schedule as a replacement ? */ -- napi_enable(&rp->napi); -- napi_schedule(&rp->napi); -+ iowrite16(RHINE_EVENT & 0xffff, rp->base + IntrEnable); - - out_unlock: - mutex_unlock(&rp->task_lock); --- -1.7.11.7 - - -From 4c26aa283f7673e08076645d776d1155ea24d01d Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 1 Feb 2013 07:21:41 +0000 -Subject: [PATCH 20/44] packet: fix leakage of tx_ring memory - -[ Upstream commit 9665d5d62487e8e7b1f546c00e11107155384b9a ] - -When releasing a packet socket, the routine packet_set_ring() is reused -to free rings instead of allocating them. But when calling it for the -first time, it fills req->tp_block_nr with the value of rb->pg_vec_len -which in the second invocation makes it bail out since req->tp_block_nr -is greater zero but req->tp_block_size is zero. - -This patch solves the problem by passing a zeroed auto-variable to -packet_set_ring() upon each invocation from packet_release(). - -As far as I can tell, this issue exists even since 69e3c75 (net: TX_RING -and packet mmap), i.e. the original inclusion of TX ring support into -af_packet, but applies only to sockets with both RX and TX ring -allocated, which is probably why this was unnoticed all the time. - -Signed-off-by: Phil Sutter -Cc: Johann Baudy -Cc: Daniel Borkmann -Acked-by: Daniel Borkmann -Signed-off-by: David S. Miller ---- - net/packet/af_packet.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 94060ed..5db6316 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -2335,13 +2335,15 @@ static int packet_release(struct socket *sock) - - packet_flush_mclist(sk); - -- memset(&req_u, 0, sizeof(req_u)); -- -- if (po->rx_ring.pg_vec) -+ if (po->rx_ring.pg_vec) { -+ memset(&req_u, 0, sizeof(req_u)); - packet_set_ring(sk, &req_u, 1, 0); -+ } - -- if (po->tx_ring.pg_vec) -+ if (po->tx_ring.pg_vec) { -+ memset(&req_u, 0, sizeof(req_u)); - packet_set_ring(sk, &req_u, 1, 1); -+ } - - fanout_release(sk); - --- -1.7.11.7 - - -From 7cc84ac7f54b5d6e70c62bf62cedd52047efb24b Mon Sep 17 00:00:00 2001 -From: Tommi Rantala -Date: Wed, 6 Feb 2013 03:24:02 +0000 -Subject: [PATCH 21/44] ipv6/ip6_gre: fix error case handling in - ip6gre_tunnel_xmit() - -[ Upstream commit 41ab3e31bd50b42c85ac0aa0469642866aee2a9a ] - -ip6gre_tunnel_xmit() is leaking the skb when we hit this error branch, -and the -1 return value from this function is bogus. Use the error -handling we already have in place in ip6gre_tunnel_xmit() for this error -case to fix this. - -Signed-off-by: Tommi Rantala -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller ---- - net/ipv6/ip6_gre.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c -index d5cb3c4..a23350c 100644 ---- a/net/ipv6/ip6_gre.c -+++ b/net/ipv6/ip6_gre.c -@@ -976,7 +976,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, - int ret; - - if (!ip6_tnl_xmit_ctl(t)) -- return -1; -+ goto tx_err; - - switch (skb->protocol) { - case htons(ETH_P_IP): --- -1.7.11.7 - - -From 09d6e93572bb278ea5a0cfaa63e18c01b25a9c7e Mon Sep 17 00:00:00 2001 -From: Heiko Carstens -Date: Fri, 8 Feb 2013 00:19:11 +0000 -Subject: [PATCH 22/44] atm/iphase: rename fregt_t -> ffreg_t - -[ Upstream commit ab54ee80aa7585f9666ff4dd665441d7ce41f1e8 ] - -We have conflicting type qualifiers for "freg_t" in s390's ptrace.h and the -iphase atm device driver, which causes the compile error below. -Unfortunately the s390 typedef can't be renamed, since it's a user visible api, -nor can I change the include order in s390 code to avoid the conflict. - -So simply rename the iphase typedef to a new name. Fixes this compile error: - -In file included from drivers/atm/iphase.c:66:0: -drivers/atm/iphase.h:639:25: error: conflicting type qualifiers for 'freg_t' -In file included from next/arch/s390/include/asm/ptrace.h:9:0, - from next/arch/s390/include/asm/lowcore.h:12, - from next/arch/s390/include/asm/thread_info.h:30, - from include/linux/thread_info.h:54, - from include/linux/preempt.h:9, - from include/linux/spinlock.h:50, - from include/linux/seqlock.h:29, - from include/linux/time.h:5, - from include/linux/stat.h:18, - from include/linux/module.h:10, - from drivers/atm/iphase.c:43: -next/arch/s390/include/uapi/asm/ptrace.h:197:3: note: previous declaration of 'freg_t' was here - -Signed-off-by: Heiko Carstens -Acked-by: chas williams - CONTRACTOR -Signed-off-by: David S. Miller ---- - drivers/atm/iphase.h | 146 +++++++++++++++++++++++++-------------------------- - 1 file changed, 73 insertions(+), 73 deletions(-) - -diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h -index 6a0955e..53ecac5 100644 ---- a/drivers/atm/iphase.h -+++ b/drivers/atm/iphase.h -@@ -636,82 +636,82 @@ struct rx_buf_desc { - #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE - #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE - --typedef volatile u_int freg_t; -+typedef volatile u_int ffreg_t; - typedef u_int rreg_t; - - typedef struct _ffredn_t { -- freg_t idlehead_high; /* Idle cell header (high) */ -- freg_t idlehead_low; /* Idle cell header (low) */ -- freg_t maxrate; /* Maximum rate */ -- freg_t stparms; /* Traffic Management Parameters */ -- freg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ -- freg_t rm_type; /* */ -- u_int filler5[0x17 - 0x06]; -- freg_t cmd_reg; /* Command register */ -- u_int filler18[0x20 - 0x18]; -- freg_t cbr_base; /* CBR Pointer Base */ -- freg_t vbr_base; /* VBR Pointer Base */ -- freg_t abr_base; /* ABR Pointer Base */ -- freg_t ubr_base; /* UBR Pointer Base */ -- u_int filler24; -- freg_t vbrwq_base; /* VBR Wait Queue Base */ -- freg_t abrwq_base; /* ABR Wait Queue Base */ -- freg_t ubrwq_base; /* UBR Wait Queue Base */ -- freg_t vct_base; /* Main VC Table Base */ -- freg_t vcte_base; /* Extended Main VC Table Base */ -- u_int filler2a[0x2C - 0x2A]; -- freg_t cbr_tab_beg; /* CBR Table Begin */ -- freg_t cbr_tab_end; /* CBR Table End */ -- freg_t cbr_pointer; /* CBR Pointer */ -- u_int filler2f[0x30 - 0x2F]; -- freg_t prq_st_adr; /* Packet Ready Queue Start Address */ -- freg_t prq_ed_adr; /* Packet Ready Queue End Address */ -- freg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ -- freg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ -- freg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ -- freg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ -- freg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ -- freg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ -- u_int filler38[0x40 - 0x38]; -- freg_t queue_base; /* Base address for PRQ and TCQ */ -- freg_t desc_base; /* Base address of descriptor table */ -- u_int filler42[0x45 - 0x42]; -- freg_t mode_reg_0; /* Mode register 0 */ -- freg_t mode_reg_1; /* Mode register 1 */ -- freg_t intr_status_reg;/* Interrupt Status register */ -- freg_t mask_reg; /* Mask Register */ -- freg_t cell_ctr_high1; /* Total cell transfer count (high) */ -- freg_t cell_ctr_lo1; /* Total cell transfer count (low) */ -- freg_t state_reg; /* Status register */ -- u_int filler4c[0x58 - 0x4c]; -- freg_t curr_desc_num; /* Contains the current descriptor num */ -- freg_t next_desc; /* Next descriptor */ -- freg_t next_vc; /* Next VC */ -- u_int filler5b[0x5d - 0x5b]; -- freg_t present_slot_cnt;/* Present slot count */ -- u_int filler5e[0x6a - 0x5e]; -- freg_t new_desc_num; /* New descriptor number */ -- freg_t new_vc; /* New VC */ -- freg_t sched_tbl_ptr; /* Schedule table pointer */ -- freg_t vbrwq_wptr; /* VBR wait queue write pointer */ -- freg_t vbrwq_rptr; /* VBR wait queue read pointer */ -- freg_t abrwq_wptr; /* ABR wait queue write pointer */ -- freg_t abrwq_rptr; /* ABR wait queue read pointer */ -- freg_t ubrwq_wptr; /* UBR wait queue write pointer */ -- freg_t ubrwq_rptr; /* UBR wait queue read pointer */ -- freg_t cbr_vc; /* CBR VC */ -- freg_t vbr_sb_vc; /* VBR SB VC */ -- freg_t abr_sb_vc; /* ABR SB VC */ -- freg_t ubr_sb_vc; /* UBR SB VC */ -- freg_t vbr_next_link; /* VBR next link */ -- freg_t abr_next_link; /* ABR next link */ -- freg_t ubr_next_link; /* UBR next link */ -- u_int filler7a[0x7c-0x7a]; -- freg_t out_rate_head; /* Out of rate head */ -- u_int filler7d[0xca-0x7d]; /* pad out to full address space */ -- freg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ -- freg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ -- u_int fillercc[0x100-0xcc]; /* pad out to full address space */ -+ ffreg_t idlehead_high; /* Idle cell header (high) */ -+ ffreg_t idlehead_low; /* Idle cell header (low) */ -+ ffreg_t maxrate; /* Maximum rate */ -+ ffreg_t stparms; /* Traffic Management Parameters */ -+ ffreg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ -+ ffreg_t rm_type; /* */ -+ u_int filler5[0x17 - 0x06]; -+ ffreg_t cmd_reg; /* Command register */ -+ u_int filler18[0x20 - 0x18]; -+ ffreg_t cbr_base; /* CBR Pointer Base */ -+ ffreg_t vbr_base; /* VBR Pointer Base */ -+ ffreg_t abr_base; /* ABR Pointer Base */ -+ ffreg_t ubr_base; /* UBR Pointer Base */ -+ u_int filler24; -+ ffreg_t vbrwq_base; /* VBR Wait Queue Base */ -+ ffreg_t abrwq_base; /* ABR Wait Queue Base */ -+ ffreg_t ubrwq_base; /* UBR Wait Queue Base */ -+ ffreg_t vct_base; /* Main VC Table Base */ -+ ffreg_t vcte_base; /* Extended Main VC Table Base */ -+ u_int filler2a[0x2C - 0x2A]; -+ ffreg_t cbr_tab_beg; /* CBR Table Begin */ -+ ffreg_t cbr_tab_end; /* CBR Table End */ -+ ffreg_t cbr_pointer; /* CBR Pointer */ -+ u_int filler2f[0x30 - 0x2F]; -+ ffreg_t prq_st_adr; /* Packet Ready Queue Start Address */ -+ ffreg_t prq_ed_adr; /* Packet Ready Queue End Address */ -+ ffreg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ -+ ffreg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ -+ ffreg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ -+ ffreg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ -+ ffreg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ -+ ffreg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ -+ u_int filler38[0x40 - 0x38]; -+ ffreg_t queue_base; /* Base address for PRQ and TCQ */ -+ ffreg_t desc_base; /* Base address of descriptor table */ -+ u_int filler42[0x45 - 0x42]; -+ ffreg_t mode_reg_0; /* Mode register 0 */ -+ ffreg_t mode_reg_1; /* Mode register 1 */ -+ ffreg_t intr_status_reg;/* Interrupt Status register */ -+ ffreg_t mask_reg; /* Mask Register */ -+ ffreg_t cell_ctr_high1; /* Total cell transfer count (high) */ -+ ffreg_t cell_ctr_lo1; /* Total cell transfer count (low) */ -+ ffreg_t state_reg; /* Status register */ -+ u_int filler4c[0x58 - 0x4c]; -+ ffreg_t curr_desc_num; /* Contains the current descriptor num */ -+ ffreg_t next_desc; /* Next descriptor */ -+ ffreg_t next_vc; /* Next VC */ -+ u_int filler5b[0x5d - 0x5b]; -+ ffreg_t present_slot_cnt;/* Present slot count */ -+ u_int filler5e[0x6a - 0x5e]; -+ ffreg_t new_desc_num; /* New descriptor number */ -+ ffreg_t new_vc; /* New VC */ -+ ffreg_t sched_tbl_ptr; /* Schedule table pointer */ -+ ffreg_t vbrwq_wptr; /* VBR wait queue write pointer */ -+ ffreg_t vbrwq_rptr; /* VBR wait queue read pointer */ -+ ffreg_t abrwq_wptr; /* ABR wait queue write pointer */ -+ ffreg_t abrwq_rptr; /* ABR wait queue read pointer */ -+ ffreg_t ubrwq_wptr; /* UBR wait queue write pointer */ -+ ffreg_t ubrwq_rptr; /* UBR wait queue read pointer */ -+ ffreg_t cbr_vc; /* CBR VC */ -+ ffreg_t vbr_sb_vc; /* VBR SB VC */ -+ ffreg_t abr_sb_vc; /* ABR SB VC */ -+ ffreg_t ubr_sb_vc; /* UBR SB VC */ -+ ffreg_t vbr_next_link; /* VBR next link */ -+ ffreg_t abr_next_link; /* ABR next link */ -+ ffreg_t ubr_next_link; /* UBR next link */ -+ u_int filler7a[0x7c-0x7a]; -+ ffreg_t out_rate_head; /* Out of rate head */ -+ u_int filler7d[0xca-0x7d]; /* pad out to full address space */ -+ ffreg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ -+ ffreg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ -+ u_int fillercc[0x100-0xcc]; /* pad out to full address space */ - } ffredn_t; - - typedef struct _rfredn_t { --- -1.7.11.7 - - -From 5ef9a447aa4e6a1da43a04b98befa5643c806c1b Mon Sep 17 00:00:00 2001 -From: Ian Campbell -Date: Wed, 6 Feb 2013 23:41:35 +0000 -Subject: [PATCH 23/44] xen/netback: shutdown the ring if it contains garbage. - -[ Upstream commit 48856286b64e4b66ec62b94e504d0b29c1ade664 ] - -A buggy or malicious frontend should not be able to confuse netback. -If we spot anything which is not as it should be then shutdown the -device and don't try to continue with the ring in a potentially -hostile state. Well behaved and non-hostile frontends will not be -penalised. - -As well as making the existing checks for such errors fatal also add a -new check that ensures that there isn't an insane number of requests -on the ring (i.e. more than would fit in the ring). If the ring -contains garbage then previously is was possible to loop over this -insane number, getting an error each time and therefore not generating -any more pending requests and therefore not exiting the loop in -xen_netbk_tx_build_gops for an externded period. - -Also turn various netdev_dbg calls which no precipitate a fatal error -into netdev_err, they are rate limited because the device is shutdown -afterwards. - -This fixes at least one known DoS/softlockup of the backend domain. - -Signed-off-by: Ian Campbell -Reviewed-by: Konrad Rzeszutek Wilk -Acked-by: Jan Beulich -Signed-off-by: David S. Miller ---- - drivers/net/xen-netback/common.h | 3 ++ - drivers/net/xen-netback/interface.c | 23 ++++++++------ - drivers/net/xen-netback/netback.c | 62 +++++++++++++++++++++++++++---------- - 3 files changed, 62 insertions(+), 26 deletions(-) - -diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h -index 94b79c3..9d7f172 100644 ---- a/drivers/net/xen-netback/common.h -+++ b/drivers/net/xen-netback/common.h -@@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb); - /* Notify xenvif that ring now has space to send an skb to the frontend */ - void xenvif_notify_tx_completion(struct xenvif *vif); - -+/* Prevent the device from generating any further traffic. */ -+void xenvif_carrier_off(struct xenvif *vif); -+ - /* Returns number of ring slots required to send an skb to the frontend */ - unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); - -diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c -index b7d41f8..b8c5193 100644 ---- a/drivers/net/xen-netback/interface.c -+++ b/drivers/net/xen-netback/interface.c -@@ -343,17 +343,22 @@ err: - return err; - } - --void xenvif_disconnect(struct xenvif *vif) -+void xenvif_carrier_off(struct xenvif *vif) - { - struct net_device *dev = vif->dev; -- if (netif_carrier_ok(dev)) { -- rtnl_lock(); -- netif_carrier_off(dev); /* discard queued packets */ -- if (netif_running(dev)) -- xenvif_down(vif); -- rtnl_unlock(); -- xenvif_put(vif); -- } -+ -+ rtnl_lock(); -+ netif_carrier_off(dev); /* discard queued packets */ -+ if (netif_running(dev)) -+ xenvif_down(vif); -+ rtnl_unlock(); -+ xenvif_put(vif); -+} -+ -+void xenvif_disconnect(struct xenvif *vif) -+{ -+ if (netif_carrier_ok(vif->dev)) -+ xenvif_carrier_off(vif); - - atomic_dec(&vif->refcnt); - wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index f2d6b78..c2e3336 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -888,6 +888,13 @@ static void netbk_tx_err(struct xenvif *vif, - xenvif_put(vif); - } - -+static void netbk_fatal_tx_err(struct xenvif *vif) -+{ -+ netdev_err(vif->dev, "fatal error; disabling device\n"); -+ xenvif_carrier_off(vif); -+ xenvif_put(vif); -+} -+ - static int netbk_count_requests(struct xenvif *vif, - struct xen_netif_tx_request *first, - struct xen_netif_tx_request *txp, -@@ -901,19 +908,22 @@ static int netbk_count_requests(struct xenvif *vif, - - do { - if (frags >= work_to_do) { -- netdev_dbg(vif->dev, "Need more frags\n"); -+ netdev_err(vif->dev, "Need more frags\n"); -+ netbk_fatal_tx_err(vif); - return -frags; - } - - if (unlikely(frags >= MAX_SKB_FRAGS)) { -- netdev_dbg(vif->dev, "Too many frags\n"); -+ netdev_err(vif->dev, "Too many frags\n"); -+ netbk_fatal_tx_err(vif); - return -frags; - } - - memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), - sizeof(*txp)); - if (txp->size > first->size) { -- netdev_dbg(vif->dev, "Frags galore\n"); -+ netdev_err(vif->dev, "Frag is bigger than frame.\n"); -+ netbk_fatal_tx_err(vif); - return -frags; - } - -@@ -921,8 +931,9 @@ static int netbk_count_requests(struct xenvif *vif, - frags++; - - if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { -- netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", -+ netdev_err(vif->dev, "txp->offset: %x, size: %u\n", - txp->offset, txp->size); -+ netbk_fatal_tx_err(vif); - return -frags; - } - } while ((txp++)->flags & XEN_NETTXF_more_data); -@@ -1095,7 +1106,8 @@ static int xen_netbk_get_extras(struct xenvif *vif, - - do { - if (unlikely(work_to_do-- <= 0)) { -- netdev_dbg(vif->dev, "Missing extra info\n"); -+ netdev_err(vif->dev, "Missing extra info\n"); -+ netbk_fatal_tx_err(vif); - return -EBADR; - } - -@@ -1104,8 +1116,9 @@ static int xen_netbk_get_extras(struct xenvif *vif, - if (unlikely(!extra.type || - extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { - vif->tx.req_cons = ++cons; -- netdev_dbg(vif->dev, -+ netdev_err(vif->dev, - "Invalid extra type: %d\n", extra.type); -+ netbk_fatal_tx_err(vif); - return -EINVAL; - } - -@@ -1121,13 +1134,15 @@ static int netbk_set_skb_gso(struct xenvif *vif, - struct xen_netif_extra_info *gso) - { - if (!gso->u.gso.size) { -- netdev_dbg(vif->dev, "GSO size must not be zero.\n"); -+ netdev_err(vif->dev, "GSO size must not be zero.\n"); -+ netbk_fatal_tx_err(vif); - return -EINVAL; - } - - /* Currently only TCPv4 S.O. is supported. */ - if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { -- netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); -+ netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); -+ netbk_fatal_tx_err(vif); - return -EINVAL; - } - -@@ -1264,9 +1279,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) - - /* Get a netif from the list with work to do. */ - vif = poll_net_schedule_list(netbk); -+ /* This can sometimes happen because the test of -+ * list_empty(net_schedule_list) at the top of the -+ * loop is unlocked. Just go back and have another -+ * look. -+ */ - if (!vif) - continue; - -+ if (vif->tx.sring->req_prod - vif->tx.req_cons > -+ XEN_NETIF_TX_RING_SIZE) { -+ netdev_err(vif->dev, -+ "Impossible number of requests. " -+ "req_prod %d, req_cons %d, size %ld\n", -+ vif->tx.sring->req_prod, vif->tx.req_cons, -+ XEN_NETIF_TX_RING_SIZE); -+ netbk_fatal_tx_err(vif); -+ continue; -+ } -+ - RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); - if (!work_to_do) { - xenvif_put(vif); -@@ -1294,17 +1325,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) - work_to_do = xen_netbk_get_extras(vif, extras, - work_to_do); - idx = vif->tx.req_cons; -- if (unlikely(work_to_do < 0)) { -- netbk_tx_err(vif, &txreq, idx); -+ if (unlikely(work_to_do < 0)) - continue; -- } - } - - ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); -- if (unlikely(ret < 0)) { -- netbk_tx_err(vif, &txreq, idx - ret); -+ if (unlikely(ret < 0)) - continue; -- } -+ - idx += ret; - - if (unlikely(txreq.size < ETH_HLEN)) { -@@ -1316,11 +1344,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) - - /* No crossing a page as the payload mustn't fragment. */ - if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { -- netdev_dbg(vif->dev, -+ netdev_err(vif->dev, - "txreq.offset: %x, size: %u, end: %lu\n", - txreq.offset, txreq.size, - (txreq.offset&~PAGE_MASK) + txreq.size); -- netbk_tx_err(vif, &txreq, idx); -+ netbk_fatal_tx_err(vif); - continue; - } - -@@ -1348,8 +1376,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) - gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; - - if (netbk_set_skb_gso(vif, skb, gso)) { -+ /* Failure in netbk_set_skb_gso is fatal. */ - kfree_skb(skb); -- netbk_tx_err(vif, &txreq, idx); - continue; - } - } --- -1.7.11.7 - - -From 10948f5aa9992de84e022e218b494586fe92d547 Mon Sep 17 00:00:00 2001 -From: Matthew Daley -Date: Wed, 6 Feb 2013 23:41:36 +0000 -Subject: [PATCH 24/44] xen/netback: don't leak pages on failure in - xen_netbk_tx_check_gop. - -[ Upstream commit 7d5145d8eb2b9791533ffe4dc003b129b9696c48 ] - -Signed-off-by: Matthew Daley -Reviewed-by: Konrad Rzeszutek Wilk -Acked-by: Ian Campbell -Acked-by: Jan Beulich -Signed-off-by: David S. Miller ---- - drivers/net/xen-netback/netback.c | 38 +++++++++++++------------------------- - 1 file changed, 13 insertions(+), 25 deletions(-) - -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index c2e3336..bf692df 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -147,7 +147,8 @@ void xen_netbk_remove_xenvif(struct xenvif *vif) - atomic_dec(&netbk->netfront_count); - } - --static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx); -+static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, -+ u8 status); - static void make_tx_response(struct xenvif *vif, - struct xen_netif_tx_request *txp, - s8 st); -@@ -1007,30 +1008,20 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, - { - struct gnttab_copy *gop = *gopp; - u16 pending_idx = *((u16 *)skb->data); -- struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; -- struct xenvif *vif = pending_tx_info[pending_idx].vif; -- struct xen_netif_tx_request *txp; - struct skb_shared_info *shinfo = skb_shinfo(skb); - int nr_frags = shinfo->nr_frags; - int i, err, start; - - /* Check status of header. */ - err = gop->status; -- if (unlikely(err)) { -- pending_ring_idx_t index; -- index = pending_index(netbk->pending_prod++); -- txp = &pending_tx_info[pending_idx].req; -- make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -- netbk->pending_ring[index] = pending_idx; -- xenvif_put(vif); -- } -+ if (unlikely(err)) -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); - - /* Skip first skb fragment if it is on same page as header fragment. */ - start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx); - - for (i = start; i < nr_frags; i++) { - int j, newerr; -- pending_ring_idx_t index; - - pending_idx = frag_get_pending_idx(&shinfo->frags[i]); - -@@ -1039,16 +1030,12 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, - if (likely(!newerr)) { - /* Had a previous error? Invalidate this fragment. */ - if (unlikely(err)) -- xen_netbk_idx_release(netbk, pending_idx); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); - continue; - } - - /* Error on this fragment: respond to client with an error. */ -- txp = &netbk->pending_tx_info[pending_idx].req; -- make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -- index = pending_index(netbk->pending_prod++); -- netbk->pending_ring[index] = pending_idx; -- xenvif_put(vif); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); - - /* Not the first error? Preceding frags already invalidated. */ - if (err) -@@ -1056,10 +1043,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, - - /* First error: invalidate header and preceding fragments. */ - pending_idx = *((u16 *)skb->data); -- xen_netbk_idx_release(netbk, pending_idx); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); - for (j = start; j < i; j++) { - pending_idx = frag_get_pending_idx(&shinfo->frags[j]); -- xen_netbk_idx_release(netbk, pending_idx); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); - } - - /* Remember the error: invalidate all subsequent fragments. */ -@@ -1093,7 +1080,7 @@ static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb) - - /* Take an extra reference to offset xen_netbk_idx_release */ - get_page(netbk->mmap_pages[pending_idx]); -- xen_netbk_idx_release(netbk, pending_idx); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); - } - } - -@@ -1476,7 +1463,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk) - txp->size -= data_len; - } else { - /* Schedule a response immediately. */ -- xen_netbk_idx_release(netbk, pending_idx); -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); - } - - if (txp->flags & XEN_NETTXF_csum_blank) -@@ -1528,7 +1515,8 @@ static void xen_netbk_tx_action(struct xen_netbk *netbk) - xen_netbk_tx_submit(netbk); - } - --static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) -+static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, -+ u8 status) - { - struct xenvif *vif; - struct pending_tx_info *pending_tx_info; -@@ -1542,7 +1530,7 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) - - vif = pending_tx_info->vif; - -- make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY); -+ make_tx_response(vif, &pending_tx_info->req, status); - - index = pending_index(netbk->pending_prod++); - netbk->pending_ring[index] = pending_idx; --- -1.7.11.7 - - -From 2e0b7c1781a94640566dccf9d7441d500fa69e40 Mon Sep 17 00:00:00 2001 -From: Ian Campbell -Date: Wed, 6 Feb 2013 23:41:37 +0000 -Subject: [PATCH 25/44] xen/netback: free already allocated memory on failure - in xen_netbk_get_requests - -[ Upstream commit 4cc7c1cb7b11b6f3515bd9075527576a1eecc4aa ] - -Signed-off-by: Ian Campbell -Signed-off-by: David S. Miller ---- - drivers/net/xen-netback/netback.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index bf692df..dcb2d4d 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -978,7 +978,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, - pending_idx = netbk->pending_ring[index]; - page = xen_netbk_alloc_page(netbk, skb, pending_idx); - if (!page) -- return NULL; -+ goto err; - - gop->source.u.ref = txp->gref; - gop->source.domid = vif->domid; -@@ -1000,6 +1000,17 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, - } - - return gop; -+err: -+ /* Unwind, freeing all pages and sending error responses. */ -+ while (i-- > start) { -+ xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]), -+ XEN_NETIF_RSP_ERROR); -+ } -+ /* The head too, if necessary. */ -+ if (start) -+ xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); -+ -+ return NULL; - } - - static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, --- -1.7.11.7 - - -From d5b2f3542a1f9c7b5092816b87db08e9f08f1551 Mon Sep 17 00:00:00 2001 -From: Ian Campbell -Date: Wed, 6 Feb 2013 23:41:38 +0000 -Subject: [PATCH 26/44] netback: correct netbk_tx_err to handle wrap around. - -[ Upstream commit b9149729ebdcfce63f853aa54a404c6a8f6ebbf3 ] - -Signed-off-by: Ian Campbell -Acked-by: Jan Beulich -Signed-off-by: David S. Miller ---- - drivers/net/xen-netback/netback.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index dcb2d4d..2b9520c 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -880,7 +880,7 @@ static void netbk_tx_err(struct xenvif *vif, - - do { - make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -- if (cons >= end) -+ if (cons == end) - break; - txp = RING_GET_REQUEST(&vif->tx, cons++); - } while (1); --- -1.7.11.7 - - -From 28ecceda6c2f58f14379e35a0caec5f9b57cc798 Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Wed, 16 Jan 2013 20:55:01 +0000 -Subject: [PATCH 27/44] ipv4: Remove output route check in ipv4_mtu -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 38d523e2948162776903349c89d65f7b9370dadb ] - -The output route check was introduced with git commit 261663b0 -(ipv4: Don't use the cached pmtu informations for input routes) -during times when we cached the pmtu informations on the -inetpeer. Now the pmtu informations are back in the routes, -so this check is obsolete. It also had some unwanted side effects, -as reported by Timo Teras and Lukas Tribus. - -Signed-off-by: Steffen Klassert -Acked-by: Timo Teräs -Signed-off-by: David S. Miller ---- - net/ipv4/route.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index df25142..11d28e3 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -1120,7 +1120,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) - if (!mtu || time_after_eq(jiffies, rt->dst.expires)) - mtu = dst_metric_raw(dst, RTAX_MTU); - -- if (mtu && rt_is_output_route(rt)) -+ if (mtu) - return mtu; - - mtu = dst->dev->mtu; --- -1.7.11.7 - - -From d282905a8f4d2f86ffca23f2bbee1697fdf832aa Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Wed, 16 Jan 2013 20:58:10 +0000 -Subject: [PATCH 28/44] ipv4: Don't update the pmtu on mtu locked routes - -[ Upstream commit fa1e492aa3cbafba9f8fc6d05e5b08a3091daf4a ] - -Routes with locked mtu should not use learned pmtu informations, -so do not update the pmtu on these routes. - -Reported-by: Julian Anastasov -Signed-off-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - net/ipv4/route.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 11d28e3..0660d6f 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -912,6 +912,9 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) - struct dst_entry *dst = &rt->dst; - struct fib_result res; - -+ if (dst_metric_locked(dst, RTAX_MTU)) -+ return; -+ - if (dst->dev->mtu < mtu) - return; - --- -1.7.11.7 - - -From 7e5337b6085429c382297b71d3099ec56b82829d Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Wed, 16 Jan 2013 22:09:49 +0000 -Subject: [PATCH 29/44] ipv6: Add an error handler for icmp6 - -[ Upstream commit 6f809da27c94425e07be4a64d5093e1df95188e9 ] - -pmtu and redirect events are now handled in the protocols error handler, -so add an error handler for icmp6 to do this. It is needed in the case -when we have no socket context. Based on a patch by Duan Jiong. - -Reported-by: Duan Jiong -Signed-off-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - net/ipv6/icmp.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c -index 24d69db..4d844d7 100644 ---- a/net/ipv6/icmp.c -+++ b/net/ipv6/icmp.c -@@ -81,10 +81,22 @@ static inline struct sock *icmpv6_sk(struct net *net) - return net->ipv6.icmp_sk[smp_processor_id()]; - } - -+static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, -+ u8 type, u8 code, int offset, __be32 info) -+{ -+ struct net *net = dev_net(skb->dev); -+ -+ if (type == ICMPV6_PKT_TOOBIG) -+ ip6_update_pmtu(skb, net, info, 0, 0); -+ else if (type == NDISC_REDIRECT) -+ ip6_redirect(skb, net, 0, 0); -+} -+ - static int icmpv6_rcv(struct sk_buff *skb); - - static const struct inet6_protocol icmpv6_protocol = { - .handler = icmpv6_rcv, -+ .err_handler = icmpv6_err, - .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, - }; - --- -1.7.11.7 - - -From 5d7f31144c2e375a5a241bc76648ccd8a6d5e6c9 Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Mon, 21 Jan 2013 01:59:11 +0000 -Subject: [PATCH 30/44] ipv4: Invalidate the socket cached route on pmtu - events if possible - -[ Upstream commit 9cb3a50c5f63ed745702972f66eaee8767659acd ] - -The route lookup in ipv4_sk_update_pmtu() might return a route -different from the route we cached at the socket. This is because -standart routes are per cpu, so each cpu has it's own struct rtable. -This means that we do not invalidate the socket cached route if the -NET_RX_SOFTIRQ is not served by the same cpu that the sending socket -uses. As a result, the cached route reused until we disconnect. - -With this patch we invalidate the socket cached route if possible. -If the socket is owened by the user, we can't update the cached -route directly. A followup patch will implement socket release -callback functions for datagram sockets to handle this case. - -Reported-by: Yurij M. Plotnikov -Signed-off-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - net/ipv4/route.c | 42 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 41 insertions(+), 1 deletion(-) - -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 0660d6f..fc6a6b4 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -965,7 +965,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, - } - EXPORT_SYMBOL_GPL(ipv4_update_pmtu); - --void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) -+static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) - { - const struct iphdr *iph = (const struct iphdr *) skb->data; - struct flowi4 fl4; -@@ -978,6 +978,46 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) - ip_rt_put(rt); - } - } -+ -+void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) -+{ -+ const struct iphdr *iph = (const struct iphdr *) skb->data; -+ struct flowi4 fl4; -+ struct rtable *rt; -+ struct dst_entry *dst; -+ -+ bh_lock_sock(sk); -+ rt = (struct rtable *) __sk_dst_get(sk); -+ -+ if (sock_owned_by_user(sk) || !rt) { -+ __ipv4_sk_update_pmtu(skb, sk, mtu); -+ goto out; -+ } -+ -+ __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); -+ -+ if (!__sk_dst_check(sk, 0)) { -+ rt = ip_route_output_flow(sock_net(sk), &fl4, sk); -+ if (IS_ERR(rt)) -+ goto out; -+ } -+ -+ __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); -+ -+ dst = dst_check(&rt->dst, 0); -+ if (!dst) { -+ rt = ip_route_output_flow(sock_net(sk), &fl4, sk); -+ if (IS_ERR(rt)) -+ goto out; -+ -+ dst = &rt->dst; -+ } -+ -+ __sk_dst_set(sk, dst); -+ -+out: -+ bh_unlock_sock(sk); -+} - EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); - - void ipv4_redirect(struct sk_buff *skb, struct net *net, --- -1.7.11.7 - - -From 250a2bac5bcef490f775aa2680c3934915aeb51a Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Mon, 21 Jan 2013 02:00:03 +0000 -Subject: [PATCH 31/44] ipv4: Add a socket release callback for datagram - sockets - -[ Upstream commit 8141ed9fcedb278f4a3a78680591bef1e55f75fb ] - -This implements a socket release callback function to check -if the socket cached route got invalid during the time -we owned the socket. The function is used from udp, raw -and ping sockets. - -Signed-off-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - include/net/ip.h | 2 ++ - net/ipv4/datagram.c | 25 +++++++++++++++++++++++++ - net/ipv4/ping.c | 1 + - net/ipv4/raw.c | 1 + - net/ipv4/udp.c | 1 + - 5 files changed, 30 insertions(+) - -diff --git a/include/net/ip.h b/include/net/ip.h -index 0707fb9..a68f838 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) - extern int ip4_datagram_connect(struct sock *sk, - struct sockaddr *uaddr, int addr_len); - -+extern void ip4_datagram_release_cb(struct sock *sk); -+ - struct ip_reply_arg { - struct kvec iov[1]; - int flags; -diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c -index 424fafb..b28e863 100644 ---- a/net/ipv4/datagram.c -+++ b/net/ipv4/datagram.c -@@ -85,3 +85,28 @@ out: - return err; - } - EXPORT_SYMBOL(ip4_datagram_connect); -+ -+void ip4_datagram_release_cb(struct sock *sk) -+{ -+ const struct inet_sock *inet = inet_sk(sk); -+ const struct ip_options_rcu *inet_opt; -+ __be32 daddr = inet->inet_daddr; -+ struct flowi4 fl4; -+ struct rtable *rt; -+ -+ if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0)) -+ return; -+ -+ rcu_read_lock(); -+ inet_opt = rcu_dereference(inet->inet_opt); -+ if (inet_opt && inet_opt->opt.srr) -+ daddr = inet_opt->opt.faddr; -+ rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr, -+ inet->inet_saddr, inet->inet_dport, -+ inet->inet_sport, sk->sk_protocol, -+ RT_CONN_FLAGS(sk), sk->sk_bound_dev_if); -+ if (!IS_ERR(rt)) -+ __sk_dst_set(sk, &rt->dst); -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL_GPL(ip4_datagram_release_cb); -diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c -index 8f3d054..6f9c072 100644 ---- a/net/ipv4/ping.c -+++ b/net/ipv4/ping.c -@@ -738,6 +738,7 @@ struct proto ping_prot = { - .recvmsg = ping_recvmsg, - .bind = ping_bind, - .backlog_rcv = ping_queue_rcv_skb, -+ .release_cb = ip4_datagram_release_cb, - .hash = ping_v4_hash, - .unhash = ping_v4_unhash, - .get_port = ping_v4_get_port, -diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c -index 73d1e4d..6f08991 100644 ---- a/net/ipv4/raw.c -+++ b/net/ipv4/raw.c -@@ -894,6 +894,7 @@ struct proto raw_prot = { - .recvmsg = raw_recvmsg, - .bind = raw_bind, - .backlog_rcv = raw_rcv_skb, -+ .release_cb = ip4_datagram_release_cb, - .hash = raw_hash_sk, - .unhash = raw_unhash_sk, - .obj_size = sizeof(struct raw_sock), -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 79c8dbe..1f4d405 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -1952,6 +1952,7 @@ struct proto udp_prot = { - .recvmsg = udp_recvmsg, - .sendpage = udp_sendpage, - .backlog_rcv = __udp_queue_rcv_skb, -+ .release_cb = ip4_datagram_release_cb, - .hash = udp_lib_hash, - .unhash = udp_lib_unhash, - .rehash = udp_v4_rehash, --- -1.7.11.7 - - -From db28ad52a9a7c7fff4063d733e39169c663b2d2e Mon Sep 17 00:00:00 2001 -From: Steffen Klassert -Date: Tue, 22 Jan 2013 00:01:28 +0000 -Subject: [PATCH 32/44] ipv4: Fix route refcount on pmtu discovery - -[ Upstream commit b44108dbdbaa07c609bb5755e8dd6c2035236251 ] - -git commit 9cb3a50c (ipv4: Invalidate the socket cached route on -pmtu events if possible) introduced a refcount problem. We don't -get a refcount on the route if we get it from__sk_dst_get(), but -we need one if we want to reuse this route because __sk_dst_set() -releases the refcount of the old route. This patch adds proper -refcount handling for that case. We introduce a 'new' flag to -indicate that we are going to use a new route and we release the -old route only if we replace it by a new one. - -Reported-by: Julian Anastasov -Signed-off-by: Steffen Klassert -Signed-off-by: David S. Miller ---- - net/ipv4/route.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index fc6a6b4..0fdfe4c 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -985,6 +985,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) - struct flowi4 fl4; - struct rtable *rt; - struct dst_entry *dst; -+ bool new = false; - - bh_lock_sock(sk); - rt = (struct rtable *) __sk_dst_get(sk); -@@ -1000,20 +1001,26 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) - rt = ip_route_output_flow(sock_net(sk), &fl4, sk); - if (IS_ERR(rt)) - goto out; -+ -+ new = true; - } - - __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); - - dst = dst_check(&rt->dst, 0); - if (!dst) { -+ if (new) -+ dst_release(&rt->dst); -+ - rt = ip_route_output_flow(sock_net(sk), &fl4, sk); - if (IS_ERR(rt)) - goto out; - -- dst = &rt->dst; -+ new = true; - } - -- __sk_dst_set(sk, dst); -+ if (new) -+ __sk_dst_set(sk, &rt->dst); - - out: - bh_unlock_sock(sk); --- -1.7.11.7 - - -From 9fdbfac789ac6ee2eade40d045576f701b5ea3ee Mon Sep 17 00:00:00 2001 -From: Neil Horman -Date: Thu, 17 Jan 2013 11:15:08 +0000 -Subject: [PATCH 33/44] sctp: refactor sctp_outq_teardown to insure proper - re-initalization - -[ Upstream commit 2f94aabd9f6c925d77aecb3ff020f1cc12ed8f86 ] - -Jamie Parsons reported a problem recently, in which the re-initalization of an -association (The duplicate init case), resulted in a loss of receive window -space. He tracked down the root cause to sctp_outq_teardown, which discarded -all the data on an outq during a re-initalization of the corresponding -association, but never reset the outq->outstanding_data field to zero. I wrote, -and he tested this fix, which does a proper full re-initalization of the outq, -fixing this problem, and hopefully future proofing us from simmilar issues down -the road. - -Signed-off-by: Neil Horman -Reported-by: Jamie Parsons -Tested-by: Jamie Parsons -CC: Jamie Parsons -CC: Vlad Yasevich -CC: "David S. Miller" -CC: netdev@vger.kernel.org -Acked-by: Vlad Yasevich -Signed-off-by: David S. Miller ---- - net/sctp/outqueue.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c -index 1b4a7f8..bcaa4c8 100644 ---- a/net/sctp/outqueue.c -+++ b/net/sctp/outqueue.c -@@ -224,7 +224,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) - - /* Free the outqueue structure and any related pending chunks. - */ --void sctp_outq_teardown(struct sctp_outq *q) -+static void __sctp_outq_teardown(struct sctp_outq *q) - { - struct sctp_transport *transport; - struct list_head *lchunk, *temp; -@@ -277,8 +277,6 @@ void sctp_outq_teardown(struct sctp_outq *q) - sctp_chunk_free(chunk); - } - -- q->error = 0; -- - /* Throw away any leftover control chunks. */ - list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { - list_del_init(&chunk->list); -@@ -286,11 +284,17 @@ void sctp_outq_teardown(struct sctp_outq *q) - } - } - -+void sctp_outq_teardown(struct sctp_outq *q) -+{ -+ __sctp_outq_teardown(q); -+ sctp_outq_init(q->asoc, q); -+} -+ - /* Free the outqueue structure and any related pending chunks. */ - void sctp_outq_free(struct sctp_outq *q) - { - /* Throw away leftover chunks. */ -- sctp_outq_teardown(q); -+ __sctp_outq_teardown(q); - - /* If we were kmalloc()'d, free the memory. */ - if (q->malloced) --- -1.7.11.7 - - -From b6eafd305aecd134d3333b2ebff487e86bd39eae Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Fri, 8 Feb 2013 03:04:34 +0000 -Subject: [PATCH 34/44] net: sctp: sctp_setsockopt_auth_key: use kzfree - instead of kfree - -[ Upstream commit 6ba542a291a5e558603ac51cda9bded347ce7627 ] - -In sctp_setsockopt_auth_key, we create a temporary copy of the user -passed shared auth key for the endpoint or association and after -internal setup, we free it right away. Since it's sensitive data, we -should zero out the key before returning the memory back to the -allocator. Thus, use kzfree instead of kfree, just as we do in -sctp_auth_key_put(). - -Signed-off-by: Daniel Borkmann -Signed-off-by: David S. Miller ---- - net/sctp/socket.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index 406d957..9261d9a 100644 ---- a/net/sctp/socket.c -+++ b/net/sctp/socket.c -@@ -3388,7 +3388,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, - - ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); - out: -- kfree(authkey); -+ kzfree(authkey); - return ret; - } - --- -1.7.11.7 - - -From de6cbc343521cd56514d53fc249fbbd03532d04c Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Fri, 8 Feb 2013 03:04:35 +0000 -Subject: [PATCH 35/44] net: sctp: sctp_endpoint_free: zero out secret key - data - -[ Upstream commit b5c37fe6e24eec194bb29d22fdd55d73bcc709bf ] - -On sctp_endpoint_destroy, previously used sensitive keying material -should be zeroed out before the memory is returned, as we already do -with e.g. auth keys when released. - -Signed-off-by: Daniel Borkmann -Acked-by: Vlad Yasevich -Signed-off-by: David S. Miller ---- - net/sctp/endpointola.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c -index 1859e2b..80a7264 100644 ---- a/net/sctp/endpointola.c -+++ b/net/sctp/endpointola.c -@@ -249,6 +249,8 @@ void sctp_endpoint_free(struct sctp_endpoint *ep) - /* Final destructor for endpoint. */ - static void sctp_endpoint_destroy(struct sctp_endpoint *ep) - { -+ int i; -+ - SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); - - /* Free up the HMAC transform. */ -@@ -271,6 +273,9 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) - sctp_inq_free(&ep->base.inqueue); - sctp_bind_addr_free(&ep->base.bind_addr); - -+ for (i = 0; i < SCTP_HOW_MANY_SECRETS; ++i) -+ memset(&ep->secret_key[i], 0, SCTP_SECRET_SIZE); -+ - /* Remove and free the port */ - if (sctp_sk(ep->base.sk)->bind_hash) - sctp_put_port(ep->base.sk); --- -1.7.11.7 - - -From a8963d813f812a9c13baed12ec4c06a1c3443e7c Mon Sep 17 00:00:00 2001 -From: Yuchung Cheng -Date: Thu, 31 Jan 2013 11:16:46 -0800 -Subject: [PATCH 36/44] tcp: detect SYN/data drop when F-RTO is disabled - -[ Upstream commit 66555e92fb7a619188c02cceae4bbc414f15f96d ] - -On receiving the SYN-ACK, Fast Open checks icsk_retransmit for SYN -retransmission to detect SYN/data drops. But if F-RTO is disabled, -icsk_retransmit is reset at step D of tcp_fastretrans_alert() ( -under tcp_ack()) before tcp_rcv_fastopen_synack(). The fix is to use -total_retrans instead which accounts for SYN retransmission regardless -the use of F-RTO. - -Signed-off-by: Yuchung Cheng -Signed-off-by: David S. Miller ---- - net/ipv4/tcp_input.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 181fc82..765db33 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -5639,8 +5639,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, - * the remote receives only the retransmitted (regular) SYNs: either - * the original SYN-data or the corresponding SYN-ACK is lost. - */ -- syn_drop = (cookie->len <= 0 && data && -- inet_csk(sk)->icsk_retransmits); -+ syn_drop = (cookie->len <= 0 && data && tp->total_retrans); - - tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); - --- -1.7.11.7 - - -From 8bee456022dadde41b6fe3c551f7e46af777df10 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Sat, 2 Feb 2013 05:23:16 +0000 -Subject: [PATCH 37/44] tcp: fix an infinite loop in tcp_slow_start() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 973ec449bb4f2b8c514bacbcb4d9506fc31c8ce3 ] - -Since commit 9dc274151a548 (tcp: fix ABC in tcp_slow_start()), -a nul snd_cwnd triggers an infinite loop in tcp_slow_start() - -Avoid this infinite loop and log a one time error for further -analysis. FRTO code is suspected to cause this bug. - -Reported-by: Pasi Kärkkäinen -Signed-off-by: Eric Dumazet -Cc: Neal Cardwell -Cc: Yuchung Cheng -Signed-off-by: David S. Miller ---- - net/ipv4/tcp_cong.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c -index 1432cdb..fc582a7 100644 ---- a/net/ipv4/tcp_cong.c -+++ b/net/ipv4/tcp_cong.c -@@ -309,6 +309,12 @@ void tcp_slow_start(struct tcp_sock *tp) - { - int cnt; /* increase in packets */ - unsigned int delta = 0; -+ u32 snd_cwnd = tp->snd_cwnd; -+ -+ if (unlikely(!snd_cwnd)) { -+ pr_err_once("snd_cwnd is nul, please report this bug.\n"); -+ snd_cwnd = 1U; -+ } - - /* RFC3465: ABC Slow start - * Increase only after a full MSS of bytes is acked -@@ -323,7 +329,7 @@ void tcp_slow_start(struct tcp_sock *tp) - if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh) - cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */ - else -- cnt = tp->snd_cwnd; /* exponential increase */ -+ cnt = snd_cwnd; /* exponential increase */ - - /* RFC3465: ABC - * We MAY increase by 2 if discovered delayed ack -@@ -333,11 +339,11 @@ void tcp_slow_start(struct tcp_sock *tp) - tp->bytes_acked = 0; - - tp->snd_cwnd_cnt += cnt; -- while (tp->snd_cwnd_cnt >= tp->snd_cwnd) { -- tp->snd_cwnd_cnt -= tp->snd_cwnd; -+ while (tp->snd_cwnd_cnt >= snd_cwnd) { -+ tp->snd_cwnd_cnt -= snd_cwnd; - delta++; - } -- tp->snd_cwnd = min(tp->snd_cwnd + delta, tp->snd_cwnd_clamp); -+ tp->snd_cwnd = min(snd_cwnd + delta, tp->snd_cwnd_clamp); - } - EXPORT_SYMBOL_GPL(tcp_slow_start); - --- -1.7.11.7 - - -From 704e9be40e69eed1a96363ce2a6707801f5ff174 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Sun, 3 Feb 2013 09:13:05 +0000 -Subject: [PATCH 38/44] tcp: frto should not set snd_cwnd to 0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 2e5f421211ff76c17130b4597bc06df4eeead24f ] - -Commit 9dc274151a548 (tcp: fix ABC in tcp_slow_start()) -uncovered a bug in FRTO code : -tcp_process_frto() is setting snd_cwnd to 0 if the number -of in flight packets is 0. - -As Neal pointed out, if no packet is in flight we lost our -chance to disambiguate whether a loss timeout was spurious. - -We should assume it was a proper loss. - -Reported-by: Pasi Kärkkäinen -Signed-off-by: Neal Cardwell -Signed-off-by: Eric Dumazet -Cc: Ilpo Järvinen -Cc: Yuchung Cheng -Signed-off-by: David S. Miller ---- - net/ipv4/tcp_input.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 765db33..3a5f691 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -3484,7 +3484,8 @@ static bool tcp_process_frto(struct sock *sk, int flag) - ((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED))) - tp->undo_marker = 0; - -- if (!before(tp->snd_una, tp->frto_highmark)) { -+ if (!before(tp->snd_una, tp->frto_highmark) || -+ !tcp_packets_in_flight(tp)) { - tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); - return true; - } --- -1.7.11.7 - - -From cd3789e7ba292f27f25e9076dd23b97cf30d89b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= -Date: Mon, 4 Feb 2013 02:14:25 +0000 -Subject: [PATCH 39/44] tcp: fix for zero packets_in_flight was too broad -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 6731d2095bd4aef18027c72ef845ab1087c3ba63 ] - -There are transients during normal FRTO procedure during which -the packets_in_flight can go to zero between write_queue state -updates and firing the resulting segments out. As FRTO processing -occurs during that window the check must be more precise to -not match "spuriously" :-). More specificly, e.g., when -packets_in_flight is zero but FLAG_DATA_ACKED is true the problematic -branch that set cwnd into zero would not be taken and new segments -might be sent out later. - -Signed-off-by: Ilpo Järvinen -Tested-by: Eric Dumazet -Acked-by: Neal Cardwell -Signed-off-by: David S. Miller ---- - net/ipv4/tcp_input.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 3a5f691..beabc80 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -3484,8 +3484,7 @@ static bool tcp_process_frto(struct sock *sk, int flag) - ((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED))) - tp->undo_marker = 0; - -- if (!before(tp->snd_una, tp->frto_highmark) || -- !tcp_packets_in_flight(tp)) { -+ if (!before(tp->snd_una, tp->frto_highmark)) { - tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); - return true; - } -@@ -3505,6 +3504,11 @@ static bool tcp_process_frto(struct sock *sk, int flag) - } - } else { - if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { -+ if (!tcp_packets_in_flight(tp)) { -+ tcp_enter_frto_loss(sk, 2, flag); -+ return true; -+ } -+ - /* Prevent sending of new data. */ - tp->snd_cwnd = min(tp->snd_cwnd, - tcp_packets_in_flight(tp)); --- -1.7.11.7 - - -From a037491fdc5e5ca2b6f21366b1165555e285c71d Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Sun, 2 Dec 2012 11:49:27 +0000 -Subject: [PATCH 40/44] tcp: don't abort splice() after small transfers - -[ Upstream commit 02275a2ee7c0ea475b6f4a6428f5df592bc9d30b ] - -TCP coalescing added a regression in splice(socket->pipe) performance, -for some workloads because of the way tcp_read_sock() is implemented. - -The reason for this is the break when (offset + 1 != skb->len). - -As we released the socket lock, this condition is possible if TCP stack -added a fragment to the skb, which can happen with TCP coalescing. - -So let's go back to the beginning of the loop when this happens, -to give a chance to splice more frags per system call. - -Doing so fixes the issue and makes GRO 10% faster than LRO -on CPU-bound splice() workloads instead of the opposite. - -Signed-off-by: Willy Tarreau -Signed-off-by: Eric Dumazet -Signed-off-by: David S. Miller ---- - net/ipv4/tcp.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index e457c7a..91de64d 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1490,15 +1490,19 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, - copied += used; - offset += used; - } -- /* -- * If recv_actor drops the lock (e.g. TCP splice -+ /* If recv_actor drops the lock (e.g. TCP splice - * receive) the skb pointer might be invalid when - * getting here: tcp_collapse might have deleted it - * while aggregating skbs from the socket queue. - */ -- skb = tcp_recv_skb(sk, seq-1, &offset); -- if (!skb || (offset+1 != skb->len)) -+ skb = tcp_recv_skb(sk, seq - 1, &offset); -+ if (!skb) - break; -+ /* TCP coalescing might have appended data to the skb. -+ * Try to splice more frags -+ */ -+ if (offset + 1 != skb->len) -+ continue; - } - if (tcp_hdr(skb)->fin) { - sk_eat_skb(sk, skb, false); --- -1.7.11.7 - - -From 1f2037984ea99422150679b62f18e9d41f2e9b71 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Thu, 10 Jan 2013 07:06:10 +0000 -Subject: [PATCH 41/44] tcp: splice: fix an infinite loop in tcp_read_sock() - -[ Upstream commit ff905b1e4aad8ccbbb0d42f7137f19482742ff07 ] - -commit 02275a2ee7c0 (tcp: don't abort splice() after small transfers) -added a regression. - -[ 83.843570] INFO: rcu_sched self-detected stall on CPU -[ 83.844575] INFO: rcu_sched detected stalls on CPUs/tasks: { 6} (detected by 0, t=21002 jiffies, g=4457, c=4456, q=13132) -[ 83.844582] Task dump for CPU 6: -[ 83.844584] netperf R running task 0 8966 8952 0x0000000c -[ 83.844587] 0000000000000000 0000000000000006 0000000000006c6c 0000000000000000 -[ 83.844589] 000000000000006c 0000000000000096 ffffffff819ce2bc ffffffffffffff10 -[ 83.844592] ffffffff81088679 0000000000000010 0000000000000246 ffff880c4b9ddcd8 -[ 83.844594] Call Trace: -[ 83.844596] [] ? vprintk_emit+0x1c9/0x4c0 -[ 83.844601] [] ? schedule+0x29/0x70 -[ 83.844606] [] ? tcp_splice_data_recv+0x42/0x50 -[ 83.844610] [] ? tcp_read_sock+0xda/0x260 -[ 83.844613] [] ? tcp_prequeue_process+0xb0/0xb0 -[ 83.844615] [] ? tcp_splice_read+0xc0/0x250 -[ 83.844618] [] ? sock_splice_read+0x22/0x30 -[ 83.844622] [] ? do_splice_to+0x7b/0xa0 -[ 83.844627] [] ? sys_splice+0x59c/0x5d0 -[ 83.844630] [] ? putname+0x2b/0x40 -[ 83.844633] [] ? do_sys_open+0x174/0x1e0 -[ 83.844636] [] ? system_call_fastpath+0x16/0x1b - -if recv_actor() returns 0, we should stop immediately, -because looping wont give a chance to drain the pipe. - -Signed-off-by: Eric Dumazet -Cc: Willy Tarreau -Signed-off-by: David S. Miller ---- - net/ipv4/tcp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 91de64d..6e92233 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1481,7 +1481,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, - break; - } - used = recv_actor(desc, skb, offset, len); -- if (used < 0) { -+ if (used <= 0) { - if (!copied) - copied = used; - break; --- -1.7.11.7 - - -From a2252d0dd0d7345a6266c6c1c5c3e7ff7025c207 Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Wed, 9 Jan 2013 20:59:09 +0000 -Subject: [PATCH 42/44] tcp: fix splice() and tcp collapsing interaction - -[ Upstream commit f26845b43c75d3f32f98d194c1327b5b1e6b3fb0 ] - -Under unusual circumstances, TCP collapse can split a big GRO TCP packet -while its being used in a splice(socket->pipe) operation. - -skb_splice_bits() releases the socket lock before calling -splice_to_pipe(). - -[ 1081.353685] WARNING: at net/ipv4/tcp.c:1330 tcp_cleanup_rbuf+0x4d/0xfc() -[ 1081.371956] Hardware name: System x3690 X5 -[7148Z68]- -[ 1081.391820] cleanup rbuf bug: copied AD3BCF1 seq AD370AF rcvnxt AD3CF13 - -To fix this problem, we must eat skbs in tcp_recv_skb(). - -Remove the inline keyword from tcp_recv_skb() definition since -it has three call sites. - -Reported-by: Christian Becker -Cc: Willy Tarreau -Signed-off-by: Eric Dumazet -Tested-by: Willy Tarreau -Signed-off-by: David S. Miller ---- - net/ipv4/tcp.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 6e92233..667e8a0 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1427,12 +1427,12 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) - } - #endif - --static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) -+static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) - { - struct sk_buff *skb; - u32 offset; - -- skb_queue_walk(&sk->sk_receive_queue, skb) { -+ while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { - offset = seq - TCP_SKB_CB(skb)->seq; - if (tcp_hdr(skb)->syn) - offset--; -@@ -1440,6 +1440,11 @@ static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) - *off = offset; - return skb; - } -+ /* This looks weird, but this can happen if TCP collapsing -+ * splitted a fat GRO packet, while we released socket lock -+ * in skb_splice_bits() -+ */ -+ sk_eat_skb(sk, skb, false); - } - return NULL; - } -@@ -1519,8 +1524,10 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, - tcp_rcv_space_adjust(sk); - - /* Clean up data we have read: This will do ACK frames. */ -- if (copied > 0) -+ if (copied > 0) { -+ tcp_recv_skb(sk, seq, &offset); - tcp_cleanup_rbuf(sk, copied); -+ } - return copied; - } - EXPORT_SYMBOL(tcp_read_sock); --- -1.7.11.7 - - -From 6d0823b619aa6fc4280d61438626b7c6c9bb31ee Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Sat, 5 Jan 2013 21:31:18 +0000 -Subject: [PATCH 43/44] net: splice: avoid high order page splitting - -[ Upstream commit 82bda6195615891181115f579a480aa5001ce7e9 ] - -splice() can handle pages of any order, but network code tries hard to -split them in PAGE_SIZE units. Not quite successfully anyway, as -__splice_segment() assumed poff < PAGE_SIZE. This is true for -the skb->data part, not necessarily for the fragments. - -This patch removes this logic to give the pages as they are in the skb. - -Signed-off-by: Eric Dumazet -Cc: Willy Tarreau -Signed-off-by: David S. Miller ---- - net/core/skbuff.c | 38 +++++++++----------------------------- - 1 file changed, 9 insertions(+), 29 deletions(-) - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 3f0636c..5b1b915 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1677,20 +1677,6 @@ static bool spd_fill_page(struct splice_pipe_desc *spd, - return false; - } - --static inline void __segment_seek(struct page **page, unsigned int *poff, -- unsigned int *plen, unsigned int off) --{ -- unsigned long n; -- -- *poff += off; -- n = *poff / PAGE_SIZE; -- if (n) -- *page = nth_page(*page, n); -- -- *poff = *poff % PAGE_SIZE; -- *plen -= off; --} -- - static bool __splice_segment(struct page *page, unsigned int poff, - unsigned int plen, unsigned int *off, - unsigned int *len, struct sk_buff *skb, -@@ -1698,6 +1684,8 @@ static bool __splice_segment(struct page *page, unsigned int poff, - struct sock *sk, - struct pipe_inode_info *pipe) - { -+ unsigned int flen; -+ - if (!*len) - return true; - -@@ -1708,24 +1696,16 @@ static bool __splice_segment(struct page *page, unsigned int poff, - } - - /* ignore any bits we already processed */ -- if (*off) { -- __segment_seek(&page, &poff, &plen, *off); -- *off = 0; -- } -- -- do { -- unsigned int flen = min(*len, plen); -+ poff += *off; -+ plen -= *off; -+ *off = 0; - -- /* the linear region may spread across several pages */ -- flen = min_t(unsigned int, flen, PAGE_SIZE - poff); -+ flen = min(*len, plen); - -- if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) -- return true; -- -- __segment_seek(&page, &poff, &plen, flen); -- *len -= flen; -+ if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) -+ return true; - -- } while (*len && plen); -+ *len -= flen; - - return false; - } --- -1.7.11.7 - - -From 6a1308f7cb927c58898aed1fa44a0df8bf1d8e4c Mon Sep 17 00:00:00 2001 -From: Eric Dumazet -Date: Fri, 11 Jan 2013 14:46:37 +0000 -Subject: [PATCH 44/44] net: splice: fix __splice_segment() - -[ Upstream commit bc9540c637c3d8712ccbf9dcf28621f380ed5e64 ] - -commit 9ca1b22d6d2 (net: splice: avoid high order page splitting) -forgot that skb->head could need a copy into several page frags. - -This could be the case for loopback traffic mostly. - -Also remove now useless skb argument from linear_to_page() -and __splice_segment() prototypes. - -Signed-off-by: Eric Dumazet -Cc: Willy Tarreau -Signed-off-by: David S. Miller ---- - net/core/skbuff.c | 28 +++++++++++++++------------- - 1 file changed, 15 insertions(+), 13 deletions(-) - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 5b1b915..1899d83 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1620,7 +1620,7 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) - - static struct page *linear_to_page(struct page *page, unsigned int *len, - unsigned int *offset, -- struct sk_buff *skb, struct sock *sk) -+ struct sock *sk) - { - struct page_frag *pfrag = sk_page_frag(sk); - -@@ -1653,14 +1653,14 @@ static bool spd_can_coalesce(const struct splice_pipe_desc *spd, - static bool spd_fill_page(struct splice_pipe_desc *spd, - struct pipe_inode_info *pipe, struct page *page, - unsigned int *len, unsigned int offset, -- struct sk_buff *skb, bool linear, -+ bool linear, - struct sock *sk) - { - if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) - return true; - - if (linear) { -- page = linear_to_page(page, len, &offset, skb, sk); -+ page = linear_to_page(page, len, &offset, sk); - if (!page) - return true; - } -@@ -1679,13 +1679,11 @@ static bool spd_fill_page(struct splice_pipe_desc *spd, - - static bool __splice_segment(struct page *page, unsigned int poff, - unsigned int plen, unsigned int *off, -- unsigned int *len, struct sk_buff *skb, -+ unsigned int *len, - struct splice_pipe_desc *spd, bool linear, - struct sock *sk, - struct pipe_inode_info *pipe) - { -- unsigned int flen; -- - if (!*len) - return true; - -@@ -1700,12 +1698,16 @@ static bool __splice_segment(struct page *page, unsigned int poff, - plen -= *off; - *off = 0; - -- flen = min(*len, plen); -- -- if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) -- return true; -+ do { -+ unsigned int flen = min(*len, plen); - -- *len -= flen; -+ if (spd_fill_page(spd, pipe, page, &flen, poff, -+ linear, sk)) -+ return true; -+ poff += flen; -+ plen -= flen; -+ *len -= flen; -+ } while (*len && plen); - - return false; - } -@@ -1728,7 +1730,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, - if (__splice_segment(virt_to_page(skb->data), - (unsigned long) skb->data & (PAGE_SIZE - 1), - skb_headlen(skb), -- offset, len, skb, spd, -+ offset, len, spd, - skb_head_is_locked(skb), - sk, pipe)) - return true; -@@ -1741,7 +1743,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, - - if (__splice_segment(skb_frag_page(f), - f->page_offset, skb_frag_size(f), -- offset, len, skb, spd, false, sk, pipe)) -+ offset, len, spd, false, sk, pipe)) - return true; - } - --- -1.7.11.7 - diff --git a/sources b/sources index c686ded..59ee680 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ 21223369d682bcf44bcdfe1521095983 linux-3.7.tar.xz -e232d2535bbd36fe05c203bacc5b72ea patch-3.7.7.xz +bf62e0cbc13524bb802d2ed05c7e2e6a patch-3.7.8.xz