3.4.32-rt46-rc1 stable review
Subsystems (7)
Steven Rostedt
reviewercover 3.4.32-rt46-rc1 stable review
Dear RT Folks,
This is the RT stable review cycle of patch 3.4.32-rt46-rc1.
Please scream at me if I messed something up. Please test the patches too.
The -rc release will be uploaded to kernel.org and will be deleted when the final release is out. This is just a review release (or release candidate).
The pre-releases will not be pushed to the git repository, only the final release is.
If all goes well, this patch will be converted to the next main release on 2/22/2013.
Enjoy,
-- Steve
To build 3.4.32-rt46-rc1 directly, the following patches should be applied:
http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.4.tar.xz
http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.4.32.xz
http://www.kernel.org/pub/linux/kernel/projects/rt/3.4/patch-3.4.32-rt46-rc1.patch.xz
You can also build from 3.4.32-rt45 by applying the incremental patch:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.4/incr/patch-3.4.32-rt45-rt46-rc1.patch.xz
Changes from 3.4.32-rt45:
---
Bu, Yitian (1):
printk: Fix rq->lock vs logbuf_lock unlock lock inversion
Steven Rostedt (2):
acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t Linux 3.4.32-rt46-rc1
Thomas Gleixner (4):
x86/32: Use kmap switch for non highmem as well
serial: Imx: Fix recursive locking bug
wait-simple: Simple waitqueue implementation
rcutiny: Use simple waitqueue
----
arch/x86/kernel/process_32.c | 2 +- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/hwregs.c | 4 +- drivers/acpi/acpica/hwxface.c | 4 +- drivers/acpi/acpica/utmutex.c | 4 +- drivers/tty/serial/imx.c | 11 ++- include/acpi/platform/aclinux.h | 14 ++++ include/linux/sched.h | 4 +- include/linux/wait-simple.h | 172 +++++++++++++++++++++++++++++++++++++++ kernel/Makefile | 2 +- kernel/printk.c | 2 +- kernel/rcutiny_plugin.h | 17 ++-- kernel/wait-simple.c | 119 +++++++++++++++++++++++++++ localversion-rt | 2 +- 14 files changed, 337 insertions(+), 22 deletions(-)
Steven Rostedt
reviewerPATCH 1/7 x86/32: Use kmap switch for non highmem as well
From: Thomas Gleixner <[email protected]>
Even with CONFIG_HIGHMEM=n we need to take care of the "atomic" mappings which are installed via iomap_atomic.
--- arch/x86/kernel/process_32.c | 2 +- include/linux/sched.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
arch/x86/kernel/process_32.c +1 -1
@@ -286,7 +286,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))__switch_to_xtra (prev_p, next_p, tss); -#if definedCONFIG_PREEMPT_RT_FULL && definedCONFIG_HIGHMEM +#ifdef CONFIG_PREEMPT_RT_FULL /* * Save @prev's kmap_atomic stack */
include/linux/sched.h +3 -1
@@ -1651,9 +1651,11 @@ struct task_struct {struct rcu_head put_rcu;int softirq_nestcnt;#endif -#if definedCONFIG_PREEMPT_RT_FULL && definedCONFIG_HIGHMEM +#ifdef CONFIG_PREEMPT_RT_FULL +# if definedCONFIG_HIGHMEM || definedCONFIG_X86_32 int kmap_idx;pte_t kmap_pte[KM_TYPE_NR ]; +# endif #endif #ifdef CONFIG_DEBUG_PREEMPT
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 2/7 acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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 ]
--- 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(-)
drivers/acpi/acpica/acglobal.h +1 -1
@@ -251,7 +251,7 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_pending;* 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 *//***************************************************************************** *
drivers/acpi/acpica/hwregs.c +2 -2
@@ -271,14 +271,14 @@ acpi_status acpi_hw_clear_acpi_status(void)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;
drivers/acpi/acpica/hwxface.c +2 -2
@@ -366,7 +366,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value)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 register_id, u32 value) 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); }
drivers/acpi/acpica/utmutex.c +2 -2
@@ -88,7 +88,7 @@ acpi_status acpi_ut_mutex_initialize(void)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 */
include/acpi/platform/aclinux.h +14 -0
@@ -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_object(acpi_cache_t * cache) 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__ */
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 3/7 printk: Fix rq->lock vs logbuf_lock unlock lock inversion
In reply to Steven RostedtFrom: "Bu, Yitian" <[email protected]>
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.
--- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/printk.c +1 -1
@@ -868,9 +868,9 @@ static int console_trylock_for_printk(unsigned int cpu, unsigned long flags) } } printk_cpu =UINT_MAX ; +raw_spin_unlock (&logbuf_lock);if (wake)up (&console_sem); -raw_spin_unlock (&logbuf_lock);return retval; } static const char recursion_bug_msg [] =
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 4/7 serial: Imx: Fix recursive locking bug
In reply to Steven RostedtFrom: Thomas Gleixner <[email protected]>
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); <--- DEADThe 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 CPU1printk()
rxint()
sysrq_detection() -> sets port->sysrq
return from interrupt
console_write()
if (port->sysrq)
avoid lockingport->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.
--- drivers/tty/serial/imx.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/tty/serial/imx.c +9 -2
@@ -1225,8 +1225,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count)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
@@ -1253,7 +1259,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)imx_port_ucrs_restore (&sport->port, &old_ucr); -spin_unlock_irqrestore (&sport->port.lock, flags); +if (locked) +spin_unlock_irqrestore (&sport->port.lock, flags); }/*
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 5/7 wait-simple: Simple waitqueue implementation
In reply to Steven RostedtFrom: Thomas Gleixner <[email protected]>
wait_queue is a swiss army knife and in most of the cases the complexity is not needed. For RT waitqueues are a constant source of trouble as we can't convert the head lock to a raw spinlock due to fancy and long lasting callbacks.
Provide a slim version, which allows RT to replace wait queues. This should go mainline as well, as it lowers memory consumption and runtime overhead.
--- include/linux/wait-simple.h | 172 +++++++++++++++++++++++++++++++++++++++++++ kernel/Makefile | 2 +- kernel/wait-simple.c | 119 ++++++++++++++++++++++++++++++ 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 include/linux/wait-simple.h create mode 100644 kernel/wait-simple.c
include/linux/wait-simple.h new file +172 -0
@@ -0,0 +1,172 @@ +#ifndef _LINUX_WAIT_SIMPLE_H +#define _LINUX_WAIT_SIMPLE_H + +#include <linux/spinlock.h> +#include <linux/list.h> + +#include <asm/current.h> + +struct swaiter { +struct task_struct *task; +struct list_head node; +}; + +#define DEFINE_SWAITER (name) \ + struct swaiter name = { \ + .task = current, \ + .node = LIST_HEAD_INIT((name).node), \ + } + +struct swait_head { +raw_spinlock_t lock; +struct list_head list; +}; + +#define SWAIT_HEAD_INITIALIZER (name) { \ + .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ + .list = LIST_HEAD_INIT((name).list), \ + } + +#define DEFINE_SWAIT_HEAD (name) \ + struct swait_head name = SWAIT_HEAD_INITIALIZER(name) + +extern void __init_swait_head (struct swait_head *h,struct lock_class_key *key); + +#define init_swait_head (swh) \ + do { \ + static struct lock_class_key __key; \ + \ + __init_swait_head((swh), &__key); \ + } while (0) + +/* +* Waiter functions +*/ +extern void swait_prepare_locked (struct swait_head *head,struct swaiter *w); +extern void swait_prepare (struct swait_head *head,struct swaiter *w,int state); +extern void swait_finish_locked (struct swait_head *head,struct swaiter *w); +extern void swait_finish (struct swait_head *head,struct swaiter *w); + +/* +* Wakeup functions +*/ +extern unsigned int __swait_wake (struct swait_head *head,unsigned int state,unsigned int num); +extern unsigned int __swait_wake_locked (struct swait_head *head,unsigned int state,unsigned int num); + +#define swait_wake (head) __swait_wake(head, TASK_NORMAL, 1) +#define swait_wake_interruptible (head) __swait_wake(head, TASK_INTERRUPTIBLE, 1) +#define swait_wake_all (head) __swait_wake(head, TASK_NORMAL, 0) +#define swait_wake_all_interruptible (head) __swait_wake(head, TASK_INTERRUPTIBLE, 0) + +/* +* Event API +*/ +#define __swait_event (wq, condition) \ +do { \ + DEFINE_SWAITER(__wait); \ + \ + for (;;) { \ + swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + schedule(); \ + } \ + swait_finish(&wq, &__wait); \ +} while (0) + +/** +* swait_event - sleep until a condition gets true +* @wq: the waitqueue to wait on +* @condition: a C expression for the event to wait for +* +* The process is put to sleep (TASK_UNINTERRUPTIBLE) until the +* @condition evaluates to true. The @condition is checked each time +* the waitqueue @wq is woken up. +* +* wake_up() has to be called after changing any variable that could +* change the result of the wait condition. +*/ +#define swait_event (wq, condition) \ +do { \ + if (condition) \ + break; \ + __swait_event(wq, condition); \ +} while (0) + +#define __swait_event_interruptible (wq, condition, ret) \ +do { \ + DEFINE_SWAITER(__wait); \ + \ + for (;;) { \ + swait_prepare(&wq, &__wait, TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (signal_pending(current)) { \ + ret = -ERESTARTSYS; \ + break; \ + } \ + schedule(); \ + } \ + swait_finish(&wq, &__wait); \ +} while (0) + +/** +* swait_event_interruptible - sleep until a condition gets true +* @wq: the waitqueue to wait on +* @condition: a C expression for the event to wait for +* +* The process is put to sleep (TASK_INTERRUPTIBLE) until the +* @condition evaluates to true. The @condition is checked each time +* the waitqueue @wq is woken up. +* +* wake_up() has to be called after changing any variable that could +* change the result of the wait condition. +*/ +#define swait_event_interruptible (wq, condition) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __swait_event_interruptible(wq, condition, __ret); \ + __ret; \ +}) + +#define __swait_event_timeout (wq, condition, ret) \ +do { \ + DEFINE_SWAITER(__wait); \ + \ + for (;;) { \ + swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + } \ + swait_finish(&wq, &__wait); \ +} while (0) + +/** +* swait_event_timeout - sleep until a condition gets true or a timeout elapses +* @wq: the waitqueue to wait on +* @condition: a C expression for the event to wait for +* @timeout: timeout, in jiffies +* +* The process is put to sleep (TASK_UNINTERRUPTIBLE) until the +* @condition evaluates to true. The @condition is checked each time +* the waitqueue @wq is woken up. +* +* wake_up() has to be called after changing any variable that could +* change the result of the wait condition. +* +* The function returns 0 if the @timeout elapsed, and the remaining +* jiffies if the condition evaluated to true before the timeout elapsed. +*/ +#define swait_event_timeout (wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __swait_event_timeout(wq, condition, __ret); \ + __ret; \ +}) + +#endif
kernel/Makefile +1 -1
@@ -10,7 +10,7 @@ obj-y = fork.o exec_domain.o panic.o printk.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o \ hrtimer.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o cred.o \ - async.o range.o groups.o + async.o range.o groups.o wait-simple.o ifdef CONFIG_FUNCTION_TRACER # Do not trace debug files and internal ftrace files
kernel/wait-simple.c new file +119 -0
119 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 6/7 rcutiny: Use simple waitqueue
In reply to Steven RostedtFrom: Thomas Gleixner <[email protected]>
Simple waitqueues can be handled from interrupt disabled contexts.
--- kernel/rcutiny_plugin.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/rcutiny_plugin.h +9 -8
@@ -26,6 +26,7 @@#include <linux/module.h> #include <linux/debugfs.h> #include <linux/seq_file.h> +#include <linux/wait-simple.h> /* Global control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk {
@@ -261,7 +262,7 @@ static void show_tiny_preempt_stats(struct seq_file *m)/* Controls for rcu_kthread() kthread. */ static struct task_struct *rcu_kthread_task; -static DECLARE_WAIT_QUEUE_HEAD (rcu_kthread_wq); +static DEFINE_SWAIT_HEAD (rcu_kthread_wq);static unsigned long have_rcu_kthread_work;/*
@@ -754,7 +755,7 @@ void synchronize_rcu(void) }EXPORT_SYMBOL_GPL (synchronize_rcu); -static DECLARE_WAIT_QUEUE_HEAD (sync_rcu_preempt_exp_wq); +static DEFINE_SWAIT_HEAD (sync_rcu_preempt_exp_wq);static unsigned long sync_rcu_preempt_exp_count;static DEFINE_MUTEX (sync_rcu_preempt_exp_mutex);
@@ -776,7 +777,7 @@ static int rcu_preempted_readers_exp(void)*/ static void rcu_report_exp_done (void ) { -wake_up (&sync_rcu_preempt_exp_wq); +swait_wake (&sync_rcu_preempt_exp_wq); }/*
@@ -828,8 +829,8 @@ void synchronize_rcu_expedited(void)else {rcu_initiate_boost ();local_irq_restore (flags); -wait_event (sync_rcu_preempt_exp_wq, - !rcu_preempted_readers_exp ()); +swait_event (sync_rcu_preempt_exp_wq, + !rcu_preempted_readers_exp ()); }/* Clean up and exit. */
@@ -917,7 +918,7 @@ static void invoke_rcu_callbacks(void) { have_rcu_kthread_work =1 ;if (rcu_kthread_task !=NULL ) -wake_up (&rcu_kthread_wq); +swait_wake (&rcu_kthread_wq); }#ifdef CONFIG_RCU_TRACE
@@ -947,8 +948,8 @@ static int rcu_kthread(void *arg)unsigned long flags;for (;;) { -wait_event_interruptible (rcu_kthread_wq, - have_rcu_kthread_work !=0 ); +swait_event_interruptible (rcu_kthread_wq, + have_rcu_kthread_work !=0 ); morework =rcu_boost ();local_irq_save (flags); work = have_rcu_kthread_work;
Signature · 1 line
1.7.10.4
Steven Rostedt
reviewerPATCH 7/7 Linux 3.4.32-rt46-rc1
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
--- localversion-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
localversion-rt +1 -1
@@ -1 +1 @@ --rt45 +-rt46-rc1
Signature · 1 line
1.7.10.4