Skip to contentSkip to conversation

[2.5.33] bad: schedule() with irqs disabled!

PATCH New Morten Helgesen 2 participants 2 messages Sep 3, 2002

lore
Share & tools
lore
#0 lore raw

Hey guys,

got this one on my Inspiron 2500 - and still cant see a fix in Linus bk-tree. Do people agree that do_softirq() is the bad guy ? Anyone looking into this ? I haven`t got the time right now as I am both trying to figure out the qlogicisp.c mess and trying to get a working i81x framebuffer in 2.5.33. But I do think it is time we get it fixed.

bad: schedule() with irqs disabled!
c1c05e2c c025c540 c11605e0 c1c05e54 c0111fd8 00000005 c03139d8 fffffffa c1c05e50 00000046 c1c05e64 c0111fef c11605e0 00000000 c03139c0 c011a170 c1c04000 00000004 00000000 00000000 00000246 c022e5c0 c02e9460 00000004

Call Trace: 

[try_to_wake_up+256/268]
[wake_up_process+11/16]
[do_softirq+160/172]
[tcp_recvmsg+2124/2372]
[inet_recvmsg+61/84]
[_recvfrom+144/272]
[smb_get_length+22/172]
[smb_receive_header+69/236]
[smb_request_recv+106/462]
[smbiod_doio+28/160]
[smbiod+358/436]
[smbiod+0/436]
[default_wake_function+0/52]
[kernel_thread_helper+5/12]

== Morten

Signature · 8 lines
"Livet er ikke for nybegynnere" - sitat fra en klok person.

mvh
Morten Helgesen 
UNIX System Administrator & C Developer 
Nextframe AS
[email protected] / 93445641
http://www.nextframe.net
#1 lore raw

PATCH 1/1 bad: schedule() with irqs disabled!

Quoted 1 line · Morten Helgesen

bad: schedule() with irqs disabled!

OK, Linus, you are right... there are enough instances of this we are not going to find them all (although I suspect Andrew's slab.c fixes will cover most of the cases). Further, I think we can should actually purposely call preempt_schedule() in certain cases after interrupt reenable to check for reschedules...

Let's just make it a rule "no preemption if interrupts are off" and enforce that.

Patch is against 2.5.33-BK, please apply.

Robert Love

kernel/sched.c +5 -8
diff -urN linux-2.5.33/kernel/sched.c linux/kernel/sched.c
@@ -1032,15 +1032,12 @@
 {
 	struct thread_info *ti = current_thread_info();
 
-	if (unlikely(ti->preempt_count))
+	/*
+	 * If there is a non-zero preempt_count or interrupts are disabled,
+	 * we do not want to preempt the current task.  Just return..
+	 */
+	if (unlikely(ti->preempt_count || irqs_disabled()))
 		return;
-	if (unlikely(irqs_disabled())) {
-		preempt_disable();
-		printk("bad: schedule() with irqs disabled!\n");
-		show_stack(NULL);
-		preempt_enable_no_resched();
-		return;
-	}
 
 need_resched:
 	ti->preempt_count = PREEMPT_ACTIVE;