summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel.spec12
-rw-r--r--mcelog-rcu-splat.patch15
-rw-r--r--x86-Avoid-invoking-RCU-when-CPU-is-idle.patch118
3 files changed, 144 insertions, 1 deletions
diff --git a/kernel.spec b/kernel.spec
index c383e0c66..3641eb53d 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -54,7 +54,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 1
+%global baserelease 2
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -758,6 +758,9 @@ Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
#rhbz 714828
Patch21236: autofs4-lockdep.patch
+Patch21237: mcelog-rcu-splat.patch
+Patch21238: x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
+
# compat-wireless patches
Patch50000: compat-wireless-config-fixups.patch
Patch50001: compat-wireless-pr_fmt-warning-avoidance.patch
@@ -1464,6 +1467,9 @@ ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
#rhbz 714828
ApplyPatch autofs4-lockdep.patch
+ApplyPatch mcelog-rcu-splat.patch
+ApplyPatch x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2334,6 +2340,10 @@ fi
# ||----w |
# || ||
%changelog
+* Tue Feb 14 2012 Josh Boyer <jwboyer@redhat.com>
+- Add patch to fix RCU usage during cpu idle (rhbz 789641)
+- Add patch to fix mce rcu splat (rhbz 789644)
+
* Tue Feb 14 2012 Josh Boyer <jwboyer@redhat.com> - 3.3.0-0.rc3.git5.1
- Linux 3.3-rc3-git5 (upstream ce5afed937f0a823d3b00c9459409c3f5f2fbd5d)
diff --git a/mcelog-rcu-splat.patch b/mcelog-rcu-splat.patch
new file mode 100644
index 000000000..12c1fe3ea
--- /dev/null
+++ b/mcelog-rcu-splat.patch
@@ -0,0 +1,15 @@
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index f22a9f7..f525f99 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -191,7 +191,7 @@ static void drain_mcelog_buffer(void)
+ {
+ unsigned int next, i, prev = 0;
+
+- next = rcu_dereference_check_mce(mcelog.next);
++ next = ACCESS_ONCE(mcelog.next);
+
+ do {
+ struct mce *m;
+
+ \ No newline at end of file
diff --git a/x86-Avoid-invoking-RCU-when-CPU-is-idle.patch b/x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
new file mode 100644
index 000000000..2d45056bb
--- /dev/null
+++ b/x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
@@ -0,0 +1,118 @@
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 15763af..f6978b0 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -386,17 +386,21 @@ void default_idle(void)
+ */
+ smp_mb();
+
++ rcu_idle_enter();
+ if (!need_resched())
+ safe_halt(); /* enables interrupts racelessly */
+ else
+ local_irq_enable();
++ rcu_idle_exit();
+ current_thread_info()->status |= TS_POLLING;
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+ } else {
+ local_irq_enable();
+ /* loop is done by the caller */
++ rcu_idle_enter();
+ cpu_relax();
++ rcu_idle_exit();
+ }
+ }
+ #ifdef CONFIG_APM_MODULE
+@@ -457,14 +461,19 @@ static void mwait_idle(void)
+
+ __monitor((void *)&current_thread_info()->flags, 0, 0);
+ smp_mb();
++ rcu_idle_enter();
+ if (!need_resched())
+ __sti_mwait(0, 0);
+ else
+ local_irq_enable();
++ rcu_idle_exit();
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+- } else
++ } else {
+ local_irq_enable();
++ rcu_idle_enter();
++ rcu_idle_exit();
++ }
+ }
+
+ /*
+@@ -477,8 +486,10 @@ static void poll_idle(void)
+ trace_power_start(POWER_CSTATE, 0, smp_processor_id());
+ trace_cpu_idle(0, smp_processor_id());
+ local_irq_enable();
++ rcu_idle_enter();
+ while (!need_resched())
+ cpu_relax();
++ rcu_idle_exit();
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+ }
+diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
+index 485204f..6d9d4d5 100644
+--- a/arch/x86/kernel/process_32.c
++++ b/arch/x86/kernel/process_32.c
+@@ -100,7 +100,6 @@ void cpu_idle(void)
+ /* endless idle loop with no priority at all */
+ while (1) {
+ tick_nohz_idle_enter();
+- rcu_idle_enter();
+ while (!need_resched()) {
+
+ check_pgt_cache();
+@@ -117,7 +116,6 @@ void cpu_idle(void)
+ pm_idle();
+ start_critical_timings();
+ }
+- rcu_idle_exit();
+ tick_nohz_idle_exit();
+ preempt_enable_no_resched();
+ schedule();
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index 9b9fe4a..55a1a35 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -140,13 +140,9 @@ void cpu_idle(void)
+ /* Don't trace irqs off for idle */
+ stop_critical_timings();
+
+- /* enter_idle() needs rcu for notifiers */
+- rcu_idle_enter();
+-
+ if (cpuidle_idle_call())
+ pm_idle();
+
+- rcu_idle_exit();
+ start_critical_timings();
+
+ /* In many cases the interrupt that ended idle
+diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
+index 20bce51..a9ddab8 100644
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -261,6 +261,7 @@ static int intel_idle(struct cpuidle_device *dev,
+ kt_before = ktime_get_real();
+
+ stop_critical_timings();
++ rcu_idle_enter();
+ if (!need_resched()) {
+
+ __monitor((void *)&current_thread_info()->flags, 0, 0);
+@@ -268,6 +269,7 @@ static int intel_idle(struct cpuidle_device *dev,
+ if (!need_resched())
+ __mwait(eax, ecx);
+ }
++ rcu_idle_exit();
+
+ start_critical_timings();
+
+
+ \ No newline at end of file