]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 03:03:42 +0000 (12:03 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 03:03:42 +0000 (12:03 +0900)
added patches:
cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
net-flow_dissector-fail-on-evil-iph-ihl.patch
net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch
tcp-gso-fix-truesize-tracking.patch
virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
xen-netback-transition-to-closed-when-removing-a-vif.patch
xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch

12 files changed:
queue-3.11/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch [new file with mode: 0644]
queue-3.11/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch [new file with mode: 0644]
queue-3.11/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch [new file with mode: 0644]
queue-3.11/net-flow_dissector-fail-on-evil-iph-ihl.patch [new file with mode: 0644]
queue-3.11/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch [new file with mode: 0644]
queue-3.11/net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch [new file with mode: 0644]
queue-3.11/series [new file with mode: 0644]
queue-3.11/tcp-gso-fix-truesize-tracking.patch [new file with mode: 0644]
queue-3.11/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch [new file with mode: 0644]
queue-3.11/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch [new file with mode: 0644]
queue-3.11/xen-netback-transition-to-closed-when-removing-a-vif.patch [new file with mode: 0644]
queue-3.11/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch [new file with mode: 0644]

diff --git a/queue-3.11/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch b/queue-3.11/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
new file mode 100644 (file)
index 0000000..fd83b06
--- /dev/null
@@ -0,0 +1,45 @@
+From dec21df8d6cd2017534f8174e0295446b6f2792d Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 27 Oct 2013 21:02:39 +0000
+Subject: cxgb3: Fix length calculation in write_ofld_wr() on 32-bit architectures
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit 262e827fe745642589450ae241b7afd3912c3f25 ]
+
+The length calculation here is now invalid on 32-bit architectures,
+since sk_buff::tail is a pointer and sk_buff::transport_header is
+an integer offset:
+
+drivers/net/ethernet/chelsio/cxgb3/sge.c: In function 'write_ofld_wr':
+drivers/net/ethernet/chelsio/cxgb3/sge.c:1603:9: warning: passing argument 4 of 'make_sgl' makes integer from pointer without a cast [enabled by default]
+         adap->pdev);
+         ^
+drivers/net/ethernet/chelsio/cxgb3/sge.c:964:28: note: expected 'unsigned int' but argument is of type 'sk_buff_data_t'
+ static inline unsigned int make_sgl(const struct sk_buff *skb,
+                            ^
+
+Use the appropriate skb accessor functions.
+
+Compile-tested only.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 1a37e412a022 ('net: Use 16bits for *_headers fields of struct skbuff')
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/chelsio/cxgb3/sge.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
++++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
+@@ -1599,7 +1599,8 @@ static void write_ofld_wr(struct adapter
+       flits = skb_transport_offset(skb) / 8;
+       sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
+       sgl_flits = make_sgl(skb, sgp, skb_transport_header(skb),
+-                           skb->tail - skb->transport_header,
++                           skb_tail_pointer(skb) -
++                           skb_transport_header(skb),
+                            adap->pdev);
+       if (need_skb_unmap()) {
+               setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
diff --git a/queue-3.11/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch b/queue-3.11/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
new file mode 100644 (file)
index 0000000..efdbbe3
--- /dev/null
@@ -0,0 +1,68 @@
+From a83f67e334054f6bebe86330a18429f713232c58 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 24 Oct 2013 07:48:24 +0200
+Subject: ipv6: ip6_dst_check needs to check for expired dst_entries
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit e3bc10bd95d7fcc3f2ac690c6ff22833ea6781d6 ]
+
+On receiving a packet too big icmp error we check if our current cached
+dst_entry in the socket is still valid. This validation check did not
+care about the expiration of the (cached) route.
+
+The error path I traced down:
+The socket receives a packet too big mtu notification. It still has a
+valid dst_entry and thus issues the ip6_rt_pmtu_update on this dst_entry,
+setting RTF_EXPIRE and updates the dst.expiration value (which could
+fail because of not up-to-date expiration values, see previous patch).
+
+In some seldom cases we race with a) the ip6_fib gc or b) another routing
+lookup which would result in a recreation of the cached rt6_info from its
+parent non-cached rt6_info. While copying the rt6_info we reinitialize the
+metrics store by copying it over from the parent thus invalidating the
+just installed pmtu update (both dsts use the same key to the inetpeer
+storage). The dst_entry with the just invalidated metrics data would
+just get its RTF_EXPIRES flag cleared and would continue to stay valid
+for the socket.
+
+We should have not issued the pmtu update on the already expired dst_entry
+in the first placed. By checking the expiration on the dst entry and
+doing a relookup in case it is out of date we close the race because
+we would install a new rt6_info into the fib before we issue the pmtu
+update, thus closing this race.
+
+Not reliably updating the dst.expire value was fixed by the patch "ipv6:
+reset dst.expires value when clearing expire flag".
+
+Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
+Reported-by: Valentijn Sessink <valentyn@blub.net>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Valentijn Sessink <valentyn@blub.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1088,10 +1088,13 @@ static struct dst_entry *ip6_dst_check(s
+       if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
+               return NULL;
+-      if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
+-              return dst;
++      if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
++              return NULL;
++
++      if (rt6_check_expired(rt))
++              return NULL;
+-      return NULL;
++      return dst;
+ }
+ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
diff --git a/queue-3.11/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch b/queue-3.11/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
new file mode 100644 (file)
index 0000000..6f41dbb
--- /dev/null
@@ -0,0 +1,54 @@
+From 62d011151c62956411e15fb6b1ba7b46e55f23d9 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 24 Oct 2013 10:14:27 +0200
+Subject: ipv6: reset dst.expires value when clearing expire flag
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 01ba16d6ec85a1ec4669c75513a76b61ec53ee50 ]
+
+On receiving a packet too big icmp error we update the expire value by
+calling rt6_update_expires. This function uses dst_set_expires which is
+implemented that it can only reduce the expiration value of the dst entry.
+
+If we insert new routing non-expiry information into the ipv6 fib where
+we already have a matching rt6_info we only clear the RTF_EXPIRES flag
+in rt6i_flags and leave the dst.expires value as is.
+
+When new mtu information arrives for that cached dst_entry we again
+call dst_set_expires. This time it won't update the dst.expire value
+because we left the dst.expire value intact from the last update. So
+dst_set_expires won't touch dst.expires.
+
+Fix this by resetting dst.expires when clearing the RTF_EXPIRE flag.
+dst_set_expires checks for a zero expiration and updates the
+dst.expires.
+
+In the past this (not updating dst.expires) was necessary because
+dst.expire was placed in a union with the dst_entry *from reference
+and rt6_clean_expires did assign NULL to it. This split happend in
+ecd9883724b78cc72ed92c98bcb1a46c764fff21 ("ipv6: fix race condition
+regarding dst->expires and dst->from").
+
+Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
+Reported-by: Valentijn Sessink <valentyn@blub.net>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Valentijn Sessink <valentyn@blub.net>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip6_fib.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/net/ip6_fib.h
++++ b/include/net/ip6_fib.h
+@@ -165,6 +165,7 @@ static inline struct inet6_dev *ip6_dst_
+ static inline void rt6_clean_expires(struct rt6_info *rt)
+ {
+       rt->rt6i_flags &= ~RTF_EXPIRES;
++      rt->dst.expires = 0;
+ }
+ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
diff --git a/queue-3.11/net-flow_dissector-fail-on-evil-iph-ihl.patch b/queue-3.11/net-flow_dissector-fail-on-evil-iph-ihl.patch
new file mode 100644 (file)
index 0000000..7fcc4f4
--- /dev/null
@@ -0,0 +1,39 @@
+From 07c0bf763fdfe84a1580098d8ddc3f5ce485edd7 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 1 Nov 2013 15:01:10 +0800
+Subject: net: flow_dissector: fail on evil iph->ihl
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 6f092343855a71e03b8d209815d8c45bf3a27fcd ]
+
+We don't validate iph->ihl which may lead a dead loop if we meet a IPIP
+skb whose iph->ihl is zero. Fix this by failing immediately when iph->ihl
+is evil (less than 5).
+
+This issue were introduced by commit ec5efe7946280d1e84603389a1030ccec0a767ae
+(rps: support IPIP encapsulation).
+
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Petr Matousek <pmatouse@redhat.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Daniel Borkmann <dborkman@redhat.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/flow_dissector.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -40,7 +40,7 @@ again:
+               struct iphdr _iph;
+ ip:
+               iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+-              if (!iph)
++              if (!iph || iph->ihl < 5)
+                       return false;
+               if (ip_is_fragment(iph))
diff --git a/queue-3.11/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch b/queue-3.11/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
new file mode 100644 (file)
index 0000000..1fc2322
--- /dev/null
@@ -0,0 +1,31 @@
+From 7e771ab8165cc09657994d01ef1d2b1f62d6c2c2 Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Date: Sun, 3 Nov 2013 10:04:07 +0200
+Subject: net/mlx4_core: Fix call to __mlx4_unregister_mac
+
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+
+[ Upstream commit c32b7dfbb1dfb3f0a68f250deff65103c8bb704a ]
+
+In function mlx4_master_deactivate_admin_state() __mlx4_unregister_mac was
+called using the MAC index. It should be called with the value of the MAC itself.
+
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cmd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+@@ -1673,7 +1673,7 @@ static void mlx4_master_deactivate_admin
+                       vp_oper->vlan_idx = NO_INDX;
+               }
+               if (NO_INDX != vp_oper->mac_idx) {
+-                      __mlx4_unregister_mac(&priv->dev, port, vp_oper->mac_idx);
++                      __mlx4_unregister_mac(&priv->dev, port, vp_oper->state.mac);
+                       vp_oper->mac_idx = NO_INDX;
+               }
+       }
diff --git a/queue-3.11/net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch b/queue-3.11/net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch
new file mode 100644 (file)
index 0000000..d2000b6
--- /dev/null
@@ -0,0 +1,51 @@
+From 4de3b2820b148893b9b901368eeae1c34d739a17 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Thu, 31 Oct 2013 09:13:32 +0100
+Subject: net: sctp: do not trigger BUG_ON in sctp_cmd_delete_tcb
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit 7926c1d5be0b7cbe5b8d5c788d7d39237e7b212c ]
+
+Introduced in f9e42b853523 ("net: sctp: sideeffect: throw BUG if
+primary_path is NULL"), we intended to find a buggy assoc that's
+part of the assoc hash table with a primary_path that is NULL.
+However, we better remove the BUG_ON for now and find a more
+suitable place to assert for these things as Mark reports that
+this also triggers the bug when duplication cookie processing
+happens, and the assoc is not part of the hash table (so all
+good in this case). Such a situation can for example easily be
+reproduced by:
+
+  tc qdisc add dev eth0 root handle 1: prio bands 2 priomap 1 1 1 1 1 1
+  tc qdisc add dev eth0 parent 1:2 handle 20: netem loss 20%
+  tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip \
+            protocol 132 0xff match u8 0x0b 0xff at 32 flowid 1:2
+
+This drops 20% of COOKIE-ACK packets. After some follow-up
+discussion with Vlad we came to the conclusion that for now we
+should still better remove this BUG_ON() assertion, and come up
+with two follow-ups later on, that is, i) find a more suitable
+place for this assertion, and possibly ii) have a special
+allocator/initializer for such kind of temporary assocs.
+
+Reported-by: Mark Thomas <Mark.Thomas@metaswitch.com>
+Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/sm_sideeffect.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -866,7 +866,6 @@ static void sctp_cmd_delete_tcb(sctp_cmd
+           (!asoc->temp) && (sk->sk_shutdown != SHUTDOWN_MASK))
+               return;
+-      BUG_ON(asoc->peer.primary_path == NULL);
+       sctp_unhash_established(asoc);
+       sctp_association_free(asoc);
+ }
diff --git a/queue-3.11/series b/queue-3.11/series
new file mode 100644 (file)
index 0000000..3753d5a
--- /dev/null
@@ -0,0 +1,11 @@
+net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
+net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch
+net-flow_dissector-fail-on-evil-iph-ihl.patch
+virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
+xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch
+cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
+tcp-gso-fix-truesize-tracking.patch
+ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
+ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
+xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
+xen-netback-transition-to-closed-when-removing-a-vif.patch
diff --git a/queue-3.11/tcp-gso-fix-truesize-tracking.patch b/queue-3.11/tcp-gso-fix-truesize-tracking.patch
new file mode 100644 (file)
index 0000000..5f03120
--- /dev/null
@@ -0,0 +1,70 @@
+From efc59b9cd7170b6417846c13b58110989ce780f9 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 25 Oct 2013 17:26:17 -0700
+Subject: tcp: gso: fix truesize tracking
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d08c42cf9a71530fef5ebcfe368f38f2dd0476f ]
+
+commit 6ff50cd55545 ("tcp: gso: do not generate out of order packets")
+had an heuristic that can trigger a warning in skb_try_coalesce(),
+because skb->truesize of the gso segments were exactly set to mss.
+
+This breaks the requirement that
+
+skb->truesize >= skb->len + truesizeof(struct sk_buff);
+
+It can trivially be reproduced by :
+
+ifconfig lo mtu 1500
+ethtool -K lo tso off
+netperf
+
+As the skbs are looped into the TCP networking stack, skb_try_coalesce()
+warns us of these skb under-estimating their truesize.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Alexei Starovoitov <ast@plumgrid.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_offload.c |   13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -18,6 +18,7 @@ struct sk_buff *tcp_tso_segment(struct s
+                               netdev_features_t features)
+ {
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
++      unsigned int sum_truesize = 0;
+       struct tcphdr *th;
+       unsigned int thlen;
+       unsigned int seq;
+@@ -102,13 +103,7 @@ struct sk_buff *tcp_tso_segment(struct s
+               if (copy_destructor) {
+                       skb->destructor = gso_skb->destructor;
+                       skb->sk = gso_skb->sk;
+-                      /* {tcp|sock}_wfree() use exact truesize accounting :
+-                       * sum(skb->truesize) MUST be exactly be gso_skb->truesize
+-                       * So we account mss bytes of 'true size' for each segment.
+-                       * The last segment will contain the remaining.
+-                       */
+-                      skb->truesize = mss;
+-                      gso_skb->truesize -= mss;
++                      sum_truesize += skb->truesize;
+               }
+               skb = skb->next;
+               th = tcp_hdr(skb);
+@@ -125,7 +120,9 @@ struct sk_buff *tcp_tso_segment(struct s
+       if (copy_destructor) {
+               swap(gso_skb->sk, skb->sk);
+               swap(gso_skb->destructor, skb->destructor);
+-              swap(gso_skb->truesize, skb->truesize);
++              sum_truesize += skb->truesize;
++              atomic_add(sum_truesize - gso_skb->truesize,
++                         &skb->sk->sk_wmem_alloc);
+       }
+       delta = htonl(oldlen + (skb_tail_pointer(skb) -
diff --git a/queue-3.11/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch b/queue-3.11/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
new file mode 100644 (file)
index 0000000..dff0999
--- /dev/null
@@ -0,0 +1,116 @@
+From 5eead7070c947004877a5ff692e5b8b2a9594346 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Tue, 29 Oct 2013 15:11:07 +0800
+Subject: virtio-net: correctly handle cpu hotplug notifier during resuming
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit ec9debbd9a88d8ea86c488d6ffcac419ee7d46d9 ]
+
+commit 3ab098df35f8b98b6553edc2e40234af512ba877 (virtio-net: don't respond to
+cpu hotplug notifier if we're not ready) tries to bypass the cpu hotplug
+notifier by checking the config_enable and does nothing is it was false. So it
+need to try to hold the config_lock mutex which may happen in atomic
+environment which leads the following warnings:
+
+[  622.944441] CPU0 attaching NULL sched-domain.
+[  622.944446] CPU1 attaching NULL sched-domain.
+[  622.944485] CPU0 attaching NULL sched-domain.
+[  622.950795] BUG: sleeping function called from invalid context at kernel/mutex.c:616
+[  622.950796] in_atomic(): 1, irqs_disabled(): 1, pid: 10, name: migration/1
+[  622.950796] no locks held by migration/1/10.
+[  622.950798] CPU: 1 PID: 10 Comm: migration/1 Not tainted 3.12.0-rc5-wl-01249-gb91e82d #317
+[  622.950799] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[  622.950802]  0000000000000000 ffff88001d42dba0 ffffffff81a32f22 ffff88001bfb9c70
+[  622.950803]  ffff88001d42dbb0 ffffffff810edb02 ffff88001d42dc38 ffffffff81a396ed
+[  622.950805]  0000000000000046 ffff88001d42dbe8 ffffffff810e861d 0000000000000000
+[  622.950805] Call Trace:
+[  622.950810]  [<ffffffff81a32f22>] dump_stack+0x54/0x74
+[  622.950815]  [<ffffffff810edb02>] __might_sleep+0x112/0x114
+[  622.950817]  [<ffffffff81a396ed>] mutex_lock_nested+0x3c/0x3c6
+[  622.950818]  [<ffffffff810e861d>] ? up+0x39/0x3e
+[  622.950821]  [<ffffffff8153ea7c>] ? acpi_os_signal_semaphore+0x21/0x2d
+[  622.950824]  [<ffffffff81565ed1>] ? acpi_ut_release_mutex+0x5e/0x62
+[  622.950828]  [<ffffffff816d04ec>] virtnet_cpu_callback+0x33/0x87
+[  622.950830]  [<ffffffff81a42576>] notifier_call_chain+0x3c/0x5e
+[  622.950832]  [<ffffffff810e86a8>] __raw_notifier_call_chain+0xe/0x10
+[  622.950835]  [<ffffffff810c5556>] __cpu_notify+0x20/0x37
+[  622.950836]  [<ffffffff810c5580>] cpu_notify+0x13/0x15
+[  622.950838]  [<ffffffff81a237cd>] take_cpu_down+0x27/0x3a
+[  622.950841]  [<ffffffff81136289>] stop_machine_cpu_stop+0x93/0xf1
+[  622.950842]  [<ffffffff81136167>] cpu_stopper_thread+0xa0/0x12f
+[  622.950844]  [<ffffffff811361f6>] ? cpu_stopper_thread+0x12f/0x12f
+[  622.950847]  [<ffffffff81119710>] ? lock_release_holdtime.part.7+0xa3/0xa8
+[  622.950848]  [<ffffffff81135e4b>] ? cpu_stop_should_run+0x3f/0x47
+[  622.950850]  [<ffffffff810ea9b0>] smpboot_thread_fn+0x1c5/0x1e3
+[  622.950852]  [<ffffffff810ea7eb>] ? lg_global_unlock+0x67/0x67
+[  622.950854]  [<ffffffff810e36b7>] kthread+0xd8/0xe0
+[  622.950857]  [<ffffffff81a3bfad>] ? wait_for_common+0x12f/0x164
+[  622.950859]  [<ffffffff810e35df>] ? kthread_create_on_node+0x124/0x124
+[  622.950861]  [<ffffffff81a45ffc>] ret_from_fork+0x7c/0xb0
+[  622.950862]  [<ffffffff810e35df>] ? kthread_create_on_node+0x124/0x124
+[  622.950876] smpboot: CPU 1 is now offline
+[  623.194556] SMP alternatives: lockdep: fixing up alternatives
+[  623.194559] smpboot: Booting Node 0 Processor 1 APIC 0x1
+...
+
+A correct fix is to unregister the hotcpu notifier during restore and register a
+new one in resume.
+
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Tested-by: Fengguang Wu <fengguang.wu@intel.com>
+Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1096,11 +1096,6 @@ static int virtnet_cpu_callback(struct n
+ {
+       struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
+-      mutex_lock(&vi->config_lock);
+-
+-      if (!vi->config_enable)
+-              goto done;
+-
+       switch(action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+@@ -1114,8 +1109,6 @@ static int virtnet_cpu_callback(struct n
+               break;
+       }
+-done:
+-      mutex_unlock(&vi->config_lock);
+       return NOTIFY_OK;
+ }
+@@ -1672,6 +1665,8 @@ static int virtnet_freeze(struct virtio_
+       struct virtnet_info *vi = vdev->priv;
+       int i;
++      unregister_hotcpu_notifier(&vi->nb);
++
+       /* Prevent config work handler from accessing the device */
+       mutex_lock(&vi->config_lock);
+       vi->config_enable = false;
+@@ -1720,6 +1715,10 @@ static int virtnet_restore(struct virtio
+       virtnet_set_queues(vi, vi->curr_queue_pairs);
+       rtnl_unlock();
++      err = register_hotcpu_notifier(&vi->nb);
++      if (err)
++              return err;
++
+       return 0;
+ }
+ #endif
diff --git a/queue-3.11/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch b/queue-3.11/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
new file mode 100644 (file)
index 0000000..11a0923
--- /dev/null
@@ -0,0 +1,248 @@
+From 1d32297a972723d03b8e40ac76885d239c9278f7 Mon Sep 17 00:00:00 2001
+From: Paul Durrant <Paul.Durrant@citrix.com>
+Date: Thu, 26 Sep 2013 12:09:52 +0100
+Subject: xen-netback: Handle backend state transitions in a more robust way
+
+From: Paul Durrant <Paul.Durrant@citrix.com>
+
+[ Upstream commit ea732dff5cfa10789007bf4a5b935388a0bb2a8f ]
+
+When the frontend state changes netback now specifies its desired state to
+a new function, set_backend_state(), which transitions through any
+necessary intermediate states.
+This fixes an issue observed with some old Windows frontend drivers where
+they failed to transition through the Closing state and netback would not
+behave correctly.
+
+Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Wei Liu <wei.liu2@citrix.com>
+Cc: David Vrabel <david.vrabel@citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/xenbus.c |  148 +++++++++++++++++++++++++++++++--------
+ 1 file changed, 118 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -24,6 +24,12 @@
+ struct backend_info {
+       struct xenbus_device *dev;
+       struct xenvif *vif;
++
++      /* This is the state that will be reflected in xenstore when any
++       * active hotplug script completes.
++       */
++      enum xenbus_state state;
++
+       enum xenbus_state frontend_state;
+       struct xenbus_watch hotplug_status_watch;
+       u8 have_hotplug_status_watch:1;
+@@ -136,6 +142,8 @@ static int netback_probe(struct xenbus_d
+       if (err)
+               goto fail;
++      be->state = XenbusStateInitWait;
++
+       /* This kicks hotplug scripts, so do it immediately. */
+       backend_create_xenvif(be);
+@@ -208,24 +216,113 @@ static void backend_create_xenvif(struct
+       kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
+ }
+-
+-static void disconnect_backend(struct xenbus_device *dev)
++static void backend_disconnect(struct backend_info *be)
+ {
+-      struct backend_info *be = dev_get_drvdata(&dev->dev);
+-
+       if (be->vif)
+               xenvif_disconnect(be->vif);
+ }
+-static void destroy_backend(struct xenbus_device *dev)
++static void backend_connect(struct backend_info *be)
+ {
+-      struct backend_info *be = dev_get_drvdata(&dev->dev);
++      if (be->vif)
++              connect(be);
++}
+-      if (be->vif) {
+-              kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
+-              xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
+-              xenvif_free(be->vif);
+-              be->vif = NULL;
++static inline void backend_switch_state(struct backend_info *be,
++                                      enum xenbus_state state)
++{
++      struct xenbus_device *dev = be->dev;
++
++      pr_debug("%s -> %s\n", dev->nodename, xenbus_strstate(state));
++      be->state = state;
++
++      /* If we are waiting for a hotplug script then defer the
++       * actual xenbus state change.
++       */
++      if (!be->have_hotplug_status_watch)
++              xenbus_switch_state(dev, state);
++}
++
++/* Handle backend state transitions:
++ *
++ * The backend state starts in InitWait and the following transitions are
++ * allowed.
++ *
++ * InitWait -> Connected
++ *
++ *    ^    \         |
++ *    |     \        |
++ *    |      \       |
++ *    |       \      |
++ *    |        \     |
++ *    |         \    |
++ *    |          V   V
++ *
++ *  Closed  <-> Closing
++ *
++ * The state argument specifies the eventual state of the backend and the
++ * function transitions to that state via the shortest path.
++ */
++static void set_backend_state(struct backend_info *be,
++                            enum xenbus_state state)
++{
++      while (be->state != state) {
++              switch (be->state) {
++              case XenbusStateClosed:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateConnected:
++                              pr_info("%s: prepare for reconnect\n",
++                                      be->dev->nodename);
++                              backend_switch_state(be, XenbusStateInitWait);
++                              break;
++                      case XenbusStateClosing:
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateInitWait:
++                      switch (state) {
++                      case XenbusStateConnected:
++                              backend_connect(be);
++                              backend_switch_state(be, XenbusStateConnected);
++                              break;
++                      case XenbusStateClosing:
++                      case XenbusStateClosed:
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateConnected:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateClosing:
++                      case XenbusStateClosed:
++                              backend_disconnect(be);
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateClosing:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateConnected:
++                      case XenbusStateClosed:
++                              backend_switch_state(be, XenbusStateClosed);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              default:
++                      BUG();
++              }
+       }
+ }
+@@ -237,40 +334,33 @@ static void frontend_changed(struct xenb
+ {
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
+-      pr_debug("frontend state %s\n", xenbus_strstate(frontend_state));
++      pr_debug("%s -> %s\n", dev->otherend, xenbus_strstate(frontend_state));
+       be->frontend_state = frontend_state;
+       switch (frontend_state) {
+       case XenbusStateInitialising:
+-              if (dev->state == XenbusStateClosed) {
+-                      pr_info("%s: prepare for reconnect\n", dev->nodename);
+-                      xenbus_switch_state(dev, XenbusStateInitWait);
+-              }
++              set_backend_state(be, XenbusStateInitWait);
+               break;
+       case XenbusStateInitialised:
+               break;
+       case XenbusStateConnected:
+-              if (dev->state == XenbusStateConnected)
+-                      break;
+-              if (be->vif)
+-                      connect(be);
++              set_backend_state(be, XenbusStateConnected);
+               break;
+       case XenbusStateClosing:
+-              disconnect_backend(dev);
+-              xenbus_switch_state(dev, XenbusStateClosing);
++              set_backend_state(be, XenbusStateClosing);
+               break;
+       case XenbusStateClosed:
+-              xenbus_switch_state(dev, XenbusStateClosed);
++              set_backend_state(be, XenbusStateClosed);
+               if (xenbus_dev_is_online(dev))
+                       break;
+-              destroy_backend(dev);
+               /* fall through if not online */
+       case XenbusStateUnknown:
++              set_backend_state(be, XenbusStateClosed);
+               device_unregister(&dev->dev);
+               break;
+@@ -363,7 +453,9 @@ static void hotplug_status_changed(struc
+       if (IS_ERR(str))
+               return;
+       if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) {
+-              xenbus_switch_state(be->dev, XenbusStateConnected);
++              /* Complete any pending state change */
++              xenbus_switch_state(be->dev, be->state);
++
+               /* Not interested in this watch anymore. */
+               unregister_hotplug_status_watch(be);
+       }
+@@ -393,12 +485,8 @@ static void connect(struct backend_info
+       err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
+                                  hotplug_status_changed,
+                                  "%s/%s", dev->nodename, "hotplug-status");
+-      if (err) {
+-              /* Switch now, since we can't do a watch. */
+-              xenbus_switch_state(dev, XenbusStateConnected);
+-      } else {
++      if (!err)
+               be->have_hotplug_status_watch = 1;
+-      }
+       netif_wake_queue(be->vif->dev);
+ }
diff --git a/queue-3.11/xen-netback-transition-to-closed-when-removing-a-vif.patch b/queue-3.11/xen-netback-transition-to-closed-when-removing-a-vif.patch
new file mode 100644 (file)
index 0000000..692ac32
--- /dev/null
@@ -0,0 +1,50 @@
+From 9ea965b3b3831664f46d7927eb967e2d016be7c4 Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Mon, 7 Oct 2013 13:55:19 +0100
+Subject: xen-netback: transition to CLOSED when removing a VIF
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+[ Upstream commit dc62ccaccfb139d9b04bbc5a2688a4402adbfab3 ]
+
+If a guest is destroyed without transitioning its frontend to CLOSED,
+the domain becomes a zombie as netback was not grant unmapping the
+shared rings.
+
+When removing a VIF, transition the backend to CLOSED so the VIF is
+disconnected if necessary (which will unmap the shared rings etc).
+
+This fixes a regression introduced by
+279f438e36c0a70b23b86d2090aeec50155034a9 (xen-netback: Don't destroy
+the netdev until the vif is shut down).
+
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Wei Liu <wei.liu2@citrix.com>
+Cc: Paul Durrant <Paul.Durrant@citrix.com>
+Acked-by: Wei Liu <wei.liu2@citrix.com>
+Reviewed-by:  Paul Durrant <paul.durrant@citrix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/xenbus.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -39,11 +39,15 @@ static int connect_rings(struct backend_
+ static void connect(struct backend_info *);
+ static void backend_create_xenvif(struct backend_info *be);
+ static void unregister_hotplug_status_watch(struct backend_info *be);
++static void set_backend_state(struct backend_info *be,
++                            enum xenbus_state state);
+ static int netback_remove(struct xenbus_device *dev)
+ {
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
++      set_backend_state(be, XenbusStateClosed);
++
+       unregister_hotplug_status_watch(be);
+       if (be->vif) {
+               kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
diff --git a/queue-3.11/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch b/queue-3.11/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch
new file mode 100644 (file)
index 0000000..5c9e19e
--- /dev/null
@@ -0,0 +1,87 @@
+From 4efd8a100d07f1b42f001fdd20315059b6aac0d1 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2@citrix.com>
+Date: Mon, 28 Oct 2013 12:07:57 +0000
+Subject: xen-netback: use jiffies_64 value to calculate credit timeout
+
+From: Wei Liu <wei.liu2@citrix.com>
+
+[ Upstream commit 059dfa6a93b779516321e5112db9d7621b1367ba ]
+
+time_after_eq() only works if the delta is < MAX_ULONG/2.
+
+For a 32bit Dom0, if netfront sends packets at a very low rate, the time
+between subsequent calls to tx_credit_exceeded() may exceed MAX_ULONG/2
+and the test for timer_after_eq() will be incorrect. Credit will not be
+replenished and the guest may become unable to send packets (e.g., if
+prior to the long gap, all credit was exhausted).
+
+Use jiffies_64 variant to mitigate this problem for 32bit Dom0.
+
+Suggested-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Wei Liu <wei.liu2@citrix.com>
+Reviewed-by: David Vrabel <david.vrabel@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Jason Luan <jianhai.luan@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/common.h    |    1 +
+ drivers/net/xen-netback/interface.c |    3 +--
+ drivers/net/xen-netback/netback.c   |   10 +++++-----
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -92,6 +92,7 @@ struct xenvif {
+       unsigned long   credit_usec;
+       unsigned long   remaining_credit;
+       struct timer_list credit_timeout;
++      u64 credit_window_start;
+       /* Statistics */
+       unsigned long rx_gso_checksum_fixup;
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -297,8 +297,7 @@ struct xenvif *xenvif_alloc(struct devic
+       vif->credit_bytes = vif->remaining_credit = ~0UL;
+       vif->credit_usec  = 0UL;
+       init_timer(&vif->credit_timeout);
+-      /* Initialize 'expires' now: it's used to track the credit window. */
+-      vif->credit_timeout.expires = jiffies;
++      vif->credit_window_start = get_jiffies_64();
+       dev->netdev_ops = &xenvif_netdev_ops;
+       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -1430,9 +1430,8 @@ out:
+ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
+ {
+-      unsigned long now = jiffies;
+-      unsigned long next_credit =
+-              vif->credit_timeout.expires +
++      u64 now = get_jiffies_64();
++      u64 next_credit = vif->credit_window_start +
+               msecs_to_jiffies(vif->credit_usec / 1000);
+       /* Timer could already be pending in rare cases. */
+@@ -1440,8 +1439,8 @@ static bool tx_credit_exceeded(struct xe
+               return true;
+       /* Passed the point where we can replenish credit? */
+-      if (time_after_eq(now, next_credit)) {
+-              vif->credit_timeout.expires = now;
++      if (time_after_eq64(now, next_credit)) {
++              vif->credit_window_start = now;
+               tx_add_credit(vif);
+       }
+@@ -1453,6 +1452,7 @@ static bool tx_credit_exceeded(struct xe
+                       tx_credit_callback;
+               mod_timer(&vif->credit_timeout,
+                         next_credit);
++              vif->credit_window_start = next_credit;
+               return true;
+       }