linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review
@ 2013-02-19  3:56 Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 1/7] x86/32: Use kmap switch for non highmem as well Steven Rostedt
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users; +Cc: Thomas Gleixner, Carsten Emde, John Kacur


Dear RT Folks,

This is the RT stable review cycle of patch 3.2.38-rt58-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.2.38-rt58-rc1 directly, the following patches should be applied:

  http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.tar.xz

  http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.2.38.xz

  http://www.kernel.org/pub/linux/kernel/projects/rt/3.2/patch-3.2.38-rt58-rc1.patch.xz

You can also build from 3.2.38-rt57 by applying the incremental patch:

http://www.kernel.org/pub/linux/kernel/projects/rt/3.2/incr/patch-3.2.38-rt57-rt58-rc1.patch.xz


Changes from 3.2.38-rt57:

---


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.2.38-rt58-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(-)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH RT 1/7] x86/32: Use kmap switch for non highmem as well
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 2/7] acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t Steven Rostedt
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users
  Cc: Thomas Gleixner, Carsten Emde, John Kacur, stable-rt

[-- Attachment #1: 0001-x86-32-Use-kmap-switch-for-non-highmem-as-well.patch --]
[-- Type: text/plain, Size: 1440 bytes --]

From: Thomas Gleixner <tglx@linutronix.de>

Even with CONFIG_HIGHMEM=n we need to take care of the "atomic"
mappings which are installed via iomap_atomic.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 arch/x86/kernel/process_32.c |    2 +-
 include/linux/sched.h        |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 20f1573..66ee590 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -340,7 +340,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 defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM
+#ifdef CONFIG_PREEMPT_RT_FULL
 	/*
 	 * Save @prev's kmap_atomic stack
 	 */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e2f9e3b..a26bd7e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1608,9 +1608,11 @@ struct task_struct {
 	struct rcu_head put_rcu;
 	int softirq_nestcnt;
 #endif
-#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM
+#ifdef CONFIG_PREEMPT_RT_FULL
+# if defined CONFIG_HIGHMEM || defined CONFIG_X86_32
 	int kmap_idx;
 	pte_t kmap_pte[KM_TYPE_NR];
+# endif
 #endif
 
 #ifdef CONFIG_DEBUG_PREEMPT
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 2/7] acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 1/7] x86/32: Use kmap switch for non highmem as well Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 3/7] printk: Fix rq->lock vs logbuf_lock unlock lock inversion Steven Rostedt
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users
  Cc: Thomas Gleixner, Carsten Emde, John Kacur, John Kacur,
	Clark Williams, stable-rt

[-- Attachment #1: 0002-acpi-rt-Convert-acpi_gbl_hardware-lock-back-to-a-raw.patch --]
[-- Type: text/plain, Size: 7407 bytes --]

From: Steven Rostedt <rostedt@goodmis.org>

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(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 76dc02f1..ca6bbe7 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -236,7 +236,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 */
 
 /*****************************************************************************
  *
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index cc70f3f..1df2ce6 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -263,14 +263,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;
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index c2793a8..5b28769 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -387,7 +387,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
@@ -448,7 +448,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);
 }
 
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 7d797e2..b611bf3 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -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 */
 
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index f4b2eff..0e70789 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -73,6 +73,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__ */
@@ -176,6 +177,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__ */
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 3/7] printk: Fix rq->lock vs logbuf_lock unlock lock inversion
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 1/7] x86/32: Use kmap switch for non highmem as well Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 2/7] acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 4/7] serial: Imx: Fix recursive locking bug Steven Rostedt
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users
  Cc: Thomas Gleixner, Carsten Emde, John Kacur, ybu, Peter Zijlstra,
	stable, stable-rt

[-- Attachment #1: 0003-printk-Fix-rq-lock-vs-logbuf_lock-unlock-lock-invers.patch --]
[-- Type: text/plain, Size: 1219 bytes --]

From: "Bu, Yitian" <ybu@qti.qualcomm.com>

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>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/printk.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/printk.c b/kernel/printk.c
index 972cc56..37b9b99 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -867,9 +867,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 [] =
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 4/7] serial: Imx: Fix recursive locking bug
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
                   ` (2 preceding siblings ...)
  2013-02-19  3:56 ` [PATCH RT 3/7] printk: Fix rq->lock vs logbuf_lock unlock lock inversion Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 5/7] wait-simple: Simple waitqueue implementation Steven Rostedt
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users
  Cc: Thomas Gleixner, Carsten Emde, John Kacur, Greg Kroah-Hartman,
	Jiri Slaby, Xinyu Chen, Dirk Behme, Shawn Guo, Tim Sander,
	Sascha Hauer, stable-rt

