From: Greg Kroah-Hartman Date: Thu, 14 Nov 2013 03:03:42 +0000 (+0900) Subject: 3.11-stable patches X-Git-Tag: v3.4.70~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95488d6f005dd2504d663d6bce370ec7de342e94;p=thirdparty%2Fkernel%2Fstable-queue.git 3.11-stable patches 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 --- 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 index 00000000000..fd83b0610d8 --- /dev/null +++ b/queue-3.11/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch @@ -0,0 +1,45 @@ +From dec21df8d6cd2017534f8174e0295446b6f2792d Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 + +[ 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 +Fixes: 1a37e412a022 ('net: Use 16bits for *_headers fields of struct skbuff') +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..efdbbe3ff67 --- /dev/null +++ b/queue-3.11/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch @@ -0,0 +1,68 @@ +From a83f67e334054f6bebe86330a18429f713232c58 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +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 + +[ 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 +Reported-by: Valentijn Sessink +Cc: YOSHIFUJI Hideaki +Signed-off-by: Hannes Frederic Sowa +Reviewed-by: Eric Dumazet +Tested-by: Valentijn Sessink +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..6f41dbb11cd --- /dev/null +++ b/queue-3.11/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch @@ -0,0 +1,54 @@ +From 62d011151c62956411e15fb6b1ba7b46e55f23d9 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Thu, 24 Oct 2013 10:14:27 +0200 +Subject: ipv6: reset dst.expires value when clearing expire flag + +From: Hannes Frederic Sowa + +[ 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 +Reported-by: Valentijn Sessink +Cc: YOSHIFUJI Hideaki +Acked-by: Eric Dumazet +Tested-by: Valentijn Sessink +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..7fcc4f46170 --- /dev/null +++ b/queue-3.11/net-flow_dissector-fail-on-evil-iph-ihl.patch @@ -0,0 +1,39 @@ +From 07c0bf763fdfe84a1580098d8ddc3f5ce485edd7 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 1 Nov 2013 15:01:10 +0800 +Subject: net: flow_dissector: fail on evil iph->ihl + +From: Jason Wang + +[ 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 +Cc: Eric Dumazet +Cc: Petr Matousek +Cc: Michael S. Tsirkin +Cc: Daniel Borkmann +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1fc232234ad --- /dev/null +++ b/queue-3.11/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch @@ -0,0 +1,31 @@ +From 7e771ab8165cc09657994d01ef1d2b1f62d6c2c2 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Sun, 3 Nov 2013 10:04:07 +0200 +Subject: net/mlx4_core: Fix call to __mlx4_unregister_mac + +From: Jack Morgenstein + +[ 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 +Signed-off-by: Or Gerlitz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..d2000b65bae --- /dev/null +++ b/queue-3.11/net-sctp-do-not-trigger-bug_on-in-sctp_cmd_delete_tcb.patch @@ -0,0 +1,51 @@ +From 4de3b2820b148893b9b901368eeae1c34d739a17 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +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 + +[ 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 +Signed-off-by: Vlad Yasevich +Signed-off-by: Daniel Borkmann +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..3753d5abd11 --- /dev/null +++ b/queue-3.11/series @@ -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 index 00000000000..5f0312033a0 --- /dev/null +++ b/queue-3.11/tcp-gso-fix-truesize-tracking.patch @@ -0,0 +1,70 @@ +From efc59b9cd7170b6417846c13b58110989ce780f9 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 25 Oct 2013 17:26:17 -0700 +Subject: tcp: gso: fix truesize tracking + +From: Eric Dumazet + +[ 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 +Reported-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..dff099981ea --- /dev/null +++ b/queue-3.11/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch @@ -0,0 +1,116 @@ +From 5eead7070c947004877a5ff692e5b8b2a9594346 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Tue, 29 Oct 2013 15:11:07 +0800 +Subject: virtio-net: correctly handle cpu hotplug notifier during resuming + +From: Jason Wang + +[ 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] [] dump_stack+0x54/0x74 +[ 622.950815] [] __might_sleep+0x112/0x114 +[ 622.950817] [] mutex_lock_nested+0x3c/0x3c6 +[ 622.950818] [] ? up+0x39/0x3e +[ 622.950821] [] ? acpi_os_signal_semaphore+0x21/0x2d +[ 622.950824] [] ? acpi_ut_release_mutex+0x5e/0x62 +[ 622.950828] [] virtnet_cpu_callback+0x33/0x87 +[ 622.950830] [] notifier_call_chain+0x3c/0x5e +[ 622.950832] [] __raw_notifier_call_chain+0xe/0x10 +[ 622.950835] [] __cpu_notify+0x20/0x37 +[ 622.950836] [] cpu_notify+0x13/0x15 +[ 622.950838] [] take_cpu_down+0x27/0x3a +[ 622.950841] [] stop_machine_cpu_stop+0x93/0xf1 +[ 622.950842] [] cpu_stopper_thread+0xa0/0x12f +[ 622.950844] [] ? cpu_stopper_thread+0x12f/0x12f +[ 622.950847] [] ? lock_release_holdtime.part.7+0xa3/0xa8 +[ 622.950848] [] ? cpu_stop_should_run+0x3f/0x47 +[ 622.950850] [] smpboot_thread_fn+0x1c5/0x1e3 +[ 622.950852] [] ? lg_global_unlock+0x67/0x67 +[ 622.950854] [] kthread+0xd8/0xe0 +[ 622.950857] [] ? wait_for_common+0x12f/0x164 +[ 622.950859] [] ? kthread_create_on_node+0x124/0x124 +[ 622.950861] [] ret_from_fork+0x7c/0xb0 +[ 622.950862] [] ? 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 +Tested-by: Fengguang Wu +Cc: Wanlong Gao +Cc: Rusty Russell +Cc: Michael S. Tsirkin +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Reviewed-by: Wanlong Gao +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..11a092320a0 --- /dev/null +++ b/queue-3.11/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch @@ -0,0 +1,248 @@ +From 1d32297a972723d03b8e40ac76885d239c9278f7 Mon Sep 17 00:00:00 2001 +From: Paul Durrant +Date: Thu, 26 Sep 2013 12:09:52 +0100 +Subject: xen-netback: Handle backend state transitions in a more robust way + +From: Paul Durrant + +[ 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 +Cc: Ian Campbell +Cc: Wei Liu +Cc: David Vrabel +Acked-by: Ian Campbell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..692ac321975 --- /dev/null +++ b/queue-3.11/xen-netback-transition-to-closed-when-removing-a-vif.patch @@ -0,0 +1,50 @@ +From 9ea965b3b3831664f46d7927eb967e2d016be7c4 Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Mon, 7 Oct 2013 13:55:19 +0100 +Subject: xen-netback: transition to CLOSED when removing a VIF + +From: David Vrabel + +[ 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 +Cc: Ian Campbell +Cc: Wei Liu +Cc: Paul Durrant +Acked-by: Wei Liu +Reviewed-by: Paul Durrant +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..5c9e19e210c --- /dev/null +++ b/queue-3.11/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch @@ -0,0 +1,87 @@ +From 4efd8a100d07f1b42f001fdd20315059b6aac0d1 Mon Sep 17 00:00:00 2001 +From: Wei Liu +Date: Mon, 28 Oct 2013 12:07:57 +0000 +Subject: xen-netback: use jiffies_64 value to calculate credit timeout + +From: Wei Liu + +[ 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 +Signed-off-by: Wei Liu +Reviewed-by: David Vrabel +Cc: Ian Campbell +Cc: Jason Luan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; + }