diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2013-02-19 18:33:41 -0500 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2013-02-19 18:33:41 -0500 |
commit | bb102e108f5d60068b3a5564f0f1f314d4c72332 (patch) | |
tree | 7221fd39d1c93e50b5dfcce9c8cf29136d9c86bb | |
parent | 5934b4e2acd48266f4aff44ca74b2d57951985e4 (diff) | |
download | 3.6-rt-patches-bb102e108f5d60068b3a5564f0f1f314d4c72332.tar.gz |
patches-3.6.11-rt30.tar.xzv3.6.11-rt30
md5sum:
512a6a0e0ed1abd8cee6a8c93f708c01 patches-3.6.11-rt30.tar.xz
Announce:
-----------------
Dear RT Folks,
I'm pleased to announce the 3.6.11-rt30 release.
Changes since 3.6.11-rt29:
1) Fix a deadlock on imx serial
2) Fix a ACPI scheduling while atomic issue (Steven)
3) Fix a longstanding mainline issue in printk (Yitian Bu)
I know I said that a few days ago already, but this is
probably^Whopefully the last release for 3.6 from my side. Steven
might keep it maintained until the 3.8-rt stabilizes, but that's not
yet decided.
The delta patch against 3.6.11-rt29 is appended below and can be found
here:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.6/incr/patch-3.6.11-rt29-rt30.pa
tch.xz
The RT patch against 3.6.11 can be found here:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.6/patch-3.6.11-rt30.patch.xz
The split quilt queue is available at:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.6/patches-3.6.11-rt30.tar.xz
Enjoy,
tglx
[delta diff snipped]
-----------------
http://marc.info/?l=linux-rt-users&m=136121604102408&w=2
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r-- | acpi-rt-convert-acpi-lock-back-to-a-raw_spinlock_t.patch | 182 | ||||
-rw-r--r-- | fix-rq-3elock-vs-logbuf_lock-unlock-race.patch | 37 | ||||
-rw-r--r-- | localversion.patch | 2 | ||||
-rw-r--r-- | serial-imx-fix-recursive-locking-bug.patch | 133 | ||||
-rw-r--r-- | series | 3 |
5 files changed, 356 insertions, 1 deletions
diff --git a/acpi-rt-convert-acpi-lock-back-to-a-raw_spinlock_t.patch b/acpi-rt-convert-acpi-lock-back-to-a-raw_spinlock_t.patch new file mode 100644 index 0000000..555d139 --- /dev/null +++ b/acpi-rt-convert-acpi-lock-back-to-a-raw_spinlock_t.patch @@ -0,0 +1,182 @@ +Subject: acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t +From: Steven Rostedt <rostedt@goodmis.org> +Date: Wed, 13 Feb 2013 09:26:05 -0500 + +We hit the following bug with 3.6-rt: + +[ 5.898990] BUG: scheduling while atomic: swapper/3/0/0x00000002 +[ 5.898991] no locks held by swapper/3/0. +[ 5.898993] Modules linked in: +[ 5.898996] Pid: 0, comm: swapper/3 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 +[ 5.898997] Call Trace: +[ 5.899011] [<ffffffff810804e7>] __schedule_bug+0x67/0x90 +[ 5.899028] [<ffffffff81577923>] __schedule+0x793/0x7a0 +[ 5.899032] [<ffffffff810b4e40>] ? debug_rt_mutex_print_deadlock+0x50/0x200 +[ 5.899034] [<ffffffff81577b89>] schedule+0x29/0x70 +[ 5.899036] BUG: scheduling while atomic: swapper/7/0/0x00000002 +[ 5.899037] no locks held by swapper/7/0. +[ 5.899039] [<ffffffff81578525>] rt_spin_lock_slowlock+0xe5/0x2f0 +[ 5.899040] Modules linked in: +[ 5.899041] +[ 5.899045] [<ffffffff81579a58>] ? _raw_spin_unlock_irqrestore+0x38/0x90 +[ 5.899046] Pid: 0, comm: swapper/7 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 +[ 5.899047] Call Trace: +[ 5.899049] [<ffffffff81578bc6>] rt_spin_lock+0x16/0x40 +[ 5.899052] [<ffffffff810804e7>] __schedule_bug+0x67/0x90 +[ 5.899054] [<ffffffff8157d3f0>] ? notifier_call_chain+0x80/0x80 +[ 5.899056] [<ffffffff81577923>] __schedule+0x793/0x7a0 +[ 5.899059] [<ffffffff812f2034>] acpi_os_acquire_lock+0x1f/0x23 +[ 5.899062] [<ffffffff810b4e40>] ? debug_rt_mutex_print_deadlock+0x50/0x200 +[ 5.899068] [<ffffffff8130be64>] acpi_write_bit_register+0x33/0xb0 +[ 5.899071] [<ffffffff81577b89>] schedule+0x29/0x70 +[ 5.899072] [<ffffffff8130be13>] ? acpi_read_bit_register+0x33/0x51 +[ 5.899074] [<ffffffff81578525>] rt_spin_lock_slowlock+0xe5/0x2f0 +[ 5.899077] [<ffffffff8131d1fc>] acpi_idle_enter_bm+0x8a/0x28e +[ 5.899079] [<ffffffff81579a58>] ? _raw_spin_unlock_irqrestore+0x38/0x90 +[ 5.899081] [<ffffffff8107e5da>] ? this_cpu_load+0x1a/0x30 +[ 5.899083] [<ffffffff81578bc6>] rt_spin_lock+0x16/0x40 +[ 5.899087] [<ffffffff8144c759>] cpuidle_enter+0x19/0x20 +[ 5.899088] [<ffffffff8157d3f0>] ? notifier_call_chain+0x80/0x80 +[ 5.899090] [<ffffffff8144c777>] cpuidle_enter_state+0x17/0x50 +[ 5.899092] [<ffffffff812f2034>] acpi_os_acquire_lock+0x1f/0x23 +[ 5.899094] [<ffffffff8144d1a1>] cpuidle899101] [<ffffffff8130be13>] ? + +As the acpi code disables interrupts in acpi_idle_enter_bm, and calls +code that grabs the acpi lock, it causes issues as the lock is currently +in RT a sleeping lock. + +The lock was converted from a raw to a sleeping lock due to some +previous issues, and tests that showed it didn't seem to matter. +Unfortunately, it did matter for one of our boxes. + +This patch converts the lock back to a raw lock. I've run this code on a +few of my own machines, one being my laptop that uses the acpi quite +extensively. I've been able to suspend and resume without issues. + +[ tglx: Made the change exclusive for acpi_gbl_hardware_lock ] + +Signed-off-by: Steven Rostedt <rostedt@goodmis.org> +Cc: John Kacur <jkacur@gmail.com> +Cc: Clark Williams <clark@redhat.com> +Link: http://lkml.kernel.org/r/1360765565.23152.5.camel@gandalf.local.home +Cc: stable-rt@vger.kernel.org +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +--- + drivers/acpi/acpica/acglobal.h | 2 +- + drivers/acpi/acpica/hwregs.c | 4 ++-- + drivers/acpi/acpica/hwxface.c | 4 ++-- + drivers/acpi/acpica/utmutex.c | 4 ++-- + include/acpi/platform/aclinux.h | 14 ++++++++++++++ + 5 files changed, 21 insertions(+), 7 deletions(-) + +Index: linux-stable/drivers/acpi/acpica/acglobal.h +=================================================================== +--- linux-stable.orig/drivers/acpi/acpica/acglobal.h ++++ linux-stable/drivers/acpi/acpica/acglobal.h +@@ -251,7 +251,7 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_pend + * interrupt level + */ + ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */ +-ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ ++ACPI_EXTERN acpi_raw_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ + + /***************************************************************************** + * +Index: linux-stable/drivers/acpi/acpica/hwregs.c +=================================================================== +--- linux-stable.orig/drivers/acpi/acpica/hwregs.c ++++ linux-stable/drivers/acpi/acpica/hwregs.c +@@ -271,14 +271,14 @@ acpi_status acpi_hw_clear_acpi_status(vo + ACPI_BITMASK_ALL_FIXED_STATUS, + ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + /* Clear the fixed events in PM1 A/B */ + + status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + ACPI_BITMASK_ALL_FIXED_STATUS); + +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + + if (ACPI_FAILURE(status)) + goto exit; +Index: linux-stable/drivers/acpi/acpica/hwxface.c +=================================================================== +--- linux-stable.orig/drivers/acpi/acpica/hwxface.c ++++ linux-stable/drivers/acpi/acpica/hwxface.c +@@ -366,7 +366,7 @@ acpi_status acpi_write_bit_register(u32 + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + /* + * At this point, we know that the parent register is one of the +@@ -427,7 +427,7 @@ acpi_status acpi_write_bit_register(u32 + + unlock_and_exit: + +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + return_ACPI_STATUS(status); + } + +Index: linux-stable/drivers/acpi/acpica/utmutex.c +=================================================================== +--- linux-stable.orig/drivers/acpi/acpica/utmutex.c ++++ linux-stable/drivers/acpi/acpica/utmutex.c +@@ -88,7 +88,7 @@ acpi_status acpi_ut_mutex_initialize(voi + return_ACPI_STATUS (status); + } + +- status = acpi_os_create_lock (&acpi_gbl_hardware_lock); ++ status = acpi_os_create_raw_lock (&acpi_gbl_hardware_lock); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } +@@ -135,7 +135,7 @@ void acpi_ut_mutex_terminate(void) + /* Delete the spinlocks */ + + acpi_os_delete_lock(acpi_gbl_gpe_lock); +- acpi_os_delete_lock(acpi_gbl_hardware_lock); ++ acpi_os_delete_raw_lock(acpi_gbl_hardware_lock); + + /* Delete the reader/writer lock */ + +Index: linux-stable/include/acpi/platform/aclinux.h +=================================================================== +--- linux-stable.orig/include/acpi/platform/aclinux.h ++++ linux-stable/include/acpi/platform/aclinux.h +@@ -72,6 +72,7 @@ + + #define acpi_cache_t struct kmem_cache + #define acpi_spinlock spinlock_t * ++#define acpi_raw_spinlock raw_spinlock_t * + #define acpi_cpu_flags unsigned long + + #else /* !__KERNEL__ */ +@@ -175,6 +176,19 @@ static inline void *acpi_os_acquire_obje + lock ? AE_OK : AE_NO_MEMORY; \ + }) + ++#define acpi_os_create_raw_lock(__handle) \ ++({ \ ++ raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ ++ \ ++ if (lock) { \ ++ *(__handle) = lock; \ ++ raw_spin_lock_init(*(__handle)); \ ++ } \ ++ lock ? AE_OK : AE_NO_MEMORY; \ ++}) ++ ++#define acpi_os_delete_raw_lock(__handle) kfree(__handle) ++ + #endif /* __KERNEL__ */ + + #endif /* __ACLINUX_H__ */ diff --git a/fix-rq-3elock-vs-logbuf_lock-unlock-race.patch b/fix-rq-3elock-vs-logbuf_lock-unlock-race.patch new file mode 100644 index 0000000..4dbb4e1 --- /dev/null +++ b/fix-rq-3elock-vs-logbuf_lock-unlock-race.patch @@ -0,0 +1,37 @@ +Subject: printk: Fix rq->lock vs logbuf_lock unlock lock inversion +From: "Bu, Yitian" <ybu@qti.qualcomm.com> +Date: Mon, 18 Feb 2013 12:53:37 +0000 + +commit 07354eb1a74d1 ("locking printk: Annotate logbuf_lock as raw") +reintroduced a lock inversion problem which was fixed in commit +0b5e1c5255 ("printk: Release console_sem after logbuf_lock"). This +happened probably when fixing up patch rejects. + +Restore the ordering and unlock logbuf_lock before releasing +console_sem. + +Signed-off-by: ybu <ybu@qti.qualcomm.com> +Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> +Cc: stable@vger.kernel.org +Cc: stable-rt@vger.kernel.org +Link: http://lkml.kernel.org/r/E807E903FE6CBE4D95E420FBFCC273B827413C@nasanexd01h.na.qualcomm.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +--- + kernel/printk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-stable/kernel/printk.c +=================================================================== +--- linux-stable.orig/kernel/printk.c ++++ linux-stable/kernel/printk.c +@@ -1412,9 +1412,9 @@ static int console_trylock_for_printk(un + } + } + logbuf_cpu = UINT_MAX; ++ raw_spin_unlock(&logbuf_lock); + if (wake) + up(&console_sem); +- raw_spin_unlock(&logbuf_lock); + return retval; + } + diff --git a/localversion.patch b/localversion.patch index 3650b62..b0fb40f 100644 --- a/localversion.patch +++ b/localversion.patch @@ -14,4 +14,4 @@ Index: linux-stable/localversion-rt --- /dev/null +++ linux-stable/localversion-rt @@ -0,0 +1 @@ -+-rt29 ++-rt30 diff --git a/serial-imx-fix-recursive-locking-bug.patch b/serial-imx-fix-recursive-locking-bug.patch new file mode 100644 index 0000000..71e19ee --- /dev/null +++ b/serial-imx-fix-recursive-locking-bug.patch @@ -0,0 +1,133 @@ +Subject: serial: Imx: Fix recursive locking bug +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 14 Feb 2013 21:01:06 +0100 (CET) + +commit 9ec1882df2 (tty: serial: imx: console write routing is unsafe +on SMP) introduced a recursive locking bug in imx_console_write(). + +The callchain is: + +imx_rxint() + spin_lock_irqsave(&sport->port.lock,flags); + ... + uart_handle_sysrq_char(); + sysrq_function(); + printk(); + imx_console_write(); + spin_lock_irqsave(&sport->port.lock,flags); <--- DEAD + +The bad news is that the kernel debugging facilities can dectect the +problem, but the printks never surface on the serial console for +obvious reasons. + +There is a similar issue with oops_in_progress. If the kernel crashes +we really don't want to be stuck on the lock and unable to tell what +happened. + +In general most UP originated drivers miss these checks and nobody +ever notices because CONFIG_PROVE_LOCKING seems to be still ignored by +a large number of developers. + +The solution is to avoid locking in the sysrq case and trylock in the +oops_in_progress case. + +This scheme is used in other drivers as well and it would be nice if +we could move this to a common place, so the usual copy/paste/modify +bugs can be avoided. + +Now there is another issue with this scheme: + +CPU0 CPU1 +printk() + rxint() + sysrq_detection() -> sets port->sysrq + return from interrupt + console_write() + if (port->sysrq) + avoid locking + +port->sysrq is reset with the next receive character. So as long as +the port->sysrq is not reset and this can take an endless amount of +time if after the break no futher receive character follows, all +console writes happen unlocked. + +While the current writer is protected against other console writers by +the console sem, it's unprotected against open/close or other +operations which fiddle with the port. That's what the above mentioned +commit tried to solve. + +That's an issue in all drivers which use that scheme and unfortunately +there is no easy workaround. The only solution is to have a separate +indicator port->sysrq_cpu. uart_handle_sysrq_char() then sets it to +smp_processor_id() before calling into handle_sysrq() and resets it to +-1 after that. Then change the locking check to: + + if (port->sysrq_cpu == smp_processor_id()) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock_irqsave(port->lock, flags); + else + spin_lock_irqsave(port->lock, flags); + +That would force all other cpus into the spin_lock path. Problem +solved, but that's way beyond the scope of this fix and really wants +to be implemented in a common function which calls the uart specific +write function to avoid another gazillion of hard to debug +copy/paste/modify bugs. + +Reported-and-tested-by: Tim Sander <tim@krieglstein.org> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Jiri Slaby <jslaby@suse.cz> +Cc: Xinyu Chen <xinyu.chen@freescale.com> +Cc: Dirk Behme <dirk.behme@de.bosch.com> +Cc: Shawn Guo <shawn.guo@linaro.org> +Cc: Tim Sander <tim@krieglstein.org> +Cc: Sascha Hauer <s.hauer@pengutronix.de> +Cc: stable-rt@vger.kernel.org +Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1302142006050.22263@ionos +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +Index: linux-2.6/drivers/tty/serial/imx.c +=================================================================== +--- linux-2.6.orig/drivers/tty/serial/imx.c ++++ linux-2.6/drivers/tty/serial/imx.c +@@ -1213,8 +1213,14 @@ imx_console_write(struct console *co, co + struct imx_port_ucrs old_ucr; + unsigned int ucr1; + unsigned long flags; ++ int locked = 1; + +- spin_lock_irqsave(&sport->port.lock, flags); ++ if (sport->port.sysrq) ++ locked = 0; ++ else if (oops_in_progress) ++ locked = spin_trylock_irqsave(&sport->port.lock, flags); ++ else ++ spin_lock_irqsave(&sport->port.lock, flags); + + /* + * First, save UCR1/2/3 and then disable interrupts +@@ -1241,7 +1247,8 @@ imx_console_write(struct console *co, co + + imx_port_ucrs_restore(&sport->port, &old_ucr); + +- spin_unlock_irqrestore(&sport->port.lock, flags); ++ if (locked) ++ spin_unlock_irqrestore(&sport->port.lock, flags); + } + + /* + + + + + + +-- +To unsubscribe from this list: send the line "unsubscribe linux-kernel" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html +Please read the FAQ at http://www.tux.org/lkml/ + + @@ -636,6 +636,9 @@ mm-make-pagefault-dis-enable-export-symbol.patch x86_32-use-kmap-switch-for-non-highmem-as-well.patch highmem-rt-store-per-task-ptes-directly.patch arm-enable-highmem-for-rt.patch +acpi-rt-convert-acpi-lock-back-to-a-raw_spinlock_t.patch +fix-rq-3elock-vs-logbuf_lock-unlock-race.patch +serial-imx-fix-recursive-locking-bug.patch kconfig-disable-a-few-options-rt.patch kconfig-preempt-rt-full.patch |