From 22aba2cc7966130fb40123ceb705bfd99233dbea Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2013 12:35:08 -0700 Subject: [PATCH] 3.9-stable patches added patches: fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch timekeeping-correct-run-time-detection-of-persistent_clock.patch xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch --- ..._machine-being-stuck-in-__do_softirq.patch | 130 ++++++++++++++++++ queue-3.9/series | 6 +- ...n-time-detection-of-persistent_clock.patch | 62 +++++++++ ...10_5052-fix-chars_in_buffer-overhead.patch | 89 ------------ ...are-buffer-status-in-chars_in_buffer.patch | 46 ------- ..._3410_5052-remove-lsr-from-port-data.patch | 79 ----------- ...pu-data-when-onlining-an-offline-cpu.patch | 82 +++++++++++ 7 files changed, 277 insertions(+), 217 deletions(-) create mode 100644 queue-3.9/fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch create mode 100644 queue-3.9/timekeeping-correct-run-time-detection-of-persistent_clock.patch delete mode 100644 queue-3.9/usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch delete mode 100644 queue-3.9/usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch delete mode 100644 queue-3.9/usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch create mode 100644 queue-3.9/xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch diff --git a/queue-3.9/fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch b/queue-3.9/fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch new file mode 100644 index 00000000000..af2443affd2 --- /dev/null +++ b/queue-3.9/fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch @@ -0,0 +1,130 @@ +From 34376a50fb1fa095b9d0636fa41ed2e73125f214 Mon Sep 17 00:00:00 2001 +From: Ben Greear +Date: Thu, 6 Jun 2013 14:29:49 -0700 +Subject: Fix lockup related to stop_machine being stuck in __do_softirq. + +From: Ben Greear + +commit 34376a50fb1fa095b9d0636fa41ed2e73125f214 upstream. + +The stop machine logic can lock up if all but one of the migration +threads make it through the disable-irq step and the one remaining +thread gets stuck in __do_softirq. The reason __do_softirq can hang is +that it has a bail-out based on jiffies timeout, but in the lockup case, +jiffies itself is not incremented. + +To work around this, re-add the max_restart counter in __do_irq and stop +processing irqs after 10 restarts. + +Thanks to Tejun Heo and Rusty Russell and others for helping me track +this down. + +This was introduced in 3.9 by commit c10d73671ad3 ("softirq: reduce +latencies"). + +It may be worth looking into ath9k to see if it has issues with its irq +handler at a later date. + +The hang stack traces look something like this: + + ------------[ cut here ]------------ + WARNING: at kernel/watchdog.c:245 watchdog_overflow_callback+0x9c/0xa7() + Watchdog detected hard LOCKUP on cpu 2 + Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 nfsv4 auth_rpcgss nfs fscache nf_nat_ipv4 nf_nat veth 8021q garp stp mrp llc pktgen lockd sunrpc] + Pid: 23, comm: migration/2 Tainted: G C 3.9.4+ #11 + Call Trace: + warn_slowpath_common+0x85/0x9f + warn_slowpath_fmt+0x46/0x48 + watchdog_overflow_callback+0x9c/0xa7 + __perf_event_overflow+0x137/0x1cb + perf_event_overflow+0x14/0x16 + intel_pmu_handle_irq+0x2dc/0x359 + perf_event_nmi_handler+0x19/0x1b + nmi_handle+0x7f/0xc2 + do_nmi+0xbc/0x304 + end_repeat_nmi+0x1e/0x2e + <> + cpu_stopper_thread+0xae/0x162 + smpboot_thread_fn+0x258/0x260 + kthread+0xc7/0xcf + ret_from_fork+0x7c/0xb0 + ---[ end trace 4947dfa9b0a4cec3 ]--- + BUG: soft lockup - CPU#1 stuck for 22s! [migration/1:17] + Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 nfsv4 auth_rpcgss nfs fscache nf_nat_ipv4 nf_nat veth 8021q garp stp mrp llc pktgen lockd sunrpc] + irq event stamp: 835637905 + hardirqs last enabled at (835637904): __do_softirq+0x9f/0x257 + hardirqs last disabled at (835637905): apic_timer_interrupt+0x6d/0x80 + softirqs last enabled at (5654720): __do_softirq+0x1ff/0x257 + softirqs last disabled at (5654725): irq_exit+0x5f/0xbb + CPU 1 + Pid: 17, comm: migration/1 Tainted: G WC 3.9.4+ #11 To be filled by O.E.M. To be filled by O.E.M./To be filled by O.E.M. + RIP: tasklet_hi_action+0xf0/0xf0 + Process migration/1 + Call Trace: + + __do_softirq+0x117/0x257 + irq_exit+0x5f/0xbb + smp_apic_timer_interrupt+0x8a/0x98 + apic_timer_interrupt+0x72/0x80 + + printk+0x4d/0x4f + stop_machine_cpu_stop+0x22c/0x274 + cpu_stopper_thread+0xae/0x162 + smpboot_thread_fn+0x258/0x260 + kthread+0xc7/0xcf + ret_from_fork+0x7c/0xb0 + +Signed-off-by: Ben Greear +Acked-by: Tejun Heo +Acked-by: Pekka Riikonen +Cc: Eric Dumazet +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/softirq.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip + EXPORT_SYMBOL(local_bh_enable_ip); + + /* +- * We restart softirq processing for at most 2 ms, +- * and if need_resched() is not set. ++ * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times, ++ * but break the loop if need_resched() is set or after 2 ms. ++ * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in ++ * certain cases, such as stop_machine(), jiffies may cease to ++ * increment and so we need the MAX_SOFTIRQ_RESTART limit as ++ * well to make sure we eventually return from this method. + * + * These limits have been established via experimentation. + * The two things to balance is latency against fairness - +@@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip); + * should not be able to lock up the box. + */ + #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) ++#define MAX_SOFTIRQ_RESTART 10 + + asmlinkage void __do_softirq(void) + { +@@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void) + unsigned long end = jiffies + MAX_SOFTIRQ_TIME; + int cpu; + unsigned long old_flags = current->flags; ++ int max_restart = MAX_SOFTIRQ_RESTART; + + /* + * Mask out PF_MEMALLOC s current task context is borrowed for the +@@ -265,7 +271,8 @@ restart: + + pending = local_softirq_pending(); + if (pending) { +- if (time_before(jiffies, end) && !need_resched()) ++ if (time_before(jiffies, end) && !need_resched() && ++ --max_restart) + goto restart; + + wakeup_softirqd(); diff --git a/queue-3.9/series b/queue-3.9/series index ee94585868f..2a9a2107478 100644 --- a/queue-3.9/series +++ b/queue-3.9/series @@ -73,7 +73,7 @@ usb-serial-add-generic-wait_until_sent-implementation.patch usb-ftdi_sio-clean-up-get_modem_status.patch usb-ftdi_sio-fix-chars_in_buffer-overhead.patch usb-io_ti-fix-chars_in_buffer-overhead.patch -usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch -usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch -usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch +fix-lockup-related-to-stop_machine-being-stuck-in-__do_softirq.patch +xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch +timekeeping-correct-run-time-detection-of-persistent_clock.patch s390-add-pgste-to-ptep_modify_prot_start.patch diff --git a/queue-3.9/timekeeping-correct-run-time-detection-of-persistent_clock.patch b/queue-3.9/timekeeping-correct-run-time-detection-of-persistent_clock.patch new file mode 100644 index 00000000000..7719a16551a --- /dev/null +++ b/queue-3.9/timekeeping-correct-run-time-detection-of-persistent_clock.patch @@ -0,0 +1,62 @@ +From 0d6bd9953f739dad96d9a0de65383e479ab4e10d Mon Sep 17 00:00:00 2001 +From: Zoran Markovic +Date: Fri, 17 May 2013 11:24:05 -0700 +Subject: timekeeping: Correct run-time detection of persistent_clock. + +From: Zoran Markovic + +commit 0d6bd9953f739dad96d9a0de65383e479ab4e10d upstream. + +Since commit 31ade30692dc9680bfc95700d794818fa3f754ac, timekeeping_init() +checks for presence of persistent clock by attempting to read a non-zero +time value. This is an issue on platforms where persistent_clock (instead +is implemented as a free-running counter (instead of an RTC) starting +from zero on each boot and running during suspend. Examples are some ARM +platforms (e.g. PandaBoard). + +An attempt to read such a clock during timekeeping_init() may return zero +value and falsely declare persistent clock as missing. Additionally, in +the above case suspend times may be accounted twice (once from +timekeeping_resume() and once from rtc_resume()), resulting in a gradual +drift of system time. + +This patch does a run-time correction of the issue by doing the same check +during timekeeping_suspend(). + +A better long-term solution would have to return error when trying to read +non-existing clock and zero when trying to read an uninitialized clock, but +that would require changing all persistent_clock implementations. + +This patch addresses the immediate breakage, for now. + +Signed-off-by: Zoran Markovic +Cc: John Stultz +Cc: Thomas Gleixner +Cc: Feng Tang +[jstultz: Tweaked commit message and subject] +Signed-off-by: John Stultz +[zoran.markovic@linaro.org: reworked patch to fit 3.9-stable.] +Signed-off-by: Zoran Markovic +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -826,6 +826,14 @@ static int timekeeping_suspend(void) + + read_persistent_clock(&timekeeping_suspend_time); + ++ /* ++ * On some systems the persistent_clock can not be detected at ++ * timekeeping_init by its return value, so if we see a valid ++ * value returned, update the persistent_clock_exists flag. ++ */ ++ if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec) ++ persistent_clock_exist = true; ++ + write_seqlock_irqsave(&tk->lock, flags); + timekeeping_forward_now(tk); + timekeeping_suspended = 1; diff --git a/queue-3.9/usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch b/queue-3.9/usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch deleted file mode 100644 index 592c58f3955..00000000000 --- a/queue-3.9/usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch +++ /dev/null @@ -1,89 +0,0 @@ -From ff93b19eed0d5c124ee7168650a8e2e120ac8ea4 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Sun, 5 May 2013 20:32:32 +0200 -Subject: USB: ti_usb_3410_5052: fix chars_in_buffer overhead - -From: Johan Hovold - -commit ff93b19eed0d5c124ee7168650a8e2e120ac8ea4 upstream. - -Use the new generic usb-serial wait_until_sent implementation to wait -for hardware buffers to drain. - -This removes the need to check the hardware buffers in chars_in_buffer -and thus removes the overhead introduced by commit 2c992cd73 ("USB: -ti_usb_3410_5052: query hardware-buffer status in chars_in_buffer") -without breaking tty_wait_until_sent (used by, for example, tcdrain, -tcsendbreak and close). - -Signed-off-by: Johan Hovold -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/usb/serial/ti_usb_3410_5052.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - ---- a/drivers/usb/serial/ti_usb_3410_5052.c -+++ b/drivers/usb/serial/ti_usb_3410_5052.c -@@ -103,6 +103,7 @@ static int ti_write(struct tty_struct *t - const unsigned char *data, int count); - static int ti_write_room(struct tty_struct *tty); - static int ti_chars_in_buffer(struct tty_struct *tty); -+static bool ti_tx_empty(struct usb_serial_port *port); - static void ti_throttle(struct tty_struct *tty); - static void ti_unthrottle(struct tty_struct *tty); - static int ti_ioctl(struct tty_struct *tty, -@@ -228,6 +229,7 @@ static struct usb_serial_driver ti_1port - .write = ti_write, - .write_room = ti_write_room, - .chars_in_buffer = ti_chars_in_buffer, -+ .tx_empty = ti_tx_empty, - .throttle = ti_throttle, - .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, -@@ -258,6 +260,7 @@ static struct usb_serial_driver ti_2port - .write = ti_write, - .write_room = ti_write_room, - .chars_in_buffer = ti_chars_in_buffer, -+ .tx_empty = ti_tx_empty, - .throttle = ti_throttle, - .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, -@@ -686,8 +689,6 @@ static int ti_chars_in_buffer(struct tty - struct ti_port *tport = usb_get_serial_port_data(port); - int chars = 0; - unsigned long flags; -- int ret; -- u8 lsr; - - if (tport == NULL) - return 0; -@@ -696,16 +697,22 @@ static int ti_chars_in_buffer(struct tty - chars = kfifo_len(&tport->write_fifo); - spin_unlock_irqrestore(&tport->tp_lock, flags); - -- if (!chars) { -- ret = ti_get_lsr(tport, &lsr); -- if (!ret && !(lsr & TI_LSR_TX_EMPTY)) -- chars = 1; -- } -- - dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); - return chars; - } - -+static bool ti_tx_empty(struct usb_serial_port *port) -+{ -+ struct ti_port *tport = usb_get_serial_port_data(port); -+ int ret; -+ u8 lsr; -+ -+ ret = ti_get_lsr(tport, &lsr); -+ if (!ret && !(lsr & TI_LSR_TX_EMPTY)) -+ return false; -+ -+ return true; -+} - - static void ti_throttle(struct tty_struct *tty) - { diff --git a/queue-3.9/usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch b/queue-3.9/usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch deleted file mode 100644 index 1bf8e6c0dbf..00000000000 --- a/queue-3.9/usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2c992cd73772bd0ef107536e8e3399d28493caa8 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Thu, 18 Apr 2013 17:33:21 +0200 -Subject: USB: ti_usb_3410_5052: query hardware-buffer status in chars_in_buffer - -From: Johan Hovold - -commit 2c992cd73772bd0ef107536e8e3399d28493caa8 upstream. - -Query hardware-buffer status in chars_in_buffer should the write fifo be -empty. - -This is needed to make the tty layer wait for hardware buffers to drain -on close. - -Signed-off-by: Johan Hovold -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/usb/serial/ti_usb_3410_5052.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/usb/serial/ti_usb_3410_5052.c -+++ b/drivers/usb/serial/ti_usb_3410_5052.c -@@ -686,6 +686,8 @@ static int ti_chars_in_buffer(struct tty - struct ti_port *tport = usb_get_serial_port_data(port); - int chars = 0; - unsigned long flags; -+ int ret; -+ u8 lsr; - - if (tport == NULL) - return 0; -@@ -694,6 +696,12 @@ static int ti_chars_in_buffer(struct tty - chars = kfifo_len(&tport->write_fifo); - spin_unlock_irqrestore(&tport->tp_lock, flags); - -+ if (!chars) { -+ ret = ti_get_lsr(tport, &lsr); -+ if (!ret && !(lsr & TI_LSR_TX_EMPTY)) -+ chars = 1; -+ } -+ - dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); - return chars; - } diff --git a/queue-3.9/usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch b/queue-3.9/usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch deleted file mode 100644 index 925b13658db..00000000000 --- a/queue-3.9/usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch +++ /dev/null @@ -1,79 +0,0 @@ -From b5784f7d8528926d69c5868f1ddb2af99f85e799 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Thu, 18 Apr 2013 17:33:20 +0200 -Subject: USB: ti_usb_3410_5052: remove lsr from port data - -From: Johan Hovold - -commit b5784f7d8528926d69c5868f1ddb2af99f85e799 upstream. - -The line status register is only polled so let's not keep a possibly -outdated value in the port data. - -Signed-off-by: Johan Hovold -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/usb/serial/ti_usb_3410_5052.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/usb/serial/ti_usb_3410_5052.c -+++ b/drivers/usb/serial/ti_usb_3410_5052.c -@@ -67,7 +67,6 @@ - struct ti_port { - int tp_is_open; - __u8 tp_msr; -- __u8 tp_lsr; - __u8 tp_shadow_mcr; - __u8 tp_uart_mode; /* 232 or 485 modes */ - unsigned int tp_uart_base_addr; -@@ -124,7 +123,7 @@ static void ti_recv(struct usb_serial_po - int length); - static void ti_send(struct ti_port *tport); - static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); --static int ti_get_lsr(struct ti_port *tport); -+static int ti_get_lsr(struct ti_port *tport, u8 *lsr); - static int ti_get_serial_info(struct ti_port *tport, - struct serial_struct __user *ret_arg); - static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, -@@ -1300,7 +1299,7 @@ static int ti_set_mcr(struct ti_port *tp - } - - --static int ti_get_lsr(struct ti_port *tport) -+static int ti_get_lsr(struct ti_port *tport, u8 *lsr) - { - int size, status; - struct ti_device *tdev = tport->tp_tdev; -@@ -1326,7 +1325,7 @@ static int ti_get_lsr(struct ti_port *tp - - dev_dbg(&port->dev, "%s - lsr 0x%02X\n", __func__, data->bLSR); - -- tport->tp_lsr = data->bLSR; -+ *lsr = data->bLSR; - - free_data: - kfree(data); -@@ -1419,6 +1418,7 @@ static void ti_drain(struct ti_port *tpo - struct ti_device *tdev = tport->tp_tdev; - struct usb_serial_port *port = tport->tp_port; - wait_queue_t wait; -+ u8 lsr; - - spin_lock_irq(&tport->tp_lock); - -@@ -1450,11 +1450,11 @@ static void ti_drain(struct ti_port *tpo - /* wait for data to drain from the device */ - /* wait for empty tx register, plus 20 ms */ - timeout += jiffies; -- tport->tp_lsr &= ~TI_LSR_TX_EMPTY; -+ lsr = 0; - while ((long)(jiffies - timeout) < 0 && !signal_pending(current) -- && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error -+ && !(lsr & TI_LSR_TX_EMPTY) && !tdev->td_urb_error - && !port->serial->disconnected) { -- if (ti_get_lsr(tport)) -+ if (ti_get_lsr(tport, &lsr)) - break; - mutex_unlock(&port->serial->disc_mutex); - msleep_interruptible(20); diff --git a/queue-3.9/xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch b/queue-3.9/xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch new file mode 100644 index 00000000000..d818e2bde44 --- /dev/null +++ b/queue-3.9/xen-smp-fixup-nohz-per-cpu-data-when-onlining-an-offline-cpu.patch @@ -0,0 +1,82 @@ +From 466318a87f28cb3ba0d08a3b7ef1a37ae73d5aa7 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Mon, 3 Jun 2013 10:33:55 -0400 +Subject: xen/smp: Fixup NOHZ per cpu data when onlining an offline CPU. + +From: Konrad Rzeszutek Wilk + +commit 466318a87f28cb3ba0d08a3b7ef1a37ae73d5aa7 upstream. + +The xen_play_dead is an undead function. When the vCPU is told to +offline it ends up calling xen_play_dead wherin it calls the +VCPUOP_down hypercall which offlines the vCPU. However, when the +vCPU is onlined back, it resumes execution right after +VCPUOP_down hypercall. + +That was OK (albeit the API for play_dead assumes that the CPU +stays dead and never returns) but with commit 4b0c0f294 +(tick: Cleanup NOHZ per cpu data on cpu down) that is no longer safe +as said commit resets the ts->inidle which at the start of the +cpu_idle loop was set. + +The net effect is that we get this warn: + +Broke affinity for irq 16 +installing Xen timer for CPU 1 +cpu 1 spinlock event irq 48 +------------[ cut here ]------------ +WARNING: at /home/konrad/linux-linus/kernel/time/tick-sched.c:935 tick_nohz_idle_exit+0x195/0x1b0() +Modules linked in: dm_multipath dm_mod xen_evtchn iscsi_boot_sysfs +CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.10.0-rc3upstream-00068-gdcdbe33 #1 +Hardware name: BIOSTAR Group N61PB-M2S/N61PB-M2S, BIOS 6.00 PG 09/03/2009 + ffffffff8193b448 ffff880039da5e60 ffffffff816707c8 ffff880039da5ea0 + ffffffff8108ce8b ffff880039da4010 ffff88003fa8e500 ffff880039da4010 + 0000000000000001 ffff880039da4000 ffff880039da4010 ffff880039da5eb0 +Call Trace: + [] dump_stack+0x19/0x1b + [] warn_slowpath_common+0x6b/0xa0 + [] warn_slowpath_null+0x15/0x20 + [] tick_nohz_idle_exit+0x195/0x1b0 + [] cpu_startup_entry+0x205/0x250 + [] cpu_bringup_and_idle+0x13/0x15 +---[ end trace 915c8c486004dda1 ]--- + +b/c ts_inidle is set to zero. Thomas suggested that we just add a workaround +to call tick_nohz_idle_enter before returning from xen_play_dead() - and +that is what this patch does and fixes the issue. + +We also add the stable part b/c git commit 4b0c0f294 is on the stable +tree. + +Suggested-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Konrad Rzeszutek Wilk + +--- + arch/x86/xen/smp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -436,6 +437,13 @@ static void __cpuinit xen_play_dead(void + play_dead_common(); + HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); + cpu_bringup(); ++ /* ++ * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down) ++ * clears certain data that the cpu_idle loop (which called us ++ * and that we return from) expects. The only way to get that ++ * data back is to call: ++ */ ++ tick_nohz_idle_enter(); + } + + #else /* !CONFIG_HOTPLUG_CPU */ -- 2.47.3