From: Antonino A. Daplas Date: Sat, 5 Aug 2006 19:14:16 +0000 (-0700) Subject: [PATCH] vt: printk: Fix framebuffer console triggering might_sleep assertion X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=78944e549d36673eb6265a2411574e79c28e23dc;p=linux-beck.git [PATCH] vt: printk: Fix framebuffer console triggering might_sleep assertion Reported by: Dave Jones Whilst printk'ing to both console and serial console, I got this... (2.6.18rc1) BUG: sleeping function called from invalid context at kernel/sched.c:4438 in_atomic():0, irqs_disabled():1 Call Trace: [] show_trace+0xaa/0x23d [] dump_stack+0x15/0x17 [] __might_sleep+0xb2/0xb4 [] __cond_resched+0x15/0x55 [] cond_resched+0x3b/0x42 [] console_conditional_schedule+0x12/0x14 [] fbcon_redraw+0xf6/0x160 [] fbcon_scroll+0x5d9/0xb52 [] scrup+0x6b/0xd6 [] lf+0x24/0x44 [] vt_console_print+0x166/0x23d [] __call_console_drivers+0x65/0x76 [] _call_console_drivers+0x5e/0x62 [] release_console_sem+0x14b/0x232 [] fb_flashcursor+0x279/0x2a6 [] run_workqueue+0xa8/0xfb [] worker_thread+0xef/0x122 [] kthread+0x100/0x136 [] child_rip+0x8/0x12 This can occur when release_console_sem() is called but the log buffer still has contents that need to be flushed. The console drivers are called while the console_may_schedule flag is still true. The might_sleep() is triggered when fbcon calls console_conditional_schedule(). Fix by setting console_may_schedule to zero earlier, before the call to the console drivers. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/kernel/printk.c b/kernel/printk.c index 65ca0688f86f..1149365e989e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -799,6 +799,9 @@ void release_console_sem(void) up(&secondary_console_sem); return; } + + console_may_schedule = 0; + for ( ; ; ) { spin_lock_irqsave(&logbuf_lock, flags); wake_klogd |= log_start - log_end; @@ -812,7 +815,6 @@ void release_console_sem(void) local_irq_restore(flags); } console_locked = 0; - console_may_schedule = 0; up(&console_sem); spin_unlock_irqrestore(&logbuf_lock, flags); if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) {