2003-05-22 07:26:13

by Duncan Sands

[permalink] [raw]
Subject: Use of sti in entry.S question

2.5/arch/i386/kernel/entry.S:

In work_resched, schedule may be called with
interrupts off:

work_resched:
call schedule
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
movl TI_FLAGS(%ebp), %ecx
andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
# than syscall tracing?
jz restore_all
testb $_TIF_NEED_RESCHED, %cl
jnz work_resched <====== schedule with interrupts disabled

Is this a mistake or an optimization? Elsewhere in entry.S, interrupts
are turned on before calling schedule:

#ifdef CONFIG_PREEMPT
ENTRY(resume_kernel)
cmpl $0,TI_PRE_COUNT(%ebp) # non-zero preempt_count ?
jnz restore_all
need_resched:
movl TI_FLAGS(%ebp), %ecx # need_resched set ?
testb $_TIF_NEED_RESCHED, %cl
jz restore_all
testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ?
jz restore_all
movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebp)
sti <====== schedule with interrupts enabled
call schedule
movl $0,TI_PRE_COUNT(%ebp)
cli
jmp need_resched
#endif

Thanks,

Duncan.


2003-05-22 08:15:34

by Andi Kleen

[permalink] [raw]
Subject: Re: Use of sti in entry.S question

Duncan Sands <[email protected]> writes:

> 2.5/arch/i386/kernel/entry.S:
>
> In work_resched, schedule may be called with
> interrupts off:
>
> work_resched:
> call schedule
> cli # make sure we don't miss an interrupt
> # setting need_resched or sigpending
> # between sampling and the iret
> movl TI_FLAGS(%ebp), %ecx
> andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
> # than syscall tracing?
> jz restore_all
> testb $_TIF_NEED_RESCHED, %cl
> jnz work_resched <====== schedule with interrupts disabled
>
> Is this a mistake or an optimization? Elsewhere in entry.S, interrupts
> are turned on before calling schedule:

It's a mistake, but a harmless one. The scheduler turns off interrupts
soon itself and the instructions it executes before that don't care.
The only reason it's not recommended to call schedule with interrupts
off is that the scheduler will turn them on again, usually breaking
your critical section. In this case it's ok because the next
instrution is a cli again.

-Andi

2003-05-22 20:35:44

by Duncan Sands

[permalink] [raw]
Subject: Re: Use of sti in entry.S question

...
> > Is this a mistake or an optimization? Elsewhere in entry.S, interrupts
> > are turned on before calling schedule:
>
> It's a mistake, but a harmless one. The scheduler turns off interrupts
> soon itself and the instructions it executes before that don't care.
> The only reason it's not recommended to call schedule with interrupts
> off is that the scheduler will turn them on again, usually breaking
> your critical section. In this case it's ok because the next
> instrution is a cli again.

Do you think it's worth pushing this fix?

diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S Thu May 22 22:45:50 2003
+++ b/arch/i386/kernel/entry.S Thu May 22 22:45:50 2003
@@ -306,6 +306,7 @@
testb $_TIF_NEED_RESCHED, %cl
jz work_notifysig
work_resched:
+ sti
call schedule
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending

2003-05-22 21:54:12

by Duncan Sands

[permalink] [raw]
Subject: Another use of sti in entry.S question

Here is another place where interrupts get turned on in a called
function:

work_resched disables interrupts and falls through to work_notifysig.
work_notifysig calls do_notify_resume.
do_notify_resume calls do_signal.
do_signal calls get_signal_to_deliver.
get_signal_to_deliver does an spin_unlock_irq before returning,
enabling interrupts.

Is this a bug?

work_resched:
sti
call schedule
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
movl TI_FLAGS(%ebp), %ecx
andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
# than syscall tracing?
jz restore_all
testb $_TIF_NEED_RESCHED, %cl
jnz work_resched

work_notifysig: # deal with pending signals and
# notify-resume requests
testl $VM_MASK, EFLAGS(%esp)
movl %esp, %eax
jne work_notifysig_v86 # returning to kernel-space or
# vm86-space
xorl %edx, %edx
call do_notify_resume <== may enable interrupts
jmp restore_all

ALIGN
work_notifysig_v86:
pushl %ecx
call save_v86_state
popl %ecx
movl %eax, %esp
xorl %edx, %edx
call do_notify_resume <== may enable interrupts
jmp restore_all