patches-3.10.9-rt5.tar.xz

md5sum:
847490ddf45287f2c8607188d4c54ee0  ../patches-3.10.9-rt5.tar.xz

Announce:
 ---------------
 Dear RT folks!

 I'm pleased to announce the v3.10.9-rt5 patch set.

 Changes since v3.10.9-rt4
 - swait fixes from Steven. It fixed the issues with CONFIG_RCU_NOCB_CPU
   where the system suddenly froze and RCU wasn't doing its job anymore
 - hwlat improvements by Steven

 Known issues:

       - SLAB support not working

       - The cpsw network driver shows some issues.

       - bcache does not compile.

       - set_affinity callbacks result in splat due to sleeping while
         atomic

       - an ancient race (since we got sleeping spinlocks) where the
         TASK_TRACED state is temporary replaced while waiting on a rw
         lock and the task can't be traced.

 The delta patch against v3.10.9-rt4 is appended below and can be found
 here:
   https://www.kernel.org/pub/linux/kernel/projects/rt/3.10/incr/patch-3.10.9-rt4-rt5.patch.xz

 The RT patch against 3.10.9 can be found here:

   https://www.kernel.org/pub/linux/kernel/projects/rt/3.10/patch-3.10.9-rt5.patch.xz

 The split quilt queue is available at:

   https://www.kernel.org/pub/linux/kernel/projects/rt/3.10/patches-3.10.9-rt5.tar.xz

 Sebastian

 [delta diff snipped]
 ---------------

http://marc.info/?l=linux-rt-users&m=137719569422440&w=2

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/patches/arm-disable-highmem-on-rt.patch b/patches/arm-disable-highmem-on-rt.patch
index cbfd519..fff3eb0 100644
--- a/patches/arm-disable-highmem-on-rt.patch
+++ b/patches/arm-disable-highmem-on-rt.patch
@@ -9,7 +9,7 @@
 
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
-@@ -1704,7 +1704,7 @@ config HAVE_ARCH_PFN_VALID
+@@ -1705,7 +1705,7 @@ config HAVE_ARCH_PFN_VALID
  
  config HIGHMEM
  	bool "High Memory Support"
diff --git a/patches/arm-enable-highmem-for-rt.patch b/patches/arm-enable-highmem-for-rt.patch
index ed94171..f481778 100644
--- a/patches/arm-enable-highmem-for-rt.patch
+++ b/patches/arm-enable-highmem-for-rt.patch
@@ -12,7 +12,7 @@
 
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
-@@ -1704,7 +1704,7 @@ config HAVE_ARCH_PFN_VALID
+@@ -1705,7 +1705,7 @@ config HAVE_ARCH_PFN_VALID
  
  config HIGHMEM
  	bool "High Memory Support"
diff --git a/patches/arm-preempt-lazy-support.patch b/patches/arm-preempt-lazy-support.patch
index 864b36e..df191b1 100644
--- a/patches/arm-preempt-lazy-support.patch
+++ b/patches/arm-preempt-lazy-support.patch
@@ -13,7 +13,7 @@
 
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
-@@ -47,6 +47,7 @@ config ARM
+@@ -48,6 +48,7 @@ config ARM
  	select HAVE_MEMBLOCK
  	select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
  	select HAVE_PERF_EVENTS
diff --git a/patches/cond-resched-lock-rt-tweak.patch b/patches/cond-resched-lock-rt-tweak.patch
index bd6a153..62604a1 100644
--- a/patches/cond-resched-lock-rt-tweak.patch
+++ b/patches/cond-resched-lock-rt-tweak.patch
@@ -9,7 +9,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -2486,7 +2486,7 @@ extern int _cond_resched(void);
+@@ -2487,7 +2487,7 @@ extern int _cond_resched(void);
  
  extern int __cond_resched_lock(spinlock_t *lock);
  
diff --git a/patches/cond-resched-softirq-rt.patch b/patches/cond-resched-softirq-rt.patch
index c2b8f90..439ce2f 100644
--- a/patches/cond-resched-softirq-rt.patch
+++ b/patches/cond-resched-softirq-rt.patch
@@ -10,7 +10,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -2497,12 +2497,16 @@ extern int __cond_resched_lock(spinlock_
+@@ -2498,12 +2498,16 @@ extern int __cond_resched_lock(spinlock_
  	__cond_resched_lock(lock);				\
  })
  
