From: Greg Kroah-Hartman Date: Fri, 8 Aug 2014 16:54:23 +0000 (-0700) Subject: 3.16-stable patches X-Git-Tag: v3.4.103~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9618c2a13606eb9ebe706fe89087a1d0f6c54d06;p=thirdparty%2Fkernel%2Fstable-queue.git 3.16-stable patches added patches: arch-sparc-math-emu-math_32.c-drop-stray-break-operator.patch batman-adv-fix-out-of-order-fragmentation-support.patch bbc-i2c-fix-bbc-i2c-envctrl-on-sunblade-2000.patch bna-fix-performance-regression.patch iovec-make-sure-the-caller-actually-wants-anything-in-memcpy_fromiovecend.patch ip_tunnel-ipv4-fix-tunnels-with-local-any-remote-remote_ip.patch macvlan-initialize-vlan_features-to-turn-on-offload-support.patch net-correctly-set-segment-mac_len-in-skb_segment.patch revert-net-phy-set-the-driver-when-registering-an-mdio-bus-device.patch sctp-fix-possible-seqlock-seadlock-in-sctp_packet_transmit.patch sparc64-do-not-insert-non-valid-ptes-into-the-tsb-hash-table.patch sparc64-guard-against-flushing-openfirmware-mappings.patch sparc64-ldc_connect-should-not-return-einval-when-handshake-is-in-progress.patch sunsab-fix-detection-of-break-on-sunsab-serial-console.patch tcp-fix-integer-overflow-in-tcp-vegas.patch tcp-fix-integer-overflows-in-tcp-veno.patch tg3-modify-tg3_tso_bug-to-handle-multiple-tx-rings.patch --- diff --git a/queue-3.16/arch-sparc-math-emu-math_32.c-drop-stray-break-operator.patch b/queue-3.16/arch-sparc-math-emu-math_32.c-drop-stray-break-operator.patch new file mode 100644 index 00000000000..43d90d5f042 --- /dev/null +++ b/queue-3.16/arch-sparc-math-emu-math_32.c-drop-stray-break-operator.patch @@ -0,0 +1,36 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: Andrey Utkin +Date: Mon, 4 Aug 2014 23:47:41 +0300 +Subject: arch/sparc/math-emu/math_32.c: drop stray break operator + +From: Andrey Utkin + +[ Upstream commit 093758e3daede29cb4ce6aedb111becf9d4bfc57 ] + +This commit is a guesswork, but it seems to make sense to drop this +break, as otherwise the following line is never executed and becomes +dead code. And that following line actually saves the result of +local calculation by the pointer given in function argument. So the +proposed change makes sense if this code in the whole makes sense (but I +am unable to analyze it in the whole). + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=81641 +Reported-by: David Binderman +Signed-off-by: Andrey Utkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/math-emu/math_32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/math-emu/math_32.c ++++ b/arch/sparc/math-emu/math_32.c +@@ -499,7 +499,7 @@ static int do_one_mathemu(u32 insn, unsi + case 0: fsr = *pfsr; + if (IR == -1) IR = 2; + /* fcc is always fcc0 */ +- fsr &= ~0xc00; fsr |= (IR << 10); break; ++ fsr &= ~0xc00; fsr |= (IR << 10); + *pfsr = fsr; + break; + case 1: rd->s = IR; break; diff --git a/queue-3.16/batman-adv-fix-out-of-order-fragmentation-support.patch b/queue-3.16/batman-adv-fix-out-of-order-fragmentation-support.patch new file mode 100644 index 00000000000..80a28612b50 --- /dev/null +++ b/queue-3.16/batman-adv-fix-out-of-order-fragmentation-support.patch @@ -0,0 +1,70 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Sven Eckelmann +Date: Mon, 26 May 2014 17:21:39 +0200 +Subject: batman-adv: Fix out-of-order fragmentation support + +From: Sven Eckelmann + +[ Upstream commit d9124268d84a836f14a6ead54ff9d8eee4c43be5 ] + +batadv_frag_insert_packet was unable to handle out-of-order packets because it +dropped them directly. This is caused by the way the fragmentation lists is +checked for the correct place to insert a fragmentation entry. + +The fragmentation code keeps the fragments in lists. The fragmentation entries +are kept in descending order of sequence number. The list is traversed and each +entry is compared with the new fragment. If the current entry has a smaller +sequence number than the new fragment then the new one has to be inserted +before the current entry. This ensures that the list is still in descending +order. + +An out-of-order packet with a smaller sequence number than all entries in the +list still has to be added to the end of the list. The used hlist has no +information about the last entry in the list inside hlist_head and thus the +last entry has to be calculated differently. Currently the code assumes that +the iterator variable of hlist_for_each_entry can be used for this purpose +after the hlist_for_each_entry finished. This is obviously wrong because the +iterator variable is always NULL when the list was completely traversed. + +Instead the information about the last entry has to be stored in a different +variable. + +This problem was introduced in 610bfc6bc99bc83680d190ebc69359a05fc7f605 +("batman-adv: Receive fragmented packets and merge"). + +Signed-off-by: Sven Eckelmann +Signed-off-by: Marek Lindner +Signed-off-by: Antonio Quartulli +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/fragmentation.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -128,6 +128,7 @@ static bool batadv_frag_insert_packet(st + { + struct batadv_frag_table_entry *chain; + struct batadv_frag_list_entry *frag_entry_new = NULL, *frag_entry_curr; ++ struct batadv_frag_list_entry *frag_entry_last = NULL; + struct batadv_frag_packet *frag_packet; + uint8_t bucket; + uint16_t seqno, hdr_size = sizeof(struct batadv_frag_packet); +@@ -180,11 +181,14 @@ static bool batadv_frag_insert_packet(st + ret = true; + goto out; + } ++ ++ /* store current entry because it could be the last in list */ ++ frag_entry_last = frag_entry_curr; + } + +- /* Reached the end of the list, so insert after 'frag_entry_curr'. */ +- if (likely(frag_entry_curr)) { +- hlist_add_after(&frag_entry_curr->list, &frag_entry_new->list); ++ /* Reached the end of the list, so insert after 'frag_entry_last'. */ ++ if (likely(frag_entry_last)) { ++ hlist_add_after(&frag_entry_last->list, &frag_entry_new->list); + chain->size += skb->len - hdr_size; + chain->timestamp = jiffies; + ret = true; diff --git a/queue-3.16/bbc-i2c-fix-bbc-i2c-envctrl-on-sunblade-2000.patch b/queue-3.16/bbc-i2c-fix-bbc-i2c-envctrl-on-sunblade-2000.patch new file mode 100644 index 00000000000..96f9f4dd004 --- /dev/null +++ b/queue-3.16/bbc-i2c-fix-bbc-i2c-envctrl-on-sunblade-2000.patch @@ -0,0 +1,69 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: Christopher Alexander Tobias Schulze +Date: Sun, 3 Aug 2014 15:44:52 +0200 +Subject: bbc-i2c: Fix BBC I2C envctrl on SunBlade 2000 + +From: Christopher Alexander Tobias Schulze + +[ Upstream commit 5cdceab3d5e02eb69ea0f5d8fa9181800baf6f77 ] + +Fix regression in bbc i2c temperature and fan control on some Sun systems +that causes the driver to refuse to load due to the bbc_i2c_bussel resource not +being present on the (second) i2c bus where the temperature sensors and fan +control are located. (The check for the number of resources was removed when +the driver was ported to a pure OF driver in mid 2008.) + +Signed-off-by: Christopher Alexander Tobias Schulze +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/sbus/char/bbc_envctrl.c | 6 ++++++ + drivers/sbus/char/bbc_i2c.c | 11 ++++++++--- + 2 files changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/sbus/char/bbc_envctrl.c ++++ b/drivers/sbus/char/bbc_envctrl.c +@@ -452,6 +452,9 @@ static void attach_one_temp(struct bbc_i + if (!tp) + return; + ++ INIT_LIST_HEAD(&tp->bp_list); ++ INIT_LIST_HEAD(&tp->glob_list); ++ + tp->client = bbc_i2c_attach(bp, op); + if (!tp->client) { + kfree(tp); +@@ -497,6 +500,9 @@ static void attach_one_fan(struct bbc_i2 + if (!fp) + return; + ++ INIT_LIST_HEAD(&fp->bp_list); ++ INIT_LIST_HEAD(&fp->glob_list); ++ + fp->client = bbc_i2c_attach(bp, op); + if (!fp->client) { + kfree(fp); +--- a/drivers/sbus/char/bbc_i2c.c ++++ b/drivers/sbus/char/bbc_i2c.c +@@ -300,13 +300,18 @@ static struct bbc_i2c_bus * attach_one_i + if (!bp) + return NULL; + ++ INIT_LIST_HEAD(&bp->temps); ++ INIT_LIST_HEAD(&bp->fans); ++ + bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs"); + if (!bp->i2c_control_regs) + goto fail; + +- bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); +- if (!bp->i2c_bussel_reg) +- goto fail; ++ if (op->num_resources == 2) { ++ bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); ++ if (!bp->i2c_bussel_reg) ++ goto fail; ++ } + + bp->waiting = 0; + init_waitqueue_head(&bp->wq); diff --git a/queue-3.16/bna-fix-performance-regression.patch b/queue-3.16/bna-fix-performance-regression.patch new file mode 100644 index 00000000000..9e60229ccd1 --- /dev/null +++ b/queue-3.16/bna-fix-performance-regression.patch @@ -0,0 +1,34 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Ivan Vecera +Date: Tue, 29 Jul 2014 16:29:30 +0200 +Subject: bna: fix performance regression + +From: Ivan Vecera + +[ Upstream commit c36c9d50cc6af5c5bfcc195f21b73f55520c15f9 ] + +The recent commit "e29aa33 bna: Enable Multi Buffer RX" is causing +a performance regression. It does not properly update 'cmpl' pointer +at the end of the loop in NAPI handler bnad_cq_process(). The result is +only one packet / per NAPI-schedule is processed. + +Signed-off-by: Ivan Vecera +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/brocade/bna/bnad.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/brocade/bna/bnad.c ++++ b/drivers/net/ethernet/brocade/bna/bnad.c +@@ -600,9 +600,9 @@ bnad_cq_process(struct bnad *bnad, struc + prefetch(bnad->netdev); + + cq = ccb->sw_q; +- cmpl = &cq[ccb->producer_index]; + + while (packets < budget) { ++ cmpl = &cq[ccb->producer_index]; + if (!cmpl->valid) + break; + /* The 'valid' field is set by the adapter, only after writing diff --git a/queue-3.16/iovec-make-sure-the-caller-actually-wants-anything-in-memcpy_fromiovecend.patch b/queue-3.16/iovec-make-sure-the-caller-actually-wants-anything-in-memcpy_fromiovecend.patch new file mode 100644 index 00000000000..53a11061fae --- /dev/null +++ b/queue-3.16/iovec-make-sure-the-caller-actually-wants-anything-in-memcpy_fromiovecend.patch @@ -0,0 +1,32 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Sasha Levin +Date: Thu, 31 Jul 2014 23:00:35 -0400 +Subject: iovec: make sure the caller actually wants anything in memcpy_fromiovecend + +From: Sasha Levin + +[ Upstream commit 06ebb06d49486676272a3c030bfeef4bd969a8e6 ] + +Check for cases when the caller requests 0 bytes instead of running off +and dereferencing potentially invalid iovecs. + +Signed-off-by: Sasha Levin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/iovec.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/lib/iovec.c ++++ b/lib/iovec.c +@@ -85,6 +85,10 @@ EXPORT_SYMBOL(memcpy_toiovecend); + int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, + int offset, int len) + { ++ /* No data? Done! */ ++ if (len == 0) ++ return 0; ++ + /* Skip over the finished iovecs */ + while (offset >= iov->iov_len) { + offset -= iov->iov_len; diff --git a/queue-3.16/ip_tunnel-ipv4-fix-tunnels-with-local-any-remote-remote_ip.patch b/queue-3.16/ip_tunnel-ipv4-fix-tunnels-with-local-any-remote-remote_ip.patch new file mode 100644 index 00000000000..9dbcdc2b67e --- /dev/null +++ b/queue-3.16/ip_tunnel-ipv4-fix-tunnels-with-local-any-remote-remote_ip.patch @@ -0,0 +1,126 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Dmitry Popov +Date: Tue, 29 Jul 2014 03:07:52 +0400 +Subject: ip_tunnel(ipv4): fix tunnels with "local any remote $remote_ip" + +From: Dmitry Popov + +[ Upstream commit 95cb5745983c222867cc9ac593aebb2ad67d72c0 ] + +Ipv4 tunnels created with "local any remote $ip" didn't work properly since +7d442fab0 (ipv4: Cache dst in tunnels). 99% of packets sent via those tunnels +had src addr = 0.0.0.0. That was because only dst_entry was cached, although +fl4.saddr has to be cached too. Every time ip_tunnel_xmit used cached dst_entry +(tunnel_rtable_get returned non-NULL), fl4.saddr was initialized with +tnl_params->saddr (= 0 in our case), and wasn't changed until iptunnel_xmit(). + +This patch adds saddr to ip_tunnel->dst_cache, fixing this issue. + +Reported-by: Sergey Popov +Signed-off-by: Dmitry Popov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ip_tunnels.h | 1 + + net/ipv4/ip_tunnel.c | 29 ++++++++++++++++++----------- + 2 files changed, 19 insertions(+), 11 deletions(-) + +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -40,6 +40,7 @@ struct ip_tunnel_prl_entry { + + struct ip_tunnel_dst { + struct dst_entry __rcu *dst; ++ __be32 saddr; + }; + + struct ip_tunnel { +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -69,23 +69,25 @@ static unsigned int ip_tunnel_hash(__be3 + } + + static void __tunnel_dst_set(struct ip_tunnel_dst *idst, +- struct dst_entry *dst) ++ struct dst_entry *dst, __be32 saddr) + { + struct dst_entry *old_dst; + + dst_clone(dst); + old_dst = xchg((__force struct dst_entry **)&idst->dst, dst); + dst_release(old_dst); ++ idst->saddr = saddr; + } + +-static void tunnel_dst_set(struct ip_tunnel *t, struct dst_entry *dst) ++static void tunnel_dst_set(struct ip_tunnel *t, ++ struct dst_entry *dst, __be32 saddr) + { +- __tunnel_dst_set(this_cpu_ptr(t->dst_cache), dst); ++ __tunnel_dst_set(this_cpu_ptr(t->dst_cache), dst, saddr); + } + + static void tunnel_dst_reset(struct ip_tunnel *t) + { +- tunnel_dst_set(t, NULL); ++ tunnel_dst_set(t, NULL, 0); + } + + void ip_tunnel_dst_reset_all(struct ip_tunnel *t) +@@ -93,20 +95,25 @@ void ip_tunnel_dst_reset_all(struct ip_t + int i; + + for_each_possible_cpu(i) +- __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); ++ __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0); + } + EXPORT_SYMBOL(ip_tunnel_dst_reset_all); + +-static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) ++static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, ++ u32 cookie, __be32 *saddr) + { ++ struct ip_tunnel_dst *idst; + struct dst_entry *dst; + + rcu_read_lock(); +- dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); ++ idst = this_cpu_ptr(t->dst_cache); ++ dst = rcu_dereference(idst->dst); + if (dst && !atomic_inc_not_zero(&dst->__refcnt)) + dst = NULL; + if (dst) { +- if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) { ++ if (!dst->obsolete || dst->ops->check(dst, cookie)) { ++ *saddr = idst->saddr; ++ } else { + tunnel_dst_reset(t); + dst_release(dst); + dst = NULL; +@@ -367,7 +374,7 @@ static int ip_tunnel_bind_dev(struct net + + if (!IS_ERR(rt)) { + tdev = rt->dst.dev; +- tunnel_dst_set(tunnel, &rt->dst); ++ tunnel_dst_set(tunnel, &rt->dst, fl4.saddr); + ip_rt_put(rt); + } + if (dev->type != ARPHRD_ETHER) +@@ -610,7 +617,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, + init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, + tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link); + +- rt = connected ? tunnel_rtable_get(tunnel, 0) : NULL; ++ rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL; + + if (!rt) { + rt = ip_route_output_key(tunnel->net, &fl4); +@@ -620,7 +627,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, + goto tx_error; + } + if (connected) +- tunnel_dst_set(tunnel, &rt->dst); ++ tunnel_dst_set(tunnel, &rt->dst, fl4.saddr); + } + + if (rt->dst.dev == dev) { diff --git a/queue-3.16/macvlan-initialize-vlan_features-to-turn-on-offload-support.patch b/queue-3.16/macvlan-initialize-vlan_features-to-turn-on-offload-support.patch new file mode 100644 index 00000000000..c55d6ff546f --- /dev/null +++ b/queue-3.16/macvlan-initialize-vlan_features-to-turn-on-offload-support.patch @@ -0,0 +1,31 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Vlad Yasevich +Date: Thu, 31 Jul 2014 10:30:25 -0400 +Subject: macvlan: Initialize vlan_features to turn on offload support. + +From: Vlad Yasevich + +[ Upstream commit 081e83a78db9b0ae1f5eabc2dedecc865f509b98 ] + +Macvlan devices do not initialize vlan_features. As a result, +any vlan devices configured on top of macvlans perform very poorly. +Initialize vlan_features based on the vlan features of the lower-level +device. + +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvlan.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -646,6 +646,7 @@ static int macvlan_init(struct net_devic + (lowerdev->state & MACVLAN_STATE_MASK); + dev->features = lowerdev->features & MACVLAN_FEATURES; + dev->features |= ALWAYS_ON_FEATURES; ++ dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES; + dev->gso_max_size = lowerdev->gso_max_size; + dev->iflink = lowerdev->ifindex; + dev->hard_header_len = lowerdev->hard_header_len; diff --git a/queue-3.16/net-correctly-set-segment-mac_len-in-skb_segment.patch b/queue-3.16/net-correctly-set-segment-mac_len-in-skb_segment.patch new file mode 100644 index 00000000000..19de8498024 --- /dev/null +++ b/queue-3.16/net-correctly-set-segment-mac_len-in-skb_segment.patch @@ -0,0 +1,58 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Vlad Yasevich +Date: Thu, 31 Jul 2014 10:33:06 -0400 +Subject: net: Correctly set segment mac_len in skb_segment(). + +From: Vlad Yasevich + +[ Upstream commit fcdfe3a7fa4cb74391d42b6a26dc07c20dab1d82 ] + +When performing segmentation, the mac_len value is copied right +out of the original skb. However, this value is not always set correctly +(like when the packet is VLAN-tagged) and we'll end up copying a bad +value. + +One way to demonstrate this is to configure a VM which tags +packets internally and turn off VLAN acceleration on the forwarding +bridge port. The packets show up corrupt like this: +16:18:24.985548 52:54:00:ab:be:25 > 52:54:00:26:ce:a3, ethertype 802.1Q +(0x8100), length 1518: vlan 100, p 0, ethertype 0x05e0, + 0x0000: 8cdb 1c7c 8cdb 0064 4006 b59d 0a00 6402 ...|...d@.....d. + 0x0010: 0a00 6401 9e0d b441 0a5e 64ec 0330 14fa ..d....A.^d..0.. + 0x0020: 29e3 01c9 f871 0000 0101 080a 000a e833)....q.........3 + 0x0030: 000f 8c75 6e65 7470 6572 6600 6e65 7470 ...unetperf.netp + 0x0040: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp + 0x0050: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp + 0x0060: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp + ... + +This also leads to awful throughput as GSO packets are dropped and +cause retransmissions. + +The solution is to set the mac_len using the values already available +in then new skb. We've already adjusted all of the header offset, so we +might as well correctly figure out the mac_len using skb_reset_mac_len(). +After this change, packets are segmented correctly and performance +is restored. + +CC: Eric Dumazet +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2976,9 +2976,9 @@ struct sk_buff *skb_segment(struct sk_bu + tail = nskb; + + __copy_skb_header(nskb, head_skb); +- nskb->mac_len = head_skb->mac_len; + + skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); ++ skb_reset_mac_len(nskb); + + skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, + nskb->data - tnl_hlen, diff --git a/queue-3.16/revert-net-phy-set-the-driver-when-registering-an-mdio-bus-device.patch b/queue-3.16/revert-net-phy-set-the-driver-when-registering-an-mdio-bus-device.patch new file mode 100644 index 00000000000..a1906e0cccd --- /dev/null +++ b/queue-3.16/revert-net-phy-set-the-driver-when-registering-an-mdio-bus-device.patch @@ -0,0 +1,68 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Fabio Estevam +Date: Tue, 5 Aug 2014 08:13:42 -0300 +Subject: Revert "net: phy: Set the driver when registering an MDIO bus device" + +From: Fabio Estevam + +[ Upstream commit ce7991e8198b80eb6b4441b6f6114bea4a665d66 ] + +Commit a71e3c37960ce5f9 ("net: phy: Set the driver when registering an MDIO bus +device") caused the following regression on the fec driver: + +root@imx6qsabresd:~# echo mem > /sys/power/state +PM: Syncing filesystems ... done. +Freezing user space processes ... (elapsed 0.003 seconds) done. +Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done. +Unable to handle kernel NULL pointer dereference at virtual address 0000002c +pgd = bcd14000 +[0000002c] *pgd=4d9e0831, *pte=00000000, *ppte=00000000 +Internal error: Oops: 17 [#1] SMP ARM +Modules linked in: +CPU: 0 PID: 617 Comm: sh Not tainted 3.16.0 #17 +task: bc0c4e00 ti: bceb6000 task.ti: bceb6000 +PC is at fec_suspend+0x10/0x70 +LR is at dpm_run_callback.isra.7+0x34/0x6c +pc : [<803f8a98>] lr : [<80361f44>] psr: 600f0013 +sp : bceb7d70 ip : bceb7d88 fp : bceb7d84 +r10: 8091523c r9 : 00000000 r8 : bd88f478 +r7 : 803f8a88 r6 : 81165988 r5 : 00000000 r4 : 00000000 +r3 : 00000000 r2 : 00000000 r1 : bd88f478 r0 : bd88f478 +Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user +Control: 10c5387d Table: 4cd1404a DAC: 00000015 +Process sh (pid: 617, stack limit = 0xbceb6240) +Stack: (0xbceb7d70 to 0xbceb8000) +.... + +The problem with the original commit is explained by Russell King: + +"It has the effect (as can be seen from the oops) of attaching the MDIO bus +device (itself is a bus-less device) to the platform driver, which means +that if the platform driver supports power management, it will be called +to power manage the MDIO bus device. + +Moreover, drivers do not expect to be called for power management +operations for devices which they haven't probed, and certainly not for +devices which aren't part of the same bus that the driver is registered +against." + +This reverts commit a71e3c37960ce5f9c6a519bc1215e3ba9fa83e75. + +Cc: #3.16 +Signed-off-by: Fabio Estevam +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/mdio_bus.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -255,7 +255,6 @@ int mdiobus_register(struct mii_bus *bus + + bus->dev.parent = bus->parent; + bus->dev.class = &mdio_bus_class; +- bus->dev.driver = bus->parent->driver; + bus->dev.groups = NULL; + dev_set_name(&bus->dev, "%s", bus->id); + diff --git a/queue-3.16/sctp-fix-possible-seqlock-seadlock-in-sctp_packet_transmit.patch b/queue-3.16/sctp-fix-possible-seqlock-seadlock-in-sctp_packet_transmit.patch new file mode 100644 index 00000000000..fdcef597edc --- /dev/null +++ b/queue-3.16/sctp-fix-possible-seqlock-seadlock-in-sctp_packet_transmit.patch @@ -0,0 +1,71 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Eric Dumazet +Date: Tue, 5 Aug 2014 16:49:52 +0200 +Subject: sctp: fix possible seqlock seadlock in sctp_packet_transmit() + +From: Eric Dumazet + +[ Upstream commit 757efd32d5ce31f67193cc0e6a56e4dffcc42fb1 ] + +Dave reported following splat, caused by improper use of +IP_INC_STATS_BH() in process context. + +BUG: using __this_cpu_add() in preemptible [00000000] code: trinity-c117/14551 +caller is __this_cpu_preempt_check+0x13/0x20 +CPU: 3 PID: 14551 Comm: trinity-c117 Not tainted 3.16.0+ #33 + ffffffff9ec898f0 0000000047ea7e23 ffff88022d32f7f0 ffffffff9e7ee207 + 0000000000000003 ffff88022d32f818 ffffffff9e397eaa ffff88023ee70b40 + ffff88022d32f970 ffff8801c026d580 ffff88022d32f828 ffffffff9e397ee3 +Call Trace: + [] dump_stack+0x4e/0x7a + [] check_preemption_disabled+0xfa/0x100 + [] __this_cpu_preempt_check+0x13/0x20 + [] sctp_packet_transmit+0x692/0x710 [sctp] + [] sctp_outq_flush+0x2a2/0xc30 [sctp] + [] ? mark_held_locks+0x7c/0xb0 + [] ? _raw_spin_unlock_irqrestore+0x5d/0x80 + [] sctp_outq_uncork+0x1a/0x20 [sctp] + [] sctp_cmd_interpreter.isra.23+0x1142/0x13f0 [sctp] + [] sctp_do_sm+0xdb/0x330 [sctp] + [] ? preempt_count_sub+0xab/0x100 + [] ? sctp_cname+0x70/0x70 [sctp] + [] sctp_primitive_ASSOCIATE+0x3a/0x50 [sctp] + [] sctp_sendmsg+0x88f/0xe30 [sctp] + [] ? lock_release_holdtime.part.28+0x9a/0x160 + [] ? put_lock_stats.isra.27+0xe/0x30 + [] inet_sendmsg+0x104/0x220 + [] ? inet_sendmsg+0x5/0x220 + [] sock_sendmsg+0x9e/0xe0 + [] ? might_fault+0xb9/0xc0 + [] ? might_fault+0x5e/0xc0 + [] SYSC_sendto+0x124/0x1c0 + [] ? syscall_trace_enter+0x250/0x330 + [] SyS_sendto+0xe/0x10 + [] tracesys+0xdd/0xe2 + +This is a followup of commits f1d8cba61c3c4b ("inet: fix possible +seqlock deadlocks") and 7f88c6b23afbd315 ("ipv6: fix possible seqlock +deadlock in ip6_finish_output2") + +Signed-off-by: Eric Dumazet +Cc: Hannes Frederic Sowa +Reported-by: Dave Jones +Acked-by: Neil Horman +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sctp/output.c ++++ b/net/sctp/output.c +@@ -599,7 +599,7 @@ out: + return err; + no_route: + kfree_skb(nskb); +- IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); ++ IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); + + /* FIXME: Returning the 'err' will effect all the associations + * associated with a socket, although only one of the paths of the diff --git a/queue-3.16/series b/queue-3.16/series new file mode 100644 index 00000000000..6094af85938 --- /dev/null +++ b/queue-3.16/series @@ -0,0 +1,17 @@ +ip_tunnel-ipv4-fix-tunnels-with-local-any-remote-remote_ip.patch +tcp-fix-integer-overflows-in-tcp-veno.patch +tcp-fix-integer-overflow-in-tcp-vegas.patch +bna-fix-performance-regression.patch +macvlan-initialize-vlan_features-to-turn-on-offload-support.patch +net-correctly-set-segment-mac_len-in-skb_segment.patch +iovec-make-sure-the-caller-actually-wants-anything-in-memcpy_fromiovecend.patch +batman-adv-fix-out-of-order-fragmentation-support.patch +revert-net-phy-set-the-driver-when-registering-an-mdio-bus-device.patch +sctp-fix-possible-seqlock-seadlock-in-sctp_packet_transmit.patch +tg3-modify-tg3_tso_bug-to-handle-multiple-tx-rings.patch +sparc64-do-not-insert-non-valid-ptes-into-the-tsb-hash-table.patch +sparc64-guard-against-flushing-openfirmware-mappings.patch +bbc-i2c-fix-bbc-i2c-envctrl-on-sunblade-2000.patch +sunsab-fix-detection-of-break-on-sunsab-serial-console.patch +sparc64-ldc_connect-should-not-return-einval-when-handshake-is-in-progress.patch +arch-sparc-math-emu-math_32.c-drop-stray-break-operator.patch diff --git a/queue-3.16/sparc64-do-not-insert-non-valid-ptes-into-the-tsb-hash-table.patch b/queue-3.16/sparc64-do-not-insert-non-valid-ptes-into-the-tsb-hash-table.patch new file mode 100644 index 00000000000..5d8f6f05899 --- /dev/null +++ b/queue-3.16/sparc64-do-not-insert-non-valid-ptes-into-the-tsb-hash-table.patch @@ -0,0 +1,55 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: "David S. Miller" +Date: Mon, 4 Aug 2014 16:34:01 -0700 +Subject: sparc64: Do not insert non-valid PTEs into the TSB hash table. + +From: "David S. Miller" + +[ Upstream commit 18f38132528c3e603c66ea464727b29e9bbcb91b ] + +The assumption was that update_mmu_cache() (and the equivalent for PMDs) would +only be called when the PTE being installed will be accessible by the user. + +This is not true for code paths originating from remove_migration_pte(). + +There are dire consequences for placing a non-valid PTE into the TSB. The TLB +miss frramework assumes thatwhen a TSB entry matches we can just load it into +the TLB and return from the TLB miss trap. + +So if a non-valid PTE is in there, we will deadlock taking the TLB miss over +and over, never satisfying the miss. + +Just exit early from update_mmu_cache() and friends in this situation. + +Based upon a report and patch from Christopher Alexander Tobias Schulze. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/mm/init_64.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -351,6 +351,10 @@ void update_mmu_cache(struct vm_area_str + + mm = vma->vm_mm; + ++ /* Don't insert a non-valid PTE into the TSB, we'll deadlock. */ ++ if (!pte_accessible(mm, pte)) ++ return; ++ + spin_lock_irqsave(&mm->context.lock, flags); + + #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) +@@ -2619,6 +2623,10 @@ void update_mmu_cache_pmd(struct vm_area + + pte = pmd_val(entry); + ++ /* Don't insert a non-valid PMD into the TSB, we'll deadlock. */ ++ if (!(pte & _PAGE_VALID)) ++ return; ++ + /* We are fabricating 8MB pages using 4MB real hw pages. */ + pte |= (addr & (1UL << REAL_HPAGE_SHIFT)); + diff --git a/queue-3.16/sparc64-guard-against-flushing-openfirmware-mappings.patch b/queue-3.16/sparc64-guard-against-flushing-openfirmware-mappings.patch new file mode 100644 index 00000000000..de585656d40 --- /dev/null +++ b/queue-3.16/sparc64-guard-against-flushing-openfirmware-mappings.patch @@ -0,0 +1,117 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: "David S. Miller" +Date: Mon, 4 Aug 2014 20:07:37 -0700 +Subject: sparc64: Guard against flushing openfirmware mappings. + +From: "David S. Miller" + +[ Upstream commit 4ca9a23765da3260058db3431faf5b4efd8cf926 ] + +Based almost entirely upon a patch by Christopher Alexander Tobias +Schulze. + +In commit db64fe02258f1507e13fe5212a989922323685ce ("mm: rewrite vmap +layer") lazy VMAP tlb flushing was added to the vmalloc layer. This +causes problems on sparc64. + +Sparc64 has two VMAP mapped regions and they are not contiguous with +eachother. First we have the malloc mapping area, then another +unrelated region, then the vmalloc region. + +This "another unrelated region" is where the firmware is mapped. + +If the lazy TLB flushing logic in the vmalloc code triggers after +we've had both a module unload and a vfree or similar, it will pass an +address range that goes from somewhere inside the malloc region to +somewhere inside the vmalloc region, and thus covering the +openfirmware area entirely. + +The sparc64 kernel learns about openfirmware's dynamic mappings in +this region early in the boot, and then services TLB misses in this +area. But openfirmware has some locked TLB entries which are not +mentioned in those dynamic mappings and we should thus not disturb +them. + +These huge lazy TLB flush ranges causes those openfirmware locked TLB +entries to be removed, resulting in all kinds of problems including +hard hangs and crashes during reboot/reset. + +Besides causing problems like this, such huge TLB flush ranges are +also incredibly inefficient. A plea has been made with the author of +the VMAP lazy TLB flushing code, but for now we'll put a safety guard +into our flush_tlb_kernel_range() implementation. + +Since the implementation has become non-trivial, stop defining it as a +macro and instead make it a function in a C source file. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/include/asm/tlbflush_64.h | 12 ++---------- + arch/sparc/mm/init_64.c | 23 +++++++++++++++++++++++ + 2 files changed, 25 insertions(+), 10 deletions(-) + +--- a/arch/sparc/include/asm/tlbflush_64.h ++++ b/arch/sparc/include/asm/tlbflush_64.h +@@ -34,6 +34,8 @@ static inline void flush_tlb_range(struc + { + } + ++void flush_tlb_kernel_range(unsigned long start, unsigned long end); ++ + #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE + + void flush_tlb_pending(void); +@@ -48,11 +50,6 @@ void __flush_tlb_kernel_range(unsigned l + + #ifndef CONFIG_SMP + +-#define flush_tlb_kernel_range(start,end) \ +-do { flush_tsb_kernel_range(start,end); \ +- __flush_tlb_kernel_range(start,end); \ +-} while (0) +- + static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) + { + __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); +@@ -63,11 +60,6 @@ static inline void global_flush_tlb_page + void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); + void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); + +-#define flush_tlb_kernel_range(start, end) \ +-do { flush_tsb_kernel_range(start,end); \ +- smp_flush_tlb_kernel_range(start, end); \ +-} while (0) +- + #define global_flush_tlb_page(mm, vaddr) \ + smp_flush_tlb_page(mm, vaddr) + +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -2707,3 +2707,26 @@ void hugetlb_setup(struct pt_regs *regs) + } + } + #endif ++ ++#ifdef CONFIG_SMP ++#define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range ++#else ++#define do_flush_tlb_kernel_range __flush_tlb_kernel_range ++#endif ++ ++void flush_tlb_kernel_range(unsigned long start, unsigned long end) ++{ ++ if (start < HI_OBP_ADDRESS && end > LOW_OBP_ADDRESS) { ++ if (start < LOW_OBP_ADDRESS) { ++ flush_tsb_kernel_range(start, LOW_OBP_ADDRESS); ++ do_flush_tlb_kernel_range(start, LOW_OBP_ADDRESS); ++ } ++ if (end > HI_OBP_ADDRESS) { ++ flush_tsb_kernel_range(end, HI_OBP_ADDRESS); ++ do_flush_tlb_kernel_range(end, HI_OBP_ADDRESS); ++ } ++ } else { ++ flush_tsb_kernel_range(start, end); ++ do_flush_tlb_kernel_range(start, end); ++ } ++} diff --git a/queue-3.16/sparc64-ldc_connect-should-not-return-einval-when-handshake-is-in-progress.patch b/queue-3.16/sparc64-ldc_connect-should-not-return-einval-when-handshake-is-in-progress.patch new file mode 100644 index 00000000000..f689559e563 --- /dev/null +++ b/queue-3.16/sparc64-ldc_connect-should-not-return-einval-when-handshake-is-in-progress.patch @@ -0,0 +1,35 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: Sowmini Varadhan +Date: Fri, 1 Aug 2014 09:50:40 -0400 +Subject: sparc64: ldc_connect() should not return EINVAL when handshake is in progress. + +From: Sowmini Varadhan + +[ Upstream commit 4ec1b01029b4facb651b8ef70bc20a4be4cebc63 ] + +The LDC handshake could have been asynchronously triggered +after ldc_bind() enables the ldc_rx() receive interrupt-handler +(and thus intercepts incoming control packets) +and before vio_port_up() calls ldc_connect(). If that is the case, +ldc_connect() should return 0 and let the state-machine +progress. + +Signed-off-by: Sowmini Varadhan +Acked-by: Karl Volz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/ldc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/kernel/ldc.c ++++ b/arch/sparc/kernel/ldc.c +@@ -1336,7 +1336,7 @@ int ldc_connect(struct ldc_channel *lp) + if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || + !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) || + lp->hs_state != LDC_HS_OPEN) +- err = -EINVAL; ++ err = ((lp->hs_state > LDC_HS_OPEN) ? 0 : -EINVAL); + else + err = start_handshake(lp); + diff --git a/queue-3.16/sunsab-fix-detection-of-break-on-sunsab-serial-console.patch b/queue-3.16/sunsab-fix-detection-of-break-on-sunsab-serial-console.patch new file mode 100644 index 00000000000..a1131743c37 --- /dev/null +++ b/queue-3.16/sunsab-fix-detection-of-break-on-sunsab-serial-console.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Aug 8 09:26:33 PDT 2014 +From: Christopher Alexander Tobias Schulze +Date: Sun, 3 Aug 2014 16:01:53 +0200 +Subject: sunsab: Fix detection of BREAK on sunsab serial console + +From: Christopher Alexander Tobias Schulze + +[ Upstream commit fe418231b195c205701c0cc550a03f6c9758fd9e ] + +Fix detection of BREAK on sunsab serial console: BREAK detection was only +performed when there were also serial characters received simultaneously. +To handle all BREAKs correctly, the check for BREAK and the corresponding +call to uart_handle_break() must also be done if count == 0, therefore +duplicate this code fragment and pull it out of the loop over the received +characters. + +Patch applies to 3.16-rc6. + +Signed-off-by: Christopher Alexander Tobias Schulze +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/sunsab.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/tty/serial/sunsab.c ++++ b/drivers/tty/serial/sunsab.c +@@ -157,6 +157,15 @@ receive_chars(struct uart_sunsab_port *u + (up->port.line == up->port.cons->index)) + saw_console_brk = 1; + ++ if (count == 0) { ++ if (unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) { ++ stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR | ++ SAB82532_ISR0_FERR); ++ up->port.icount.brk++; ++ uart_handle_break(&up->port); ++ } ++ } ++ + for (i = 0; i < count; i++) { + unsigned char ch = buf[i], flag; + diff --git a/queue-3.16/tcp-fix-integer-overflow-in-tcp-vegas.patch b/queue-3.16/tcp-fix-integer-overflow-in-tcp-vegas.patch new file mode 100644 index 00000000000..c5b2702f39b --- /dev/null +++ b/queue-3.16/tcp-fix-integer-overflow-in-tcp-vegas.patch @@ -0,0 +1,40 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Christoph Paasch +Date: Tue, 29 Jul 2014 13:40:57 +0200 +Subject: tcp: Fix integer-overflow in TCP vegas + +From: Christoph Paasch + +[ Upstream commit 1f74e613ded11517db90b2bd57e9464d9e0fb161 ] + +In vegas we do a multiplication of the cwnd and the rtt. This +may overflow and thus their result is stored in a u64. However, we first +need to cast the cwnd so that actually 64-bit arithmetic is done. + +Then, we need to do do_div to allow this to be used on 32-bit arches. + +Cc: Stephen Hemminger +Cc: Neal Cardwell +Cc: Eric Dumazet +Cc: David Laight +Cc: Doug Leith +Fixes: 8d3a564da34e (tcp: tcp_vegas cong avoid fix) +Signed-off-by: Christoph Paasch +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_vegas.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_vegas.c ++++ b/net/ipv4/tcp_vegas.c +@@ -218,7 +218,8 @@ static void tcp_vegas_cong_avoid(struct + * This is: + * (actual rate in segments) * baseRTT + */ +- target_cwnd = tp->snd_cwnd * vegas->baseRTT / rtt; ++ target_cwnd = (u64)tp->snd_cwnd * vegas->baseRTT; ++ do_div(target_cwnd, rtt); + + /* Calculate the difference between the window we had, + * and the window we would like to have. This quantity diff --git a/queue-3.16/tcp-fix-integer-overflows-in-tcp-veno.patch b/queue-3.16/tcp-fix-integer-overflows-in-tcp-veno.patch new file mode 100644 index 00000000000..c9716bb2feb --- /dev/null +++ b/queue-3.16/tcp-fix-integer-overflows-in-tcp-veno.patch @@ -0,0 +1,36 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Christoph Paasch +Date: Tue, 29 Jul 2014 12:07:27 +0200 +Subject: tcp: Fix integer-overflows in TCP veno + +From: Christoph Paasch + +[ Upstream commit 45a07695bc64b3ab5d6d2215f9677e5b8c05a7d0 ] + +In veno we do a multiplication of the cwnd and the rtt. This +may overflow and thus their result is stored in a u64. However, we first +need to cast the cwnd so that actually 64-bit arithmetic is done. + +A first attempt at fixing 76f1017757aa0 ([TCP]: TCP Veno congestion +control) was made by 159131149c2 (tcp: Overflow bug in Vegas), but it +failed to add the required cast in tcp_veno_cong_avoid(). + +Fixes: 76f1017757aa0 ([TCP]: TCP Veno congestion control) +Signed-off-by: Christoph Paasch +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_veno.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/tcp_veno.c ++++ b/net/ipv4/tcp_veno.c +@@ -144,7 +144,7 @@ static void tcp_veno_cong_avoid(struct s + + rtt = veno->minrtt; + +- target_cwnd = (tp->snd_cwnd * veno->basertt); ++ target_cwnd = (u64)tp->snd_cwnd * veno->basertt; + target_cwnd <<= V_PARAM_SHIFT; + do_div(target_cwnd, rtt); + diff --git a/queue-3.16/tg3-modify-tg3_tso_bug-to-handle-multiple-tx-rings.patch b/queue-3.16/tg3-modify-tg3_tso_bug-to-handle-multiple-tx-rings.patch new file mode 100644 index 00000000000..e0e9a7ca8f9 --- /dev/null +++ b/queue-3.16/tg3-modify-tg3_tso_bug-to-handle-multiple-tx-rings.patch @@ -0,0 +1,85 @@ +From foo@baz Fri Aug 8 09:25:59 PDT 2014 +From: Prashant Sreedharan +Date: Tue, 5 Aug 2014 16:02:02 -0700 +Subject: tg3: Modify tg3_tso_bug() to handle multiple TX rings + +From: Prashant Sreedharan + +[ Upstream commit 4d8fdc95c60e90d84c8257a0067ff4b1729a3757 ] + +tg3_tso_bug() was originally designed to handle only HW TX ring 0, Commit +d3f6f3a1d818410c17445bce4f4caab52eb102f1 ("tg3: Prevent page allocation failure +during TSO workaround") changed the driver logic to use tg3_tso_bug() for all +HW TX rings that are enabled. This patch fixes the regression by modifying +tg3_tso_bug() to handle multiple HW TX rings. + +Signed-off-by: Prashant Sreedharan +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/tg3.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -7830,17 +7830,18 @@ static int tigon3_dma_hwbug_workaround(s + + static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); + +-/* Use GSO to workaround a rare TSO bug that may be triggered when the +- * TSO header is greater than 80 bytes. ++/* Use GSO to workaround all TSO packets that meet HW bug conditions ++ * indicated in tg3_tx_frag_set() + */ +-static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) ++static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, ++ struct netdev_queue *txq, struct sk_buff *skb) + { + struct sk_buff *segs, *nskb; + u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3; + + /* Estimate the number of fragments in the worst case */ +- if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) { +- netif_stop_queue(tp->dev); ++ if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) { ++ netif_tx_stop_queue(txq); + + /* netif_tx_stop_queue() must be done before checking + * checking tx index in tg3_tx_avail() below, because in +@@ -7848,13 +7849,14 @@ static int tg3_tso_bug(struct tg3 *tp, s + * netif_tx_queue_stopped(). + */ + smp_mb(); +- if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est) ++ if (tg3_tx_avail(tnapi) <= frag_cnt_est) + return NETDEV_TX_BUSY; + +- netif_wake_queue(tp->dev); ++ netif_tx_wake_queue(txq); + } + +- segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6)); ++ segs = skb_gso_segment(skb, tp->dev->features & ++ ~(NETIF_F_TSO | NETIF_F_TSO6)); + if (IS_ERR(segs) || !segs) + goto tg3_tso_bug_end; + +@@ -7930,7 +7932,7 @@ static netdev_tx_t tg3_start_xmit(struct + if (!skb_is_gso_v6(skb)) { + if (unlikely((ETH_HLEN + hdr_len) > 80) && + tg3_flag(tp, TSO_BUG)) +- return tg3_tso_bug(tp, skb); ++ return tg3_tso_bug(tp, tnapi, txq, skb); + + ip_csum = iph->check; + ip_tot_len = iph->tot_len; +@@ -8061,7 +8063,7 @@ static netdev_tx_t tg3_start_xmit(struct + iph->tot_len = ip_tot_len; + } + tcph->check = tcp_csum; +- return tg3_tso_bug(tp, skb); ++ return tg3_tso_bug(tp, tnapi, txq, skb); + } + + /* If the workaround fails due to memory/mapping