2002-07-11 20:27:58

by Oleg Nesterov

[permalink] [raw]
Subject: Q: preemptible kernel and interrupts consistency.

Hello.

Documentation/preempt-locking.txt states, that
disabled interrupts prevents preemption.

Well, unless process does not touch TIF_NEED_RESCHED.
Consider:

// preempt_count == 0
local_irq_disable();
set_tsk_need_resched(current);
preempt_disable();
preempt_enable();

We fall into the schedule() - possible preemtion,
interruppts ENABLED in any case.

Note that this may be implicit, for example:

__cli();
wake_up(q);
// spin_lock_irqsave(&q->lock, flags)
// __wake_up_common() - sets need_resched
// spin_unlock_irqrestore(q->lock, flags)
// spin_unlock()
// preempt_enable()
// irq_handler: I WAS HERE!!!
// possible preemtion
// local_irq_restore() - too late

Or I am just stupid?

Oleg.


2002-07-11 20:39:07

by Robert Love

[permalink] [raw]
Subject: Re: Q: preemptible kernel and interrupts consistency.

On Thu, 2002-07-11 at 13:33, Oleg Nesterov wrote:

> Documentation/preempt-locking.txt states, that
> disabled interrupts prevents preemption.
>
> Well, unless process does not touch TIF_NEED_RESCHED.

Yes, you are right, if need_resched is set under you, you will preempt
off the last unlock, even if interrupts are disabled.

However, the only places that set need_resched like that are the
scheduler and they do so also under lock so we are safe.

Also, in your example, being in an interrupt handler bumps the
preempt_count so even the scenario you give will not cause a
preemption. If we did not bump the unlock, then your example would give
a lot of "scheduling in interrupt" BUGs so we would know it ;-)

All that said, there is a bug: the send_reschedule IPI can set
need_resched on another CPU. If the other CPU happens to have
interrupts disabled, we can in fact preempt. I have a patch for this I
will submit shortly.

Robert Love

2002-07-11 21:13:43

by Oleg Nesterov

[permalink] [raw]
Subject: Re: Q: preemptible kernel and interrupts consistency.

Hello.

Robert Love wrote:
> However, the only places that set need_resched like that are the
> scheduler and they do so also under lock so we are safe.

Safe? Look, if process does not hold any spinlock and interrupts
disabled, then any distant implicit call to resched_task() silently
enables irqs. At least, this must be documented.

> Also, in your example, being in an interrupt handler bumps the
> preempt_count so even the scenario you give will not cause a
> preemption. If we did not bump the unlock, then your example would give
> a lot of "scheduling in interrupt" BUGs so we would know it ;-)

No, I meant process context in both scenarios! Note also, that it
happens even in UP case.

> All that said, there is a bug: the send_reschedule IPI can set
> need_resched on another CPU. If the other CPU happens to have
> interrupts disabled, we can in fact preempt.

I can't see, how this can happen. Can you explain?
But it seems unrelated...

Oleg.

2002-07-11 21:25:41

by Robert Love

[permalink] [raw]
Subject: Re: Q: preemptible kernel and interrupts consistency.

On Thu, 2002-07-11 at 14:19, Oleg Nesterov wrote:

> Safe? Look, if process does not hold any spinlock and interrupts
> disabled, then any distant implicit call to resched_task() silently
> enables irqs. At least, this must be documented.

If interrupts are disabled, where is this distant implicit call from
resched_task() coming from?

That was my point, aside from interrupt handlers all the
need_resched-touching code is in sched.c and both Ingo and I verified
everything is locked.

If interrupts are disabled, there are no interrupts handlers. And if
you are in an interrupt handler, preemption is already disabled.

Robert Love

2002-07-11 22:02:09

by Oleg Nesterov

[permalink] [raw]
Subject: Re: Q: preemptible kernel and interrupts consistency.

Hello.

I am sorry, may be i do not understand something obvious.

Robert Love wrote:
> That was my point, aside from interrupt handlers all the
> need_resched-touching code is in sched.c and both Ingo and I verified
> everything is locked.
>
> If interrupts are disabled, there are no interrupts handlers. And if
> you are in an interrupt handler, preemption is already disabled.

Is it legal to call wake_up_process(some_task) from process context,
with irqs disabled, and current->preempt_count == 0 ?

Then current may have need_resched flag set, and task_rq_unlock() falls
into schedule().

Oleg.