diff --git a/patches/cpu-rt-rework-cpu-down.patch b/patches/cpu-rt-rework-cpu-down.patch
index efaf1a1..05899ac 100644
--- a/patches/cpu-rt-rework-cpu-down.patch
+++ b/patches/cpu-rt-rework-cpu-down.patch
@@ -56,7 +56,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1811,6 +1811,10 @@ extern void do_set_cpus_allowed(struct t
+@@ -1812,6 +1812,10 @@ extern void do_set_cpus_allowed(struct t
  
  extern int set_cpus_allowed_ptr(struct task_struct *p,
  				const struct cpumask *new_mask);
@@ -67,7 +67,7 @@
  #else
  static inline void do_set_cpus_allowed(struct task_struct *p,
  				      const struct cpumask *new_mask)
-@@ -1823,6 +1827,9 @@ static inline int set_cpus_allowed_ptr(s
+@@ -1824,6 +1828,9 @@ static inline int set_cpus_allowed_ptr(s
  		return -EINVAL;
  	return 0;
  }
diff --git a/patches/ftrace-migrate-disable-tracing.patch b/patches/ftrace-migrate-disable-tracing.patch
index 01a01db..3fa66a9 100644
--- a/patches/ftrace-migrate-disable-tracing.patch
+++ b/patches/ftrace-migrate-disable-tracing.patch
@@ -23,7 +23,7 @@
  #define FTRACE_MAX_EVENT						\
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
-@@ -399,7 +399,7 @@ int __trace_puts(unsigned long ip, const
+@@ -428,7 +428,7 @@ int __trace_puts(unsigned long ip, const
  
  	local_save_flags(irq_flags);
  	buffer = global_trace.trace_buffer.buffer;
@@ -32,7 +32,7 @@
  					  irq_flags, preempt_count());
  	if (!event)
  		return 0;
-@@ -1449,6 +1449,8 @@ tracing_generic_entry_update(struct trac
+@@ -1493,6 +1493,8 @@ tracing_generic_entry_update(struct trac
  		((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
  		((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
  		(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
@@ -41,7 +41,7 @@
  }
  EXPORT_SYMBOL_GPL(tracing_generic_entry_update);
  
-@@ -2352,9 +2354,10 @@ static void print_lat_help_header(struct
+@@ -2396,9 +2398,10 @@ static void print_lat_help_header(struct
  	seq_puts(m, "#                | / _----=> need-resched    \n");
  	seq_puts(m, "#                || / _---=> hardirq/softirq \n");
  	seq_puts(m, "#                ||| / _--=> preempt-depth   \n");
diff --git a/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch
new file mode 100644
index 0000000..5dbd27d
--- /dev/null
+++ b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch
@@ -0,0 +1,152 @@
+From 76666dbbdd40e963e7df84c123fc9aea4a2bcc69 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 21 Aug 2013 17:48:46 +0200
+Subject: [PATCH] genirq: do not invoke the affinity callback via a workqueue
+
+Joe Korty reported, that __irq_set_affinity_locked() schedules a
+workqueue while holding a rawlock which results in a might_sleep()
+warning.
+This patch moves the invokation into a process context so that we only
+wakeup() a process while holding the lock.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ include/linux/interrupt.h |  1 +
+ kernel/irq/manage.c       | 79 +++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 77 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index 11bdb1e..838d4bd 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -263,6 +263,7 @@ struct irq_affinity_notify {
+ 	unsigned int irq;
+ 	struct kref kref;
+ 	struct work_struct work;
++	struct list_head list;
+ 	void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
+ 	void (*release)(struct kref *ref);
+ };
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 0e34a98..5999a67 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -164,6 +164,62 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_PREEMPT_RT_FULL
++static void _irq_affinity_notify(struct irq_affinity_notify *notify);
++static struct task_struct *set_affinity_helper;
++static LIST_HEAD(affinity_list);
++static DEFINE_RAW_SPINLOCK(affinity_list_lock);
++
++static int set_affinity_thread(void *unused)
++{
++	while (1) {
++		struct irq_affinity_notify *notify;
++		int empty;
++
++		set_current_state(TASK_INTERRUPTIBLE);
++
++		raw_spin_lock_irq(&affinity_list_lock);
++		empty = list_empty(&affinity_list);
++		raw_spin_unlock_irq(&affinity_list_lock);
++
++		if (empty)
++			schedule();
++		if (kthread_should_stop())
++			break;
++		set_current_state(TASK_RUNNING);
++try_next:
++		notify = NULL;
++
++		raw_spin_lock_irq(&affinity_list_lock);
++		if (!list_empty(&affinity_list)) {
++			notify = list_first_entry(&affinity_list,
++					struct irq_affinity_notify, list);
++			list_del(&notify->list);
++		}
++		raw_spin_unlock_irq(&affinity_list_lock);
++
++		if (!notify)
++			continue;
++		_irq_affinity_notify(notify);
++		goto try_next;
++	}
++	return 0;
++}
++
++static void init_helper_thread(void)
++{
++	if (set_affinity_helper)
++		return;
++	set_affinity_helper = kthread_run(set_affinity_thread, NULL,
++			"affinity-cb");
++	WARN_ON(IS_ERR(set_affinity_helper));
++}
++#else
++
++static inline void init_helper_thread(void) { }
++
++#endif
++
+ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
+ {
+ 	struct irq_chip *chip = irq_data_get_irq_chip(data);
+@@ -182,7 +238,17 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
+ 
+ 	if (desc->affinity_notify) {
+ 		kref_get(&desc->affinity_notify->kref);
++
++#ifdef CONFIG_PREEMPT_RT_FULL
++		raw_spin_lock(&affinity_list_lock);
++		if (list_empty(&desc->affinity_notify->list))
++			list_add_tail(&affinity_list,
++					&desc->affinity_notify->list);
++		raw_spin_unlock(&affinity_list_lock);
++		wake_up_process(set_affinity_helper);
++#else
+ 		schedule_work(&desc->affinity_notify->work);
++#endif
+ 	}
+ 	irqd_set(data, IRQD_AFFINITY_SET);
+ 
+@@ -223,10 +289,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+ }
+ EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
+ 
+-static void irq_affinity_notify(struct work_struct *work)
++static void _irq_affinity_notify(struct irq_affinity_notify *notify)
+ {
+-	struct irq_affinity_notify *notify =
+-		container_of(work, struct irq_affinity_notify, work);
+ 	struct irq_desc *desc = irq_to_desc(notify->irq);
+ 	cpumask_var_t cpumask;
+ 	unsigned long flags;
+@@ -248,6 +312,13 @@ static void irq_affinity_notify(struct work_struct *work)
+ 	kref_put(&notify->kref, notify->release);
+ }
+ 
++static void irq_affinity_notify(struct work_struct *work)
++{
++	struct irq_affinity_notify *notify =
++		container_of(work, struct irq_affinity_notify, work);
++	_irq_affinity_notify(notify);
++}
++
+ /**
+  *	irq_set_affinity_notifier - control notification of IRQ affinity changes
+  *	@irq:		Interrupt for which to enable/disable notification
+@@ -277,6 +348,8 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
+ 		notify->irq = irq;
+ 		kref_init(&notify->kref);
+ 		INIT_WORK(&notify->work, irq_affinity_notify);
++		INIT_LIST_HEAD(&notify->list);
++		init_helper_thread();
+ 	}
+ 
+ 	raw_spin_lock_irqsave(&desc->lock, flags);
+-- 
+1.8.4.rc3
+
diff --git a/patches/hwlat-detector-Update-hwlat_detector-to-add-outer-lo.patch b/patches/hwlat-detector-Update-hwlat_detector-to-add-outer-lo.patch
new file mode 100644
index 0000000..253b4dd
--- /dev/null
+++ b/patches/hwlat-detector-Update-hwlat_detector-to-add-outer-lo.patch
@@ -0,0 +1,132 @@
+From 7a036d4dfcf3f2d3247ff7f739284f4b5056bdcb Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 17:33:25 -0400
+Subject: [PATCH 1/3] hwlat-detector: Update hwlat_detector to add outer loop
+ detection
+
+The hwlat_detector reads two timestamps in a row, then reports any
+gap between those calls. The problem is, it misses everything between
+the second reading of the time stamp to the first reading of the time stamp
+in the next loop. That's were most of the time is spent, which means,
+chances are likely that it will miss all hardware latencies. This
+defeats the purpose.
+
+By also testing the first time stamp from the previous loop second
+time stamp (the outer loop), we are more likely to find a latency.
+
+Setting the threshold to 1, here's what the report now looks like:
+
+1347415723.0232202770	0	2
+1347415725.0234202822	0	2
+1347415727.0236202875	0	2
+1347415729.0238202928	0	2
+1347415731.0240202980	0	2
+1347415734.0243203061	0	2
+1347415736.0245203113	0	2
+1347415738.0247203166	2	0
+1347415740.0249203219	0	3
+1347415742.0251203272	0	3
+1347415743.0252203299	0	3
+1347415745.0254203351	0	2
+1347415747.0256203404	0	2
+1347415749.0258203457	0	2
+1347415751.0260203510	0	2
+1347415754.0263203589	0	2
+1347415756.0265203642	0	2
+1347415758.0267203695	0	2
+1347415760.0269203748	0	2
+1347415762.0271203801	0	2
+1347415764.0273203853	2	0
+
+There's some hardware latency that takes 2 microseconds to run.
+
+Signed-off-by: Steven Rostedt <srostedt@redhat.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/misc/hwlat_detector.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/misc/hwlat_detector.c b/drivers/misc/hwlat_detector.c
+index b7b7c90..f93b8ef 100644
+--- a/drivers/misc/hwlat_detector.c
++++ b/drivers/misc/hwlat_detector.c
+@@ -143,6 +143,7 @@ static void detector_exit(void);
+ struct sample {
+ 	u64		seqnum;		/* unique sequence */
+ 	u64		duration;	/* ktime delta */
++	u64		outer_duration;	/* ktime delta (outer loop) */
+ 	struct timespec	timestamp;	/* wall time */
+ 	unsigned long   lost;
+ };
+@@ -219,11 +220,13 @@ static struct sample *buffer_get_sample(struct sample *sample)
+  */
+ static int get_sample(void *unused)
+ {
+-	ktime_t start, t1, t2;
++	ktime_t start, t1, t2, last_t2;
+ 	s64 diff, total = 0;
+ 	u64 sample = 0;
++	u64 outer_sample = 0;
+ 	int ret = 1;
+ 
++	last_t2.tv64 = 0;
+ 	start = ktime_get(); /* start timestamp */
+ 
+ 	do {
+@@ -231,7 +234,22 @@ static int get_sample(void *unused)
+ 		t1 = ktime_get();	/* we'll look for a discontinuity */
+ 		t2 = ktime_get();
+ 
++		if (last_t2.tv64) {
++			/* Check the delta from the outer loop (t2 to next t1) */
++			diff = ktime_to_us(ktime_sub(t1, last_t2));
++			/* This shouldn't happen */
++			if (diff < 0) {
++				printk(KERN_ERR BANNER "time running backwards\n");
++				goto out;
++			}
++			if (diff > outer_sample)
++				outer_sample = diff;
++		}
++		last_t2 = t2;
++
+ 		total = ktime_to_us(ktime_sub(t2, start)); /* sample width */
++
++		/* This checks the inner loop (t1 to t2) */
+ 		diff = ktime_to_us(ktime_sub(t2, t1));     /* current diff */
+ 
+ 		/* This shouldn't happen */
+@@ -246,12 +264,13 @@ static int get_sample(void *unused)
+ 	} while (total <= data.sample_width);
+ 
+ 	/* If we exceed the threshold value, we have found a hardware latency */
+-	if (sample > data.threshold) {
++	if (sample > data.threshold || outer_sample > data.threshold) {
+ 		struct sample s;
+ 
+ 		data.count++;
+ 		s.seqnum = data.count;
+ 		s.duration = sample;
++		s.outer_duration = outer_sample;
+ 		s.timestamp = CURRENT_TIME;
+ 		__buffer_add_sample(&s);
+ 
+@@ -738,10 +757,11 @@ static ssize_t debug_sample_fread(struct file *filp, char __user *ubuf,
+ 		}
+ 	}
+ 
+-	len = snprintf(buf, sizeof(buf), "%010lu.%010lu\t%llu\n",
+-		      sample->timestamp.tv_sec,
+-		      sample->timestamp.tv_nsec,
+-		      sample->duration);
++	len = snprintf(buf, sizeof(buf), "%010lu.%010lu\t%llu\t%llu\n",
++		       sample->timestamp.tv_sec,
++		       sample->timestamp.tv_nsec,
++		       sample->duration,
++		       sample->outer_duration);
+ 
+ 
+ 	/* handling partial reads is more trouble than it's worth */
+-- 
+1.8.4.rc3
+
diff --git a/patches/hwlat-detector-Use-thread-instead-of-stop-machine.patch b/patches/hwlat-detector-Use-thread-instead-of-stop-machine.patch
new file mode 100644
index 0000000..f41beef
--- /dev/null
+++ b/patches/hwlat-detector-Use-thread-instead-of-stop-machine.patch
@@ -0,0 +1,188 @@
+From 42b3963c5d3dcdb54226fc6bbb6b5fbcf3f2ddee Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 17:33:27 -0400
+Subject: [PATCH 3/3] hwlat-detector: Use thread instead of stop machine
+
+There's no reason to use stop machine to search for hardware latency.
+Simply disabling interrupts while running the loop will do enough to
+check if something comes in that wasn't disabled by interrupts being
+off, which is exactly what stop machine does.
+
+Instead of using stop machine, just have the thread disable interrupts
+while it checks for hardware latency.
+
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/misc/hwlat_detector.c | 59 ++++++++++++++++++-------------------------
+ 1 file changed, 25 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/misc/hwlat_detector.c b/drivers/misc/hwlat_detector.c
+index d80a857..0bfa40d 100644
+--- a/drivers/misc/hwlat_detector.c
++++ b/drivers/misc/hwlat_detector.c
+@@ -41,7 +41,6 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/ring_buffer.h>
+-#include <linux/stop_machine.h>
+ #include <linux/time.h>
+ #include <linux/hrtimer.h>
+ #include <linux/kthread.h>
+@@ -107,7 +106,6 @@ struct data;					/* Global state */
+ /* Sampling functions */
+ static int __buffer_add_sample(struct sample *sample);
+ static struct sample *buffer_get_sample(struct sample *sample);
+-static int get_sample(void *unused);
+ 
+ /* Threading and state */
+ static int kthread_fn(void *unused);
+@@ -149,7 +147,7 @@ struct sample {
+ 	unsigned long   lost;
+ };
+ 
+-/* keep the global state somewhere. Mostly used under stop_machine. */
++/* keep the global state somewhere. */
+ static struct data {
+ 
+ 	struct mutex lock;		/* protect changes */
+@@ -172,7 +170,7 @@ static struct data {
+  * @sample: The new latency sample value
+  *
+  * This receives a new latency sample and records it in a global ring buffer.
+- * No additional locking is used in this case - suited for stop_machine use.
++ * No additional locking is used in this case.
+  */
+ static int __buffer_add_sample(struct sample *sample)
+ {
+@@ -229,18 +227,17 @@ static struct sample *buffer_get_sample(struct sample *sample)
+ #endif
+ /**
+  * get_sample - sample the CPU TSC and look for likely hardware latencies
+- * @unused: This is not used but is a part of the stop_machine API
+  *
+  * Used to repeatedly capture the CPU TSC (or similar), looking for potential
+- * hardware-induced latency. Called under stop_machine, with data.lock held.
++ * hardware-induced latency. Called with interrupts disabled and with data.lock held.
+  */
+-static int get_sample(void *unused)
++static int get_sample(void)
+ {
+ 	time_type start, t1, t2, last_t2;
+ 	s64 diff, total = 0;
+ 	u64 sample = 0;
+ 	u64 outer_sample = 0;
+-	int ret = 1;
++	int ret = -1;
+ 
+ 	init_time(last_t2, 0);
+ 	start = time_get(); /* start timestamp */
+@@ -279,10 +276,14 @@ static int get_sample(void *unused)
+ 
+ 	} while (total <= data.sample_width);
+ 
++	ret = 0;
++
+ 	/* If we exceed the threshold value, we have found a hardware latency */
+ 	if (sample > data.threshold || outer_sample > data.threshold) {
+ 		struct sample s;
+ 
++		ret = 1;
++
+ 		data.count++;
+ 		s.seqnum = data.count;
+ 		s.duration = sample;
+@@ -295,7 +296,6 @@ static int get_sample(void *unused)
+ 			data.max_sample = sample;
+ 	}
+ 
+-	ret = 0;
+ out:
+ 	return ret;
+ }
+@@ -305,32 +305,30 @@ static int get_sample(void *unused)
+  * @unused: A required part of the kthread API.
+  *
+  * Used to periodically sample the CPU TSC via a call to get_sample. We
+- * use stop_machine, whith does (intentionally) introduce latency since we
++ * disable interrupts, which does (intentionally) introduce latency since we
+  * need to ensure nothing else might be running (and thus pre-empting).
+  * Obviously this should never be used in production environments.
+  *
+- * stop_machine will schedule us typically only on CPU0 which is fine for
+- * almost every real-world hardware latency situation - but we might later
+- * generalize this if we find there are any actualy systems with alternate
+- * SMI delivery or other non CPU0 hardware latencies.
++ * Currently this runs on which ever CPU it was scheduled on, but most
++ * real-worald hardware latency situations occur across several CPUs,
++ * but we might later generalize this if we find there are any actualy
++ * systems with alternate SMI delivery or other hardware latencies.
+  */
+ static int kthread_fn(void *unused)
+ {
+-	int err = 0;
+-	u64 interval = 0;
++	int ret;
++	u64 interval;
+ 
+ 	while (!kthread_should_stop()) {
+ 
+ 		mutex_lock(&data.lock);
+ 
+-		err = stop_machine(get_sample, unused, 0);
+-		if (err) {
+-			/* Houston, we have a problem */
+-			mutex_unlock(&data.lock);
+-			goto err_out;
+-		}
++		local_irq_disable();
++		ret = get_sample();
++		local_irq_enable();
+ 
+-		wake_up(&data.wq); /* wake up reader(s) */
++		if (ret > 0)
++			wake_up(&data.wq); /* wake up reader(s) */
+ 
+ 		interval = data.sample_window - data.sample_width;
+ 		do_div(interval, USEC_PER_MSEC); /* modifies interval value */
+@@ -338,15 +336,10 @@ static int kthread_fn(void *unused)
+ 		mutex_unlock(&data.lock);
+ 
+ 		if (msleep_interruptible(interval))
+-			goto out;
++			break;
+ 	}
+-		goto out;
+-err_out:
+-	printk(KERN_ERR BANNER "could not call stop_machine, disabling\n");
+-	enabled = 0;
+-out:
+-	return err;
+ 
++	return 0;
+ }
+ 
+ /**
+@@ -442,8 +435,7 @@ static int init_stats(void)
+  * This function provides a generic read implementation for the global state
+  * "data" structure debugfs filesystem entries. It would be nice to use
+  * simple_attr_read directly, but we need to make sure that the data.lock
+- * spinlock is held during the actual read (even though we likely won't ever
+- * actually race here as the updater runs under a stop_machine context).
++ * is held during the actual read.
+  */
+ static ssize_t simple_data_read(struct file *filp, char __user *ubuf,
+ 				size_t cnt, loff_t *ppos, const u64 *entry)
+@@ -478,8 +470,7 @@ static ssize_t simple_data_read(struct file *filp, char __user *ubuf,
+  * This function provides a generic write implementation for the global state
+  * "data" structure debugfs filesystem entries. It would be nice to use
+  * simple_attr_write directly, but we need to make sure that the data.lock
+- * spinlock is held during the actual write (even though we likely won't ever
+- * actually race here as the updater runs under a stop_machine context).
++ * is held during the actual write.
+  */
+ static ssize_t simple_data_write(struct file *filp, const char __user *ubuf,
+ 				 size_t cnt, loff_t *ppos, u64 *entry)
+-- 
+1.8.4.rc3
+
diff --git a/patches/hwlat-detector-Use-trace_clock_local-if-available.patch b/patches/hwlat-detector-Use-trace_clock_local-if-available.patch
new file mode 100644
index 0000000..9d7d327
--- /dev/null
+++ b/patches/hwlat-detector-Use-trace_clock_local-if-available.patch
@@ -0,0 +1,98 @@
+From 4aaca90c0255caee9a55371afaecb32365123762 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 17:33:26 -0400
+Subject: [PATCH 2/3] hwlat-detector: Use trace_clock_local if available
+
+As ktime_get() calls into the timing code which does a read_seq(), it
+may be affected by other CPUS that touch that lock. To remove this
+dependency, use the trace_clock_local() which is already exported
+for module use. If CONFIG_TRACING is enabled, use that as the clock,
+otherwise use ktime_get().
+
+Signed-off-by: Steven Rostedt <srostedt@redhat.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/misc/hwlat_detector.c | 34 +++++++++++++++++++++++++---------
+ 1 file changed, 25 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/misc/hwlat_detector.c b/drivers/misc/hwlat_detector.c
+index f93b8ef..d80a857 100644
+--- a/drivers/misc/hwlat_detector.c
++++ b/drivers/misc/hwlat_detector.c
+@@ -51,6 +51,7 @@
+ #include <linux/version.h>
+ #include <linux/delay.h>
+ #include <linux/slab.h>
++#include <linux/trace_clock.h>
+ 
+ #define BUF_SIZE_DEFAULT	262144UL		/* 8K*(sizeof(entry)) */
+ #define BUF_FLAGS		(RB_FL_OVERWRITE)	/* no block on full */
+@@ -211,6 +212,21 @@ static struct sample *buffer_get_sample(struct sample *sample)
+ 	return sample;
+ }
+ 
++#ifndef CONFIG_TRACING
++#define time_type	ktime_t
++#define time_get()	ktime_get()
++#define time_to_us(x)	ktime_to_us(x)
++#define time_sub(a, b)	ktime_sub(a, b)
++#define init_time(a, b)	(a).tv64 = b
++#define time_u64(a)	(a).tv64
++#else
++#define time_type	u64
++#define time_get()	trace_clock_local()
++#define time_to_us(x)	((x) / 1000)
++#define time_sub(a, b)	((a) - (b))
++#define init_time(a, b)	a = b
++#define time_u64(a)	a
++#endif
+ /**
+  * get_sample - sample the CPU TSC and look for likely hardware latencies
+  * @unused: This is not used but is a part of the stop_machine API
+@@ -220,23 +236,23 @@ static struct sample *buffer_get_sample(struct sample *sample)
+  */
+ static int get_sample(void *unused)
+ {
+-	ktime_t start, t1, t2, last_t2;
++	time_type start, t1, t2, last_t2;
+ 	s64 diff, total = 0;
+ 	u64 sample = 0;
+ 	u64 outer_sample = 0;
+ 	int ret = 1;
+ 
+-	last_t2.tv64 = 0;
+-	start = ktime_get(); /* start timestamp */
++	init_time(last_t2, 0);
++	start = time_get(); /* start timestamp */
+ 
+ 	do {
+ 
+-		t1 = ktime_get();	/* we'll look for a discontinuity */
+-		t2 = ktime_get();
++		t1 = time_get();	/* we'll look for a discontinuity */
++		t2 = time_get();
+ 
+-		if (last_t2.tv64) {
++		if (time_u64(last_t2)) {
+ 			/* Check the delta from the outer loop (t2 to next t1) */
+-			diff = ktime_to_us(ktime_sub(t1, last_t2));
++			diff = time_to_us(time_sub(t1, last_t2));
+ 			/* This shouldn't happen */
+ 			if (diff < 0) {
+ 				printk(KERN_ERR BANNER "time running backwards\n");
+@@ -247,10 +263,10 @@ static int get_sample(void *unused)
+ 		}
+ 		last_t2 = t2;
+ 
+-		total = ktime_to_us(ktime_sub(t2, start)); /* sample width */
++		total = time_to_us(time_sub(t2, start)); /* sample width */
+ 
+ 		/* This checks the inner loop (t1 to t2) */
+-		diff = ktime_to_us(ktime_sub(t2, t1));     /* current diff */
++		diff = time_to_us(time_sub(t2, t1));     /* current diff */
+ 
+ 		/* This shouldn't happen */
+ 		if (diff < 0) {
+-- 
+1.8.4.rc3
+
diff --git a/patches/latency-hist.patch b/patches/latency-hist.patch
index 2cc56fc..26a0b51 100644
--- a/patches/latency-hist.patch
+++ b/patches/latency-hist.patch
@@ -228,7 +228,7 @@
  	void				*start_site;
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1409,6 +1409,12 @@ struct task_struct {
+@@ -1410,6 +1410,12 @@ struct task_struct {
  	unsigned long trace;
  	/* bitmask and counter of trace recursion */
  	unsigned long trace_recursion;
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 0e1394d..e5fcadf 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -12,4 +12,4 @@
 --- /dev/null
 +++ b/localversion-rt
 @@ -0,0 +1 @@
-+-rt4
++-rt5
diff --git a/patches/mips-disable-highmem-on-rt.patch b/patches/mips-disable-highmem-on-rt.patch
index 4511ade..8f11f93 100644
--- a/patches/mips-disable-highmem-on-rt.patch
+++ b/patches/mips-disable-highmem-on-rt.patch
@@ -9,7 +9,7 @@
 
 --- a/arch/mips/Kconfig
 +++ b/arch/mips/Kconfig
-@@ -2114,7 +2114,7 @@ config CPU_R4400_WORKAROUNDS
+@@ -2115,7 +2115,7 @@ config CPU_R4400_WORKAROUNDS
  #
  config HIGHMEM
  	bool "High Memory Support"
diff --git a/patches/mm-prepare-pf-disable-discoupling.patch b/patches/mm-prepare-pf-disable-discoupling.patch
index f4c98b9..9bf7e52 100644
--- a/patches/mm-prepare-pf-disable-discoupling.patch
+++ b/patches/mm-prepare-pf-disable-discoupling.patch
@@ -17,7 +17,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1260,6 +1260,7 @@ struct task_struct {
+@@ -1261,6 +1261,7 @@ struct task_struct {
  	/* mutex deadlock detection */
  	struct mutex_waiter *blocked_on;
  #endif
@@ -80,7 +80,7 @@
  	p->curr_chain_key = 0;
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -3751,6 +3751,35 @@ unlock:
+@@ -3757,6 +3757,35 @@ unlock:
  	return 0;
  }
  
diff --git a/patches/mm-remove-preempt-count-from-pf.patch b/patches/mm-remove-preempt-count-from-pf.patch
index b7beaf7..93bf166 100644
--- a/patches/mm-remove-preempt-count-from-pf.patch
+++ b/patches/mm-remove-preempt-count-from-pf.patch
@@ -11,7 +11,7 @@
 
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -3754,7 +3754,6 @@ unlock:
+@@ -3760,7 +3760,6 @@ unlock:
  #ifdef CONFIG_PREEMPT_RT_FULL
  void pagefault_disable(void)
  {
@@ -19,7 +19,7 @@
  	current->pagefault_disabled++;
  	/*
  	 * make sure to have issued the store before a pagefault
-@@ -3772,12 +3771,6 @@ void pagefault_enable(void)
+@@ -3778,12 +3777,6 @@ void pagefault_enable(void)
  	 */
  	barrier();
  	current->pagefault_disabled--;
diff --git a/patches/mm-rt-kmap-atomic-scheduling.patch b/patches/mm-rt-kmap-atomic-scheduling.patch
index 5c467f0..e1272e6 100644
--- a/patches/mm-rt-kmap-atomic-scheduling.patch
+++ b/patches/mm-rt-kmap-atomic-scheduling.patch
@@ -215,7 +215,7 @@
  #include <asm/page.h>
  #include <asm/ptrace.h>
  #include <asm/cputime.h>
-@@ -1449,6 +1450,12 @@ struct task_struct {
+@@ -1450,6 +1451,12 @@ struct task_struct {
  	struct rcu_head put_rcu;
  	int softirq_nestcnt;
  #endif
@@ -256,7 +256,7 @@
  {
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -3754,6 +3754,7 @@ unlock:
+@@ -3760,6 +3760,7 @@ unlock:
  #ifdef CONFIG_PREEMPT_RT_FULL
  void pagefault_disable(void)
  {
@@ -264,7 +264,7 @@
  	current->pagefault_disabled++;
  	/*
  	 * make sure to have issued the store before a pagefault
-@@ -3771,6 +3772,7 @@ void pagefault_enable(void)
+@@ -3777,6 +3778,7 @@ void pagefault_enable(void)
  	 */
  	barrier();
  	current->pagefault_disabled--;
diff --git a/patches/mm-shrink-the-page-frame-to-rt-size.patch b/patches/mm-shrink-the-page-frame-to-rt-size.patch
index 7654f94..a95cbf3 100644
--- a/patches/mm-shrink-the-page-frame-to-rt-size.patch
+++ b/patches/mm-shrink-the-page-frame-to-rt-size.patch
@@ -102,7 +102,7 @@
  		struct page *first_page;	/* Compound tail pages */
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -4322,3 +4322,35 @@ void copy_user_huge_page(struct page *ds
+@@ -4328,3 +4328,35 @@ void copy_user_huge_page(struct page *ds
  	}
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
diff --git a/patches/oleg-signal-rt-fix.patch b/patches/oleg-signal-rt-fix.patch
index 271c516..a5ccd44 100644
--- a/patches/oleg-signal-rt-fix.patch
+++ b/patches/oleg-signal-rt-fix.patch
@@ -76,7 +76,7 @@
  
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1220,6 +1220,10 @@ struct task_struct {
+@@ -1221,6 +1221,10 @@ struct task_struct {
  	sigset_t blocked, real_blocked;
  	sigset_t saved_sigmask;	/* restored if set_restore_sigmask() was used */
  	struct sigpending pending;
diff --git a/patches/peter_zijlstra-frob-migrate_disable-2.patch b/patches/peter_zijlstra-frob-migrate_disable-2.patch
index 157a4fa..17f8071 100644
--- a/patches/peter_zijlstra-frob-migrate_disable-2.patch
+++ b/patches/peter_zijlstra-frob-migrate_disable-2.patch
@@ -63,7 +63,7 @@
  #ifdef CONFIG_PREEMPT_NOTIFIERS
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1074,7 +1074,9 @@ struct task_struct {
+@@ -1075,7 +1075,9 @@ struct task_struct {
  #endif
  
  	unsigned int policy;
@@ -73,7 +73,7 @@
  	int nr_cpus_allowed;
  	cpumask_t cpus_allowed;
  
-@@ -2617,11 +2619,22 @@ static inline void set_task_cpu(struct t
+@@ -2618,11 +2620,22 @@ static inline void set_task_cpu(struct t
  
  #endif /* CONFIG_SMP */
  
@@ -152,7 +152,7 @@
   * Move (not current) task off this cpu, onto dest cpu. We're doing
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
-@@ -1450,7 +1450,7 @@ tracing_generic_entry_update(struct trac
+@@ -1494,7 +1494,7 @@ tracing_generic_entry_update(struct trac
  		((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
  		(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
  
diff --git a/patches/peter_zijlstra-frob-pagefault_disable.patch b/patches/peter_zijlstra-frob-pagefault_disable.patch
index d1070a1..355a340 100644
--- a/patches/peter_zijlstra-frob-pagefault_disable.patch
+++ b/patches/peter_zijlstra-frob-pagefault_disable.patch
@@ -288,7 +288,7 @@
  
  #include <asm/processor.h>
  
-@@ -1260,7 +1261,9 @@ struct task_struct {
+@@ -1261,7 +1262,9 @@ struct task_struct {
  	/* mutex deadlock detection */
  	struct mutex_waiter *blocked_on;
  #endif
@@ -298,7 +298,7 @@
  #ifdef CONFIG_TRACE_IRQFLAGS
  	unsigned int irq_events;
  	unsigned long hardirq_enable_ip;
-@@ -1443,6 +1446,17 @@ static inline void set_numabalancing_sta
+@@ -1444,6 +1447,17 @@ static inline void set_numabalancing_sta
  }
  #endif
  
diff --git a/patches/peterz-raw_pagefault_disable.patch b/patches/peterz-raw_pagefault_disable.patch
index 0bda2da..ea4524d 100644
--- a/patches/peterz-raw_pagefault_disable.patch
+++ b/patches/peterz-raw_pagefault_disable.patch
@@ -129,7 +129,7 @@
  	})
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -3751,6 +3751,7 @@ unlock:
+@@ -3757,6 +3757,7 @@ unlock:
  	return 0;
  }
  
@@ -137,7 +137,7 @@
  void pagefault_disable(void)
  {
  	inc_preempt_count();
-@@ -3779,6 +3780,7 @@ void pagefault_enable(void)
+@@ -3785,6 +3786,7 @@ void pagefault_enable(void)
  	preempt_check_resched();
  }
  EXPORT_SYMBOL(pagefault_enable);
diff --git a/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch b/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch
index e6dc56a..77f29e9 100644
--- a/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch
+++ b/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch
@@ -43,7 +43,7 @@
  		[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),		\
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1185,6 +1185,9 @@ struct task_struct {
+@@ -1186,6 +1186,9 @@ struct task_struct {
  
  	struct task_cputime cputime_expires;
  	struct list_head cpu_timers[3];
diff --git a/patches/powerpc-52xx-provide-a-default-in-mpc52xx_irqhost_ma.patch b/patches/powerpc-52xx-provide-a-default-in-mpc52xx_irqhost_ma.patch
index 532494c..47f2878 100644
--- a/patches/powerpc-52xx-provide-a-default-in-mpc52xx_irqhost_ma.patch
+++ b/patches/powerpc-52xx-provide-a-default-in-mpc52xx_irqhost_ma.patch
@@ -21,14 +21,12 @@
 
 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 ---
- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 3 ++-
+ arch/powerpc/platforms/52xx/mpc52xx_pic.c |    3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
-diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
-index b89ef65..b69221b 100644
 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
 +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
-@@ -373,8 +373,9 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
+@@ -373,8 +373,9 @@ static int mpc52xx_irqhost_map(struct ir
  	case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
  	case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
  	case MPC52xx_IRQ_L1_CRIT:
@@ -39,6 +37,3 @@
  		irq_set_chip(virq, &no_irq_chip);
  		return 0;
  	}
--- 
-1.8.4.rc1
-
diff --git a/patches/powerpc-preempt-lazy-support.patch b/patches/powerpc-preempt-lazy-support.patch
index 32f9a8d..78b43ce 100644
--- a/patches/powerpc-preempt-lazy-support.patch
+++ b/patches/powerpc-preempt-lazy-support.patch
@@ -71,7 +71,7 @@
  /* Don't move TLF_NAPPING without adjusting the code in entry_32.S */
 --- a/arch/powerpc/kernel/asm-offsets.c
 +++ b/arch/powerpc/kernel/asm-offsets.c
-@@ -162,6 +162,7 @@ int main(void)
+@@ -165,6 +165,7 @@ int main(void)
  	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
  	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
  	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
@@ -180,7 +180,7 @@
   */
  	.align	7
  _GLOBAL(_switch)
-@@ -637,7 +637,7 @@ _GLOBAL(ret_from_except_lite)
+@@ -653,7 +653,7 @@ _GLOBAL(ret_from_except_lite)
  	andi.	r0,r4,_TIF_USER_WORK_MASK
  	beq	restore
  
@@ -189,7 +189,7 @@
  	beq	1f
  	bl	.restore_interrupts
  	SCHEDULE_USER
-@@ -687,10 +687,18 @@ resume_kernel:
+@@ -703,10 +703,18 @@ resume_kernel:
  
  #ifdef CONFIG_PREEMPT
  	/* Check if we need to preempt */
@@ -209,7 +209,7 @@
  	cmpwi	cr1,r8,0
  	ld	r0,SOFTE(r1)
  	cmpdi	r0,0
-@@ -707,7 +715,7 @@ resume_kernel:
+@@ -723,7 +731,7 @@ resume_kernel:
  	/* Re-test flags and eventually loop */
  	CURRENT_THREAD_INFO(r9, r1)
  	ld	r4,TI_FLAGS(r9)
@@ -218,7 +218,7 @@
  	bne	1b
  
  	/*
-@@ -874,7 +882,7 @@ restore_check_irq_replay:
+@@ -890,7 +898,7 @@ restore_check_irq_replay:
  	bl	.__check_irq_replay
  	cmpwi	cr0,r3,0
   	beq	restore_no_replay
@@ -227,7 +227,7 @@
  	/*
  	 * We need to re-emit an interrupt. We do so by re-using our
  	 * existing exception frame. We first change the trap value,
-@@ -916,7 +924,7 @@ restore_check_irq_replay:
+@@ -932,7 +940,7 @@ restore_check_irq_replay:
  	b	.ret_from_except
  #endif /* CONFIG_PPC_DOORBELL */
  1:	b	.ret_from_except /* What else to do here ? */
@@ -236,7 +236,7 @@
  unrecov_restore:
  	addi	r3,r1,STACK_FRAME_OVERHEAD
  	bl	.unrecoverable_exception
-@@ -928,7 +936,7 @@ unrecov_restore:
+@@ -944,7 +952,7 @@ unrecov_restore:
   * called with the MMU off.
   *
   * In addition, we need to be in 32b mode, at least for now.
@@ -245,7 +245,7 @@
   * Note: r3 is an input parameter to rtas, so don't trash it...
   */
  _GLOBAL(enter_rtas)
-@@ -962,7 +970,7 @@ _GLOBAL(enter_rtas)
+@@ -978,7 +986,7 @@ _GLOBAL(enter_rtas)
  	li	r0,0
  	mtcr	r0
  
@@ -254,7 +254,7 @@
  	/* There is no way it is acceptable to get here with interrupts enabled,
  	 * check it with the asm equivalent of WARN_ON
  	 */
-@@ -970,7 +978,7 @@ _GLOBAL(enter_rtas)
+@@ -986,7 +994,7 @@ _GLOBAL(enter_rtas)
  1:	tdnei	r0,0
  	EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
  #endif
@@ -263,7 +263,7 @@
  	/* Hard-disable interrupts */
  	mfmsr	r6
  	rldicl	r7,r6,48,1
-@@ -984,7 +992,7 @@ _GLOBAL(enter_rtas)
+@@ -1000,7 +1008,7 @@ _GLOBAL(enter_rtas)
  	std	r1,PACAR1(r13)
          std	r6,PACASAVEDMSR(r13)
  
@@ -272,7 +272,7 @@
  	LOAD_REG_ADDR(r4,.rtas_return_loc)
  	clrldi	r4,r4,2			/* convert to realmode address */
         	mtlr	r4
-@@ -992,7 +1000,7 @@ _GLOBAL(enter_rtas)
+@@ -1008,7 +1016,7 @@ _GLOBAL(enter_rtas)
  	li	r0,0
  	ori	r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
  	andc	r0,r6,r0
@@ -281,7 +281,7 @@
          li      r9,1
          rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
  	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
-@@ -1003,7 +1011,7 @@ _GLOBAL(enter_rtas)
+@@ -1019,7 +1027,7 @@ _GLOBAL(enter_rtas)
  	LOAD_REG_ADDR(r4, rtas)
  	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
  	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
@@ -290,7 +290,7 @@
  	mtspr	SPRN_SRR0,r5
  	mtspr	SPRN_SRR1,r6
  	rfid
-@@ -1021,9 +1029,9 @@ _STATIC(rtas_return_loc)
+@@ -1037,9 +1045,9 @@ _STATIC(rtas_return_loc)
  	mfmsr   r6
  	li	r0,MSR_RI
  	andc	r6,r6,r0
@@ -302,7 +302,7 @@
          ld	r1,PACAR1(r4)           /* Restore our SP */
          ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
  
-@@ -1121,7 +1129,7 @@ _GLOBAL(enter_prom)
+@@ -1137,7 +1145,7 @@ _GLOBAL(enter_prom)
  	REST_10GPRS(22, r1)
  	ld	r4,_CCR(r1)
  	mtcr	r4
diff --git a/patches/preempt-lazy-support.patch b/patches/preempt-lazy-support.patch
index 896e80d..fcf683a 100644
--- a/patches/preempt-lazy-support.patch
+++ b/patches/preempt-lazy-support.patch
@@ -146,7 +146,7 @@
  #define add_preempt_count_notrace(val)			\
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -2454,6 +2454,52 @@ static inline int test_tsk_need_resched(
+@@ -2455,6 +2455,52 @@ static inline int test_tsk_need_resched(
  	return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED));
  }
  
@@ -199,7 +199,7 @@
  static inline int restart_syscall(void)
  {
  	set_tsk_thread_flag(current, TIF_SIGPENDING);
-@@ -2485,11 +2531,6 @@ static inline int signal_pending_state(l
+@@ -2486,11 +2532,6 @@ static inline int signal_pending_state(l
  	return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p);
  }
  
@@ -364,7 +364,7 @@
  }
  
  static void
-@@ -1991,7 +1991,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc
+@@ -1992,7 +1992,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc
  	 * validating it and just reschedule.
  	 */
  	if (queued) {
@@ -373,7 +373,7 @@
  		return;
  	}
  	/*
-@@ -2180,7 +2180,7 @@ static void __account_cfs_rq_runtime(str
+@@ -2181,7 +2181,7 @@ static void __account_cfs_rq_runtime(str
  	 * hierarchy can be throttled
  	 */
  	if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr))
@@ -382,7 +382,7 @@
  }
  
  static __always_inline
-@@ -2765,7 +2765,7 @@ static void hrtick_start_fair(struct rq
+@@ -2766,7 +2766,7 @@ static void hrtick_start_fair(struct rq
  
  		if (delta < 0) {
  			if (rq->curr == p)
@@ -391,7 +391,7 @@
  			return;
  		}
  
-@@ -3590,7 +3590,7 @@ static void check_preempt_wakeup(struct
+@@ -3591,7 +3591,7 @@ static void check_preempt_wakeup(struct
  	return;
  
  preempt:
@@ -400,7 +400,7 @@
  	/*
  	 * Only set the backward buddy when the current task is still
  	 * on the rq. This can happen when a wakeup gets interleaved
-@@ -5795,7 +5795,7 @@ static void task_fork_fair(struct task_s
+@@ -5796,7 +5796,7 @@ static void task_fork_fair(struct task_s
  		 * 'current' within the tree based on its new key value.
  		 */
  		swap(curr->vruntime, se->vruntime);
@@ -409,7 +409,7 @@
  	}
  
  	se->vruntime -= cfs_rq->min_vruntime;
-@@ -5820,7 +5820,7 @@ prio_changed_fair(struct rq *rq, struct
+@@ -5821,7 +5821,7 @@ prio_changed_fair(struct rq *rq, struct
  	 */
  	if (rq->curr == p) {
  		if (p->prio > oldprio)
@@ -450,7 +450,7 @@
  
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
-@@ -1439,6 +1439,7 @@ tracing_generic_entry_update(struct trac
+@@ -1483,6 +1483,7 @@ tracing_generic_entry_update(struct trac
  	struct task_struct *tsk = current;
  
  	entry->preempt_count		= pc & 0xff;
@@ -458,7 +458,7 @@
  	entry->pid			= (tsk) ? tsk->pid : 0;
  	entry->flags =
  #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
-@@ -1448,7 +1449,8 @@ tracing_generic_entry_update(struct trac
+@@ -1492,7 +1493,8 @@ tracing_generic_entry_update(struct trac
  #endif
  		((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
  		((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
@@ -468,7 +468,7 @@
  
  	entry->migrate_disable	= (tsk) ? __migrate_disabled(tsk) & 0xFF : 0;
  }
-@@ -2349,15 +2351,17 @@ get_total_entries(struct trace_buffer *b
+@@ -2393,15 +2395,17 @@ get_total_entries(struct trace_buffer *b
  
  static void print_lat_help_header(struct seq_file *m)
  {
@@ -495,7 +495,7 @@
  }
  
  static void print_event_info(struct trace_buffer *buf, struct seq_file *m)
-@@ -2381,13 +2385,16 @@ static void print_func_help_header(struc
+@@ -2425,13 +2429,16 @@ static void print_func_help_header(struc
  static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m)
  {
  	print_event_info(buf, m);
diff --git a/patches/rcu-swait-Fix-RCU-conversion-of-wake_up_all-to-swait.patch b/patches/rcu-swait-Fix-RCU-conversion-of-wake_up_all-to-swait.patch
new file mode 100644
index 0000000..64ea078
--- /dev/null
+++ b/patches/rcu-swait-Fix-RCU-conversion-of-wake_up_all-to-swait.patch
@@ -0,0 +1,34 @@
+From 1c126aeea000d5acd67b3adb153daa43fbabb600 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 11:35:31 -0400
+Subject: [PATCH] rcu/swait: Fix RCU conversion of wake_up_all() to
+ swait_wake()
+
+Reverting the rcu swait patches fixed the boot problem. Then when I was
+looking at the revert itself, this stood out like a sore thumb.
+
+ static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) {
+-       swait_wake(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
++       wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
+ }
+
+See the problem there?
+
+Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/rcutree_plugin.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/rcutree_plugin.h
++++ b/kernel/rcutree_plugin.h
+@@ -2036,7 +2036,7 @@ static int rcu_nocb_needs_gp(struct rcu_
+  */
+ static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
+ {
+-	swait_wake(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
++	swait_wake_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
+ }
+ 
+ /*
diff --git a/patches/sched-better-debug-output-for-might-sleep.patch b/patches/sched-better-debug-output-for-might-sleep.patch
index b00703f..57e5c04 100644
--- a/patches/sched-better-debug-output-for-might-sleep.patch
+++ b/patches/sched-better-debug-output-for-might-sleep.patch
@@ -13,7 +13,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1329,6 +1329,9 @@ struct task_struct {
+@@ -1330,6 +1330,9 @@ struct task_struct {
  	struct mutex perf_event_mutex;
  	struct list_head perf_event_list;
  #endif
diff --git a/patches/sched-delay-put-task.patch b/patches/sched-delay-put-task.patch
index 2f23347..1446197 100644
--- a/patches/sched-delay-put-task.patch
+++ b/patches/sched-delay-put-task.patch
@@ -10,7 +10,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1438,6 +1438,9 @@ struct task_struct {
+@@ -1439,6 +1439,9 @@ struct task_struct {
  	unsigned int	sequential_io;
  	unsigned int	sequential_io_avg;
  #endif
@@ -20,7 +20,7 @@
  };
  
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
-@@ -1597,6 +1600,15 @@ extern struct pid *cad_pid;
+@@ -1598,6 +1601,15 @@ extern struct pid *cad_pid;
  extern void free_task(struct task_struct *tsk);
  #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
  
@@ -36,7 +36,7 @@
  extern void __put_task_struct(struct task_struct *t);
  
  static inline void put_task_struct(struct task_struct *t)
-@@ -1604,6 +1616,7 @@ static inline void put_task_struct(struc
+@@ -1605,6 +1617,7 @@ static inline void put_task_struct(struc
  	if (atomic_dec_and_test(&t->usage))
  		__put_task_struct(t);
  }
diff --git a/patches/sched-migrate-disable.patch b/patches/sched-migrate-disable.patch
index d9a328a..4e3a8b4 100644
--- a/patches/sched-migrate-disable.patch
+++ b/patches/sched-migrate-disable.patch
@@ -29,7 +29,7 @@
  # define preempt_enable_rt()		preempt_enable()
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1074,6 +1074,7 @@ struct task_struct {
+@@ -1075,6 +1075,7 @@ struct task_struct {
  #endif
  
  	unsigned int policy;
@@ -37,7 +37,7 @@
  	int nr_cpus_allowed;
  	cpumask_t cpus_allowed;
  
-@@ -1444,9 +1445,6 @@ struct task_struct {
+@@ -1445,9 +1446,6 @@ struct task_struct {
  #endif
  };
  
@@ -47,7 +47,7 @@
  #ifdef CONFIG_NUMA_BALANCING
  extern void task_numa_fault(int node, int pages, bool migrated);
  extern void set_numabalancing_state(bool enabled);
-@@ -2619,6 +2617,15 @@ static inline void set_task_cpu(struct t
+@@ -2620,6 +2618,15 @@ static inline void set_task_cpu(struct t
  
  #endif /* CONFIG_SMP */
  
diff --git a/patches/sched-mmdrop-delayed.patch b/patches/sched-mmdrop-delayed.patch
index 870e86f..2695d65 100644
--- a/patches/sched-mmdrop-delayed.patch
+++ b/patches/sched-mmdrop-delayed.patch
@@ -35,7 +35,7 @@
  /* first nid will either be a valid NID or one of these values */
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -2132,12 +2132,24 @@ extern struct mm_struct * mm_alloc(void)
+@@ -2133,12 +2133,24 @@ extern struct mm_struct * mm_alloc(void)
  
  /* mmdrop drops the mm and the page tables */
  extern void __mmdrop(struct mm_struct *);
diff --git a/patches/sched-rt-mutex-wakeup.patch b/patches/sched-rt-mutex-wakeup.patch
index fa60771..3255b24 100644
--- a/patches/sched-rt-mutex-wakeup.patch
+++ b/patches/sched-rt-mutex-wakeup.patch
@@ -11,7 +11,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1034,6 +1034,7 @@ enum perf_event_task_context {
+@@ -1035,6 +1035,7 @@ enum perf_event_task_context {
  
  struct task_struct {
  	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
@@ -19,7 +19,7 @@
  	void *stack;
  	atomic_t usage;
  	unsigned int flags;	/* per process flags, defined below */
-@@ -2018,6 +2019,7 @@ extern void xtime_update(unsigned long t
+@@ -2019,6 +2020,7 @@ extern void xtime_update(unsigned long t
  
  extern int wake_up_state(struct task_struct *tsk, unsigned int state);
  extern int wake_up_process(struct task_struct *tsk);
diff --git a/patches/sched-teach-migrate_disable-about-atomic-contexts.patch b/patches/sched-teach-migrate_disable-about-atomic-contexts.patch
index afcc4bd..d27013f 100644
--- a/patches/sched-teach-migrate_disable-about-atomic-contexts.patch
+++ b/patches/sched-teach-migrate_disable-about-atomic-contexts.patch
@@ -39,7 +39,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1076,6 +1076,9 @@ struct task_struct {
+@@ -1077,6 +1077,9 @@ struct task_struct {
  	unsigned int policy;
  #ifdef CONFIG_PREEMPT_RT_FULL
  	int migrate_disable;
diff --git a/patches/series b/patches/series
index 96f00cc..2267ed0 100644
--- a/patches/series
+++ b/patches/series
@@ -178,6 +178,9 @@
 
 # HW LATENCY DETECTOR - this really wants a rewrite
 hwlatdetect.patch
+hwlat-detector-Update-hwlat_detector-to-add-outer-lo.patch
+hwlat-detector-Use-trace_clock_local-if-available.patch
+hwlat-detector-Use-thread-instead-of-stop-machine.patch
 
 ##################################################
 # REAL RT STUFF starts here
@@ -607,10 +610,13 @@
 # SIMPLE WAITQUEUE
 wait-simple-implementation.patch
 wait-simple-rework-for-completions.patch
+swait-Add-memory-barrier-before-checking-list-empty.patch
+swait-Add-smp_mb-after-setting-h-list.patch
 
 rcutiny-use-simple-waitqueue.patch
 treercu-use-simple-waitqueue.patch
 rcu-more-swait-conversions.patch
+rcu-swait-Fix-RCU-conversion-of-wake_up_all-to-swait.patch
 
 completion-use-simple-wait-queues.patch
 
diff --git a/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch b/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch
index d16f297..62bdcab 100644
--- a/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch
+++ b/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch
@@ -17,7 +17,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1215,6 +1215,7 @@ struct task_struct {
+@@ -1216,6 +1216,7 @@ struct task_struct {
  /* signal handlers */
  	struct signal_struct *signal;
  	struct sighand_struct *sighand;
diff --git a/patches/softirq-local-lock.patch b/patches/softirq-local-lock.patch
index 3261641..6825a0a 100644
--- a/patches/softirq-local-lock.patch
+++ b/patches/softirq-local-lock.patch
@@ -84,7 +84,7 @@
   *
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1447,6 +1447,7 @@ struct task_struct {
+@@ -1448,6 +1448,7 @@ struct task_struct {
  #endif
  #ifdef CONFIG_PREEMPT_RT_BASE
  	struct rcu_head put_rcu;
diff --git a/patches/softirq-make-serving-softirqs-a-task-flag.patch b/patches/softirq-make-serving-softirqs-a-task-flag.patch
index 6d75318..71d9425 100644
--- a/patches/softirq-make-serving-softirqs-a-task-flag.patch
+++ b/patches/softirq-make-serving-softirqs-a-task-flag.patch
@@ -12,7 +12,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1667,6 +1667,7 @@ extern void thread_group_cputime_adjuste
+@@ -1668,6 +1668,7 @@ extern void thread_group_cputime_adjuste
  /*
   * Per process flags
   */
diff --git a/patches/softirq-split-locks.patch b/patches/softirq-split-locks.patch
index 66df3ab..db7ede3 100644
--- a/patches/softirq-split-locks.patch
+++ b/patches/softirq-split-locks.patch
@@ -30,7 +30,7 @@
 
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1449,6 +1449,7 @@ struct task_struct {
+@@ -1450,6 +1450,7 @@ struct task_struct {
  #ifdef CONFIG_PREEMPT_RT_BASE
  	struct rcu_head put_rcu;
  	int softirq_nestcnt;
diff --git a/patches/swait-Add-memory-barrier-before-checking-list-empty.patch b/patches/swait-Add-memory-barrier-before-checking-list-empty.patch
new file mode 100644
index 0000000..24ddbdd
--- /dev/null
+++ b/patches/swait-Add-memory-barrier-before-checking-list-empty.patch
@@ -0,0 +1,54 @@
+From 8c7c8225cf6bfcf8a6cdcc86bc8d1137e38dde56 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 11:35:32 -0400
+Subject: [PATCH] swait: Add memory barrier before checking list empty
+
+There's a race condition with swait wakeups and adding to the list. The
+__swait_wake() does a check for swait_head_has_waiters(), and if it is
+empty it will exit without doing any wake ups. The problem is that the
+check does not include any memory barriers before it makes a decision
+to wake up or not.
+
+	CPU0				CPU1
+	----				----
+
+  condition = 1
+
+  load h->list (is empty)
+				    raw_spin_lock(hlist->lock)
+				    hlist_add();
+				    __set_current_state();
+				    raw_spin_unlock(hlist->lock)
+  swait_wake()
+   swait_head_has_waiters()
+   (sees h->list as empty and returns)
+
+				    check_condition (sees condition = 0)
+
+   store condition = 1
+
+				    schedule()
+
+Now the task on CPU1 has just missed its wakeup. By adding a memory
+barrier before the list empty check, we fix the problem of miss seeing
+the list not empty as well as pushing out the condition for the other
+task to see.
+
+Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/wait-simple.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/wait-simple.c
++++ b/kernel/wait-simple.c
+@@ -27,6 +27,8 @@ static inline void __swait_dequeue(struc
+ /* Check whether a head has waiters enqueued */
+ static inline bool swait_head_has_waiters(struct swait_head *h)
+ {
++	/* Make sure the condition is visible before checking list_empty() */
++	smp_mb();
+ 	return !list_empty(&h->list);
+ }
+ 
diff --git a/patches/swait-Add-smp_mb-after-setting-h-list.patch b/patches/swait-Add-smp_mb-after-setting-h-list.patch
new file mode 100644
index 0000000..f09ad2b
--- /dev/null
+++ b/patches/swait-Add-smp_mb-after-setting-h-list.patch
@@ -0,0 +1,65 @@
+From b82ab65560f7f21371d90f94d51b2e535574adeb Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Mon, 19 Aug 2013 11:35:33 -0400
+Subject: [PATCH] swait: Add smp_mb() after setting h->list
+
+The raw_spin_unlock() is not a full memory barrier. It only keeps
+things from leaking past it, but does not prevent leaks from entering
+the critical section. That is:
+
+ 	p = 1;
+
+ 	raw_spin_lock();
+ 	[...]
+ 	raw_spin_unlock();
+
+ 	y = x
+
+ Can turn into:
+
+  	p = 1;
+
+ 	raw_spin_lock();
+
+ 	load x
+
+ 	store p = 1
+
+ 	raw_spin_unlock();
+
+ 	y = x
+
+This means that the condition check in __swait_event() (and friends)
+can be seen before the h->list is set.
+
+ 	raw_spin_lock();
+
+ 	load condition;
+
+ 	store h->list;
+
+ 	raw_spin_unlock();
+
+And the other CPU can see h->list as empty, and this CPU see condition
+as not set, and possibly miss the wake up.
+
+To prevent this from happening, add an mb() after setting the h->list.
+
+Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/wait-simple.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/wait-simple.c
++++ b/kernel/wait-simple.c
+@@ -16,6 +16,8 @@
+ static inline void __swait_enqueue(struct swait_head *head, struct swaiter *w)
+ {
+ 	list_add(&w->node, &head->list);
++	/* We can't let the condition leak before the setting of head */
++	smp_mb();
+ }
+ 
+ /* Removes w from head->list. Must be called with head->lock locked. */
diff --git a/patches/vtime-split-lock-and-seqcount.patch b/patches/vtime-split-lock-and-seqcount.patch
index 3932760..b8c9609 100644
--- a/patches/vtime-split-lock-and-seqcount.patch
+++ b/patches/vtime-split-lock-and-seqcount.patch
@@ -24,7 +24,7 @@
  #else
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1167,7 +1167,8 @@ struct task_struct {
+@@ -1168,7 +1168,8 @@ struct task_struct {
  	struct cputime prev_cputime;
  #endif
  #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
diff --git a/patches/x86-mce-Defer-mce-wakeups-to-threads-for-PREEMPT_RT.patch b/patches/x86-mce-Defer-mce-wakeups-to-threads-for-PREEMPT_RT.patch
index 58c2f3c..54dbd46 100644
--- a/patches/x86-mce-Defer-mce-wakeups-to-threads-for-PREEMPT_RT.patch
+++ b/patches/x86-mce-Defer-mce-wakeups-to-threads-for-PREEMPT_RT.patch
@@ -54,8 +54,8 @@
 		     kthread_run()]
 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 ---
- arch/x86/kernel/cpu/mcheck/mce.c |   75 ++++++++++++++++++++++++++++++++-------
- 1 file changed, 62 insertions(+), 13 deletions(-)
+ arch/x86/kernel/cpu/mcheck/mce.c |   73 ++++++++++++++++++++++++++++++++-------
+ 1 file changed, 61 insertions(+), 12 deletions(-)
 
 --- a/arch/x86/kernel/cpu/mcheck/mce.c
 +++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -67,24 +67,15 @@
  #include <linux/kdebug.h>
  #include <linux/kernel.h>
  #include <linux/percpu.h>
-@@ -1343,26 +1344,72 @@ static void mce_do_trigger(struct work_s
+@@ -1343,6 +1344,63 @@ static void mce_do_trigger(struct work_s
  
  static DECLARE_WORK(mce_trigger_work, mce_do_trigger);
  
--/*
-- * Notify the user(s) about new machine check events.
-- * Can be called from interrupt context, but not from machine check/NMI
-- * context.
-- */
--int mce_notify_irq(void)
 +static void __mce_notify_work(void)
- {
- 	/* Not more than two messages every minute */
- 	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
- 
--	if (test_and_clear_bit(0, &mce_need_notify)) {
--		/* wake processes polling /dev/mcelog */
--		wake_up_interruptible(&mce_chrdev_wait);
++{
++	/* Not more than two messages every minute */
++	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
++
 +	/* wake processes polling /dev/mcelog */
 +	wake_up_interruptible(&mce_chrdev_wait);
 +
@@ -121,14 +112,10 @@
 +					   "mce-notify");
 +	if (!mce_notify_helper)
 +		return -ENOMEM;
- 
--		if (mce_helper[0])
--			schedule_work(&mce_trigger_work);
++
 +	return 0;
 +}
- 
--		if (__ratelimit(&ratelimit))
--			pr_info(HW_ERR "Machine check events logged\n");
++
 +static void mce_notify_work(void)
 +{
 +	wake_up_process(mce_notify_helper);
@@ -140,15 +127,27 @@
 +}
 +static inline int mce_notify_work_init(void) { return 0; }
 +#endif
- 
-+/*
-+ * Notify the user(s) about new machine check events.
-+ * Can be called from interrupt context, but not from machine check/NMI
-+ * context.
-+ */
-+int mce_notify_irq(void)
-+{
-+	if (test_and_clear_bit(0, &mce_need_notify)) {
++
+ /*
+  * Notify the user(s) about new machine check events.
+  * Can be called from interrupt context, but not from machine check/NMI
+@@ -1350,19 +1408,8 @@ static DECLARE_WORK(mce_trigger_work, mc
+  */
+ int mce_notify_irq(void)
+ {
+-	/* Not more than two messages every minute */
+-	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
+-
+ 	if (test_and_clear_bit(0, &mce_need_notify)) {
+-		/* wake processes polling /dev/mcelog */
+-		wake_up_interruptible(&mce_chrdev_wait);
+-
+-		if (mce_helper[0])
+-			schedule_work(&mce_trigger_work);
+-
+-		if (__ratelimit(&ratelimit))
+-			pr_info(HW_ERR "Machine check events logged\n");
+-
 +		mce_notify_work();
  		return 1;
  	}