2002-09-03 13:30:54

by Morten Helgesen

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

Hey guys,

got this one on my Inspiron 2500 - and still can`t 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

--

"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


2002-09-03 14:48:27

by Robert Love

[permalink] [raw]
Subject: [PATCH] bad: schedule() with irqs disabled!

On Tue, 2002-09-03 at 09:36, Morten Helgesen wrote:

> 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

diff -urN linux-2.5.33/kernel/sched.c linux/kernel/sched.c
--- linux-2.5.33/kernel/sched.c Sat Aug 31 18:04:53 2002
+++ linux/kernel/sched.c Tue Sep 3 10:48:56 2002
@@ -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;