[-- Attachment #1: 0004-serial-Imx-Fix-recursive-locking-bug.patch --]
[-- Type: text/plain, Size: 4369 bytes --]

From: Thomas Gleixner <tglx@linutronix.de>

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>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 drivers/tty/serial/imx.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 8e68f79..5f5c214 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1115,8 +1115,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	struct imx_port *sport = imx_ports[co->index];
 	unsigned int old_ucr1, old_ucr2, 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 and then disable interrupts
@@ -1144,7 +1150,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	writel(old_ucr1, sport->port.membase + UCR1);
 	writel(old_ucr2, sport->port.membase + UCR2);
 
-	spin_unlock_irqrestore(&sport->port.lock, flags);
+	if (locked)
+		spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
 /*
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 5/7] wait-simple: Simple waitqueue implementation
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
                   ` (3 preceding siblings ...)
  2013-02-19  3:56 ` [PATCH RT 4/7] serial: Imx: Fix recursive locking bug Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 6/7] rcutiny: Use simple waitqueue Steven Rostedt
  2013-02-19  3:56 ` [PATCH RT 7/7] Linux 3.2.38-rt58-rc1 Steven Rostedt
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users; +Cc: Thomas Gleixner, Carsten Emde, John Kacur

[-- Attachment #1: 0005-wait-simple-Simple-waitqueue-implementation.patch --]
[-- Type: text/plain, Size: 9813 bytes --]

From: Thomas Gleixner <tglx@linutronix.de>

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.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[backport by: Tim Sander <tim.sander@hbm.com> ]
---
 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

diff --git a/include/linux/wait-simple.h b/include/linux/wait-simple.h
new file mode 100644
index 0000000..44fee60
--- /dev/null
+++ b/include/linux/wait-simple.h
@@ -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
diff --git a/kernel/Makefile b/kernel/Makefile
index c961d3a..0b0ed50 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    hrtimer.o nsproxy.o srcu.o semaphore.o \
 	    notifier.o ksysfs.o sched_clock.o cred.o \
 	    async.o range.o
-obj-y += groups.o
+obj-y += groups.o wait-simple.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace debug files and internal ftrace files
diff --git a/kernel/wait-simple.c b/kernel/wait-simple.c
new file mode 100644
index 0000000..c35ec78
--- /dev/null
+++ b/kernel/wait-simple.c
@@ -0,0 +1,119 @@
+/*
+ * Simple waitqueues without fancy flags and callbacks
+ *
+ * (C) 2011 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Based on kernel/wait.c
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/wait-simple.h>
+
+/* Adds w to head->list. Must be called with head->lock locked. */
+static inline void __swait_enqueue(struct swait_head *head, struct swaiter *w)
+{
+	list_add(&w->node, &head->list);
+}
+
+/* Removes w from head->list. Must be called with head->lock locked. */
+static inline void __swait_dequeue(struct swaiter *w)
+{
+	list_del_init(&w->node);
+}
+
+/* Check whether a head has waiters enqueued */
+static inline bool swait_head_has_waiters(struct swait_head *h)
+{
+	return !list_empty(&h->list);
+}
+
+void __init_swait_head(struct swait_head *head, struct lock_class_key *key)
+{
+	raw_spin_lock_init(&head->lock);
+	lockdep_set_class(&head->lock, key);
+	INIT_LIST_HEAD(&head->list);
+}
+EXPORT_SYMBOL_GPL(__init_swait_head);
+
+void swait_prepare_locked(struct swait_head *head, struct swaiter *w)
+{
+	w->task = current;
+	if (list_empty(&w->node))
+		__swait_enqueue(head, w);
+}
+
+void swait_prepare(struct swait_head *head, struct swaiter *w, int state)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&head->lock, flags);
+	swait_prepare_locked(head, w);
+	__set_current_state(state);
+	raw_spin_unlock_irqrestore(&head->lock, flags);
+}
+EXPORT_SYMBOL_GPL(swait_prepare);
+
+void swait_finish_locked(struct swait_head *head, struct swaiter *w)
+{
+	__set_current_state(TASK_RUNNING);
+	if (w->task)
+		__swait_dequeue(w);
+}
+
+void swait_finish(struct swait_head *head, struct swaiter *w)
+{
+	unsigned long flags;
+
+	__set_current_state(TASK_RUNNING);
+	if (w->task) {
+		raw_spin_lock_irqsave(&head->lock, flags);
+		__swait_dequeue(w);
+		raw_spin_unlock_irqrestore(&head->lock, flags);
+	}
+}
+EXPORT_SYMBOL_GPL(swait_finish);
+
+unsigned int
+__swait_wake_locked(struct swait_head *head, unsigned int state, unsigned int num)
+{
+	struct swaiter *curr, *next;
+	int woken = 0;
+
+	list_for_each_entry_safe(curr, next, &head->list, node) {
+		if (wake_up_state(curr->task, state)) {
+			__swait_dequeue(curr);
+			/*
+			 * The waiting task can free the waiter as
+			 * soon as curr->task = NULL is written,
+			 * without taking any locks. A memory barrier
+			 * is required here to prevent the following
+			 * store to curr->task from getting ahead of
+			 * the dequeue operation.
+			 */
+			smp_wmb();
+			curr->task = NULL;
+			if (++woken == num)
+				break;
+		}
+	}
+	return woken;
+}
+
+unsigned int
+__swait_wake(struct swait_head *head, unsigned int state, unsigned int num)
+{
+	unsigned long flags;
+	int woken;
+
+	if (!swait_head_has_waiters(head))
+		return 0;
+
+	raw_spin_lock_irqsave(&head->lock, flags);
+	woken = __swait_wake_locked(head, state, num);
+	raw_spin_unlock_irqrestore(&head->lock, flags);
+	return woken;
+}
+EXPORT_SYMBOL_GPL(__swait_wake);
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 6/7] rcutiny: Use simple waitqueue
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
                   ` (4 preceding siblings ...)
  2013-02-19  3:56 ` [PATCH RT 5/7] wait-simple: Simple waitqueue implementation Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  2013-02-20 16:20   ` io_apic.c --> "nr_ioapics" not initialized ! Armin Steinhoff
  2013-02-19  3:56 ` [PATCH RT 7/7] Linux 3.2.38-rt58-rc1 Steven Rostedt
  6 siblings, 1 reply; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users; +Cc: Thomas Gleixner, Carsten Emde, John Kacur

