2.6.35-stable review patch. If anyone has any objections, please let us know.

------------------

From: Thomas Gleixner <tglx@linutronix.de>

commit 0a7992c90828a65281c3c9cf180be3b432d277b2 upstream.

The ACPI_PREEMPTION_POINT() logic was introduced in commit 8bd108d(ACPICA: add preemption point after each opcode parse). The follow upcommits abe1dfab6, 138d15692, c084ca70 tried to fix the preemption logicback and forth, but nobody noticed that the usage ofin_atomic_preempt_off() in that context is wrong.

The check which guards the call of cond_resched() is:

if (!in_atomic_preempt_off() && !irqs_disabled())

in_atomic_preempt_off() is not intended for general use as the commentabove the macro definition clearly says:

* Check whether we were atomic before we did preempt_disable(): * (used by the scheduler, *after* releasing the kernel lock)

On a CONFIG_PREEMPT=n kernel the usage of in_atomic_preempt_off() works byaccident, but with CONFIG_PREEMPT=y it's just broken.

The whole purpose of the ACPI_PREEMPTION_POINT() is to reduce the latencyon a CONFIG_PREEMPT=n kernel, so make ACPI_PREEMPTION_POINT() depend onCONFIG_PREEMPT=n and remove the in_atomic_preempt_off() check.

-/* Used within ACPICA to show where it is safe to preempt execution */-#include <linux/hardirq.h>+#ifndef CONFIG_PREEMPT+/*+ * Used within ACPICA to show where it is safe to preempt execution+ * when CONFIG_PREEMPT=n+ */ #define ACPI_PREEMPTION_POINT() \ do { \- if (!in_atomic_preempt_off() && !irqs_disabled()) \+ if (!irqs_disabled()) \ cond_resched(); \ } while (0)+#endif