ioremap problems

Anton Blanchard anton at samba.org
Tue Jan 27 21:55:33 EST 2004


> Just got this might sleep warning when using recent 2.6 ameslab. Looks
> like __add_new_im_area is doing a kmalloc inside a spinlock. Someone
> in the mood to fix it up? Im a little side tracked at the moment :)

Heres the spinlock sleep debugging patch. Give it a spin on a 2.6
kernel (dont forget to enable the config option), I'll bet there are still
5 bugs in our drivers left to find.

Anton

--


Sleep with spinlock debugging.


 gr16c-anton/arch/ppc64/Kconfig          |    7 +++++++
 gr16c-anton/include/asm-ppc64/hardirq.h |    2 +-
 gr16c-anton/include/linux/preempt.h     |   17 +++++++++++------
 gr16c-anton/kernel/sched.c              |    4 ++--
 4 files changed, 21 insertions(+), 9 deletions(-)

diff -puN arch/ppc64/Kconfig~spinlock_sleep arch/ppc64/Kconfig
--- gr16c/arch/ppc64/Kconfig~spinlock_sleep	2004-01-23 15:05:56.365930995 +1100
+++ gr16c-anton/arch/ppc64/Kconfig	2004-01-23 15:05:56.384934743 +1100
@@ -410,6 +410,13 @@ config DEBUG_PAGEALLOC
 	  This results in a large slowdown, but helps to find certain types
 	  of memory corruptions.

+config DEBUG_SPINLOCK_SLEEP
+	bool "Sleep-inside-spinlock checking"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, various routines which may sleep will become very
+	  noisy if they are called with a spinlock held.
+
 endmenu

 source "security/Kconfig"
diff -puN include/asm-ppc64/hardirq.h~spinlock_sleep include/asm-ppc64/hardirq.h
--- gr16c/include/asm-ppc64/hardirq.h~spinlock_sleep	2004-01-23 15:05:56.368931587 +1100
+++ gr16c-anton/include/asm-ppc64/hardirq.h	2004-01-23 15:05:56.385934940 +1100
@@ -80,7 +80,7 @@ typedef struct {

 #define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)

-#ifdef CONFIG_PREEMPT
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP)
 # define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
diff -puN include/linux/preempt.h~spinlock_sleep include/linux/preempt.h
--- gr16c/include/linux/preempt.h~spinlock_sleep	2004-01-23 15:05:56.372932376 +1100
+++ gr16c-anton/include/linux/preempt.h	2004-01-23 15:05:56.387935334 +1100
@@ -24,6 +24,17 @@ do { \

 extern void preempt_schedule(void);

+#define preempt_check_resched() \
+do { \
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
+		preempt_schedule(); \
+} while (0)
+#else
+#define preempt_check_resched()		do { } while (0)
+#endif
+
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP)
+
 #define preempt_disable() \
 do { \
 	inc_preempt_count(); \
@@ -36,12 +47,6 @@ do { \
 	dec_preempt_count(); \
 } while (0)

-#define preempt_check_resched() \
-do { \
-	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
-		preempt_schedule(); \
-} while (0)
-
 #define preempt_enable() \
 do { \
 	preempt_enable_no_resched(); \
diff -puN kernel/fork.c~spinlock_sleep kernel/fork.c
diff -puN kernel/sched.c~spinlock_sleep kernel/sched.c
--- gr16c/kernel/sched.c~spinlock_sleep	2004-01-23 15:05:56.379933756 +1100
+++ gr16c-anton/kernel/sched.c	2004-01-23 15:05:56.393936518 +1100
@@ -728,7 +728,7 @@ void sched_fork(task_t *p)
 	INIT_LIST_HEAD(&p->run_list);
 	p->array = NULL;
 	spin_lock_init(&p->switch_lock);
-#ifdef CONFIG_PREEMPT
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP)
 	/*
 	 * During context-switch we hold precisely one spinlock, which
 	 * schedule_tail drops. (in the common case it's this_rq()->lock,
@@ -2659,7 +2659,7 @@ void __init init_idle(task_t *idle, int
 	local_irq_restore(flags);

 	/* Set the preempt count _outside_ the spinlocks! */
-#ifdef CONFIG_PREEMPT
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP)
 	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
 #else
 	idle->thread_info->preempt_count = 0;

_

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list