[-- Attachment #1: 0006-rcutiny-Use-simple-waitqueue.patch --]
[-- Type: text/plain, Size: 2373 bytes --]

From: Thomas Gleixner <tglx@linutronix.de>

Simple waitqueues can be handled from interrupt disabled contexts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/rcutiny_plugin.h |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
index 2b0484a..f0a6606 100644
--- a/kernel/rcutiny_plugin.h
+++ b/kernel/rcutiny_plugin.h
@@ -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 {
@@ -250,7 +251,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;
 
 /*
@@ -720,7 +721,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);
 
@@ -742,7 +743,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);
 }
 
 /*
@@ -794,8 +795,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. */
@@ -882,7 +883,7 @@ static void rcu_preempt_process_callbacks(void)
 static void invoke_rcu_callbacks(void)
 {
 	have_rcu_kthread_work = 1;
-	wake_up(&rcu_kthread_wq);
+	swake_up(&rcu_kthread_wq);
 }
 
 /*
@@ -899,8 +900,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;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RT 7/7] Linux 3.2.38-rt58-rc1
  2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
                   ` (5 preceding siblings ...)
  2013-02-19  3:56 ` [PATCH RT 6/7] rcutiny: Use simple waitqueue Steven Rostedt
@ 2013-02-19  3:56 ` Steven Rostedt
  6 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:56 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users; +Cc: Thomas Gleixner, Carsten Emde, John Kacur

[-- Attachment #1: 0007-Linux-3.2.38-rt58-rc1.patch --]
[-- Type: text/plain, Size: 290 bytes --]

From: Steven Rostedt <srostedt@redhat.com>

---
 localversion-rt |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/localversion-rt b/localversion-rt
index c06cc435..1fdcd49 100644
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt57
+-rt58-rc1
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* io_apic.c   -->  "nr_ioapics" not initialized !
  2013-02-19  3:56 ` [PATCH RT 6/7] rcutiny: Use simple waitqueue Steven Rostedt
@ 2013-02-20 16:20   ` Armin Steinhoff
  2013-02-20 21:04     ` Robin Holt
  2013-02-20 22:55     ` Thomas Gleixner
  0 siblings, 2 replies; 13+ messages in thread
From: Armin Steinhoff @ 2013-02-20 16:20 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-rt-users


Hello,

after a walk through the module "io_apic.c" in 
"/usr/src/linux/arch/x86/kernel/apic" I got the impression that the 
variable "nr_ioapics" is used but isn't initialized !
Could it be the source of boot problems ?

Dangerous coding stile in "static struct resource * __init 
ioapic_setup_resources(int nr_ioapics)" ....
########

Cheers

--Armin



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: io_apic.c   -->  "nr_ioapics" not initialized !
  2013-02-20 16:20   ` io_apic.c --> "nr_ioapics" not initialized ! Armin Steinhoff
@ 2013-02-20 21:04     ` Robin Holt
  2013-02-20 22:55     ` Thomas Gleixner
  1 sibling, 0 replies; 13+ messages in thread
From: Robin Holt @ 2013-02-20 21:04 UTC (permalink / raw)
  To: Armin Steinhoff; +Cc: linux-kernel, linux-rt-users

On Wed, Feb 20, 2013 at 05:20:10PM +0100, Armin Steinhoff wrote:
> 
> Hello,
> 
> after a walk through the module "io_apic.c" in
> "/usr/src/linux/arch/x86/kernel/apic" I got the impression that the
> variable "nr_ioapics" is used but isn't initialized !

Just to be sure we are looking at the same thing, it is declared in
arch/x86/kernel/apic/io_apic.c on line 129.  Being declared that way,
it is, by definition, 0 unless there is an initializer.

Did I miss something?

Thanks,
Robin


> Could it be the source of boot problems ?
> 
> Dangerous coding stile in "static struct resource * __init
> ioapic_setup_resources(int nr_ioapics)" ....
> ########
> 
> Cheers
> 
> --Armin
> 
> 
> --
> 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: io_apic.c --> "nr_ioapics" not initialized !
  2013-02-20 16:20   ` io_apic.c --> "nr_ioapics" not initialized ! Armin Steinhoff
  2013-02-20 21:04     ` Robin Holt
@ 2013-02-20 22:55     ` Thomas Gleixner
  2013-02-21  7:30       ` Armin Steinhoff
  1 sibling, 1 reply; 13+ messages in thread
From: Thomas Gleixner @ 2013-02-20 22:55 UTC (permalink / raw)
  To: Armin Steinhoff; +Cc: LKML, linux-rt-users, x86

On Wed, 20 Feb 2013, Armin Steinhoff wrote:
> after a walk through the module "io_apic.c" in
> "/usr/src/linux/arch/x86/kernel/apic" I got the impression that the variable
> "nr_ioapics" is used but isn't initialized !
> Could it be the source of boot problems ?

Well no, unless your compiler is silly.
 
arch/x86/kernel/apic/io_apic.c:int nr_ioapics;

That's initialized to 0

> Dangerous coding stile in "static struct resource * __init
> ioapic_setup_resources(int nr_ioapics)" ....

Though the brilliant brain who decided to name the argument of
ioapic_setup_resources() the same as a global variable and of course
the call site of it to do:

    ioapic_res = ioapic_setup_resources(nr_ioapics);

Brilliant. Unfortunately that's completely correct C code. Though it's
confusing as hell and definitely worth to be fixed. Patch below.

Thanks,

	tglx

Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -3637,25 +3637,25 @@ void __init setup_ioapic_dest(void)
 
 static struct resource *ioapic_resources;
 
-static struct resource * __init ioapic_setup_resources(int nr_ioapics)
+static struct resource * __init ioapic_setup_resources(int cnt)
 {
 	unsigned long n;
 	struct resource *res;
 	char *mem;
 	int i;
 
-	if (nr_ioapics <= 0)
+	if (cnt <= 0)
 		return NULL;
 
 	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
-	n *= nr_ioapics;
+	n *= cnt;
 
 	mem = alloc_bootmem(n);
 	res = (void *)mem;
 
-	mem += sizeof(struct resource) * nr_ioapics;
+	mem += sizeof(struct resource) * cnt;
 
-	for (i = 0; i < nr_ioapics; i++) {
+	for (i = 0; i < cnt; i++) {
 		res[i].name = mem;
 		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 		snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: io_apic.c --> "nr_ioapics" not initialized !
  2013-02-20 22:55     ` Thomas Gleixner
@ 2013-02-21  7:30       ` Armin Steinhoff
  0 siblings, 0 replies; 13+ messages in thread
From: Armin Steinhoff @ 2013-02-21  7:30 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, linux-rt-users, x86

Thomas Gleixner wrote:
> On Wed, 20 Feb 2013, Armin Steinhoff wrote:
>> after a walk through the module "io_apic.c" in
>> "/usr/src/linux/arch/x86/kernel/apic" I got the impression that the variable
>> "nr_ioapics" is used but isn't initialized !
>> Could it be the source of boot problems ?
> Well no, unless your compiler is silly.
>   
> arch/x86/kernel/apic/io_apic.c:int nr_ioapics;
>
> That's initialized to 0

  My "silly compiler" does it only during load time ....

--Armin

>
>> Dangerous coding stile in "static struct resource * __init
>> ioapic_setup_resources(int nr_ioapics)" ....
> Though the brilliant brain who decided to name the argument of
> ioapic_setup_resources() the same as a global variable and of course
> the call site of it to do:
>
>      ioapic_res = ioapic_setup_resources(nr_ioapics);
>
> Brilliant. Unfortunately that's completely correct C code. Though it's
> confusing as hell and definitely worth to be fixed. Patch below.
>
> Thanks,
>
> 	tglx
>
> Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
> +++ linux-2.6/arch/x86/kernel/apic/io_apic.c
> @@ -3637,25 +3637,25 @@ void __init setup_ioapic_dest(void)
>   
>   static struct resource *ioapic_resources;
>   
> -static struct resource * __init ioapic_setup_resources(int nr_ioapics)
> +static struct resource * __init ioapic_setup_resources(int cnt)
>   {
>   	unsigned long n;
>   	struct resource *res;
>   	char *mem;
>   	int i;
>   
> -	if (nr_ioapics <= 0)
> +	if (cnt <= 0)
>   		return NULL;
>   
>   	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
> -	n *= nr_ioapics;
> +	n *= cnt;
>   
>   	mem = alloc_bootmem(n);
>   	res = (void *)mem;
>   
> -	mem += sizeof(struct resource) * nr_ioapics;
> +	mem += sizeof(struct resource) * cnt;
>   
> -	for (i = 0; i < nr_ioapics; i++) {
> +	for (i = 0; i < cnt; i++) {
>   		res[i].name = mem;
>   		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
>   		snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH RT 6/7] rcutiny: Use simple waitqueue
  2013-02-19  3:53 [PATCH RT 0/7] [ANNOUNCE] 3.4.32-rt46-rc1 stable review Steven Rostedt
@ 2013-02-19  3:53 ` Steven Rostedt
  0 siblings, 0 replies; 13+ messages in thread
From: Steven Rostedt @ 2013-02-19  3:53 UTC (permalink / raw)
  To: linux-kernel, linux-rt-users; +Cc: Thomas Gleixner, Carsten Emde, John Kacur

[-- Attachment #1: 0006-rcutiny-Use-simple-waitqueue.patch --]
[-- Type: text/plain, Size: 2381 bytes --]

From: Thomas Gleixner <tglx@linutronix.de>

Simple waitqueues can be handled from interrupt disabled contexts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/rcutiny_plugin.h |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
index 97e359b..2824dbd 100644
--- a/kernel/rcutiny_plugin.h
+++ b/kernel/rcutiny_plugin.h
@@ -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;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-02-21  7:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-19  3:56 [PATCH RT 0/7] [ANNOUNCE] 3.2.38-rt58-rc1 stable review Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 1/7] x86/32: Use kmap switch for non highmem as well Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 2/7] acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 3/7] printk: Fix rq->lock vs logbuf_lock unlock lock inversion Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 4/7] serial: Imx: Fix recursive locking bug Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 5/7] wait-simple: Simple waitqueue implementation Steven Rostedt
2013-02-19  3:56 ` [PATCH RT 6/7] rcutiny: Use simple waitqueue Steven Rostedt
2013-02-20 16:20   ` io_apic.c --> "nr_ioapics" not initialized ! Armin Steinhoff
2013-02-20 21:04     ` Robin Holt
2013-02-20 22:55     ` Thomas Gleixner
2013-02-21  7:30       ` Armin Steinhoff
2013-02-19  3:56 ` [PATCH RT 7/7] Linux 3.2.38-rt58-rc1 Steven Rostedt
  -- strict thread matches above, loose matches on Subject: below --
2013-02-19  3:53 [PATCH RT 0/7] [ANNOUNCE] 3.4.32-rt46-rc1 stable review Steven Rostedt
2013-02-19  3:53 ` [PATCH RT 6/7] rcutiny: Use simple waitqueue Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).