<br><br><div class="gmail_quote">On Sat, Feb 9, 2013 at 8:07 PM, anish kumar <span dir="ltr"><<a href="mailto:anish198519851985@gmail.com" target="_blank">anish198519851985@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks Frederic.<br>
<div>On Sat, 2013-02-09 at 08:44 +0100, Frederic Weisbecker wrote:<br>
> 2013/2/8 Gaurav Jain <<a href="mailto:gjainroorkee@gmail.com" target="_blank">gjainroorkee@gmail.com</a>>:<br>
> > What happens if the kernel executing in some process context (let's say<br>
> > executing a time-consuming syscall) gets interrupted by the Timer - which is<br>
> > apparently allowed in 2.6 onwards kernels.<br>
> ><br>
> > My understanding is that once the interrupt handler is done executing, we<br>
> > should switch back to where the kernel code was executing.<br>
><br>
> Exactly. At the end of the interrupt, the state of the processor<br>
> (register values) as it was before being interrupted is restored.<br>
><br>
> > Specifically, the<br>
> > interrupt handler for the Timer interrupt should not schedule some other<br>
> > task since that might leave kernel data in an inconsistent state - kernel<br>
> > didn't finish doing whatever it was doing when interrupted.<br>
> ><br>
> > So, does the Timer interrupt handler include such a policy for the above<br>
> > case?<br>
><br>
> In the case you have CONFIG_PREEMPT and it's the turn for some other<br>
> task to be scheduled, the function preempt_schedule_irq() is called<br>
> right before the irq return to the interrupted code. If the irq<br>
> interrupted preemptible code (code that was not under a<br>
> preempt_disable() section) then the scheduler may well schedule<br>
> another task.<br>
</div>However if the code is under preempt_disable() when irq happened then it<br>
won't choose any other task and will come back immediately to the task<br>
which was preempted by the irq handler.<br>
<br>
I think what you are referring is below code:<br>
<br>
__irq_svc:<br>
svc_entry<br>
irq_handler<br>
<br>
#ifdef CONFIG_PREEMPT<br>
get_thread_info tsk<br>
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count<br>
ldr r0, [tsk, #TI_FLAGS] @ get flags<br>
teq r8, #0 @ if preempt count != 0<br>
movne r0, #0 @ force flags to 0<br>
tst r0, #_TIF_NEED_RESCHED<br>
blne svc_preempt<br>
#endif<br>
<br>
#ifdef CONFIG_PREEMPT<br>
svc_preempt:<br>
mov r8, lr<br>
1: bl preempt_schedule_irq @ irq en/disable is done<br>
inside<br>
ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS<br>
tst r0, #_TIF_NEED_RESCHED<br>
moveq pc, r8 @ go again<br>
b 1b<br>
#endif<br>
<br>
<br>
/*<br>
* this is the entry point to schedule() from kernel preemption<br>
* off of irq context.<br>
* Note, that this is called and return with irqs disabled. This will<br>
* protect us against recursive calling from irq.<br>
*/<br>
asmlinkage void __sched preempt_schedule_irq(void)<br>
{<br>
struct thread_info *ti = current_thread_info();<br>
<br>
/* Catch callers which need to be fixed */<br>
BUG_ON(ti->preempt_count || !irqs_disabled());<br>
<br>
user_exit();<br>
do {<br>
add_preempt_count(PREEMPT_ACTIVE);<br>
local_irq_enable();<br>
__schedule();<br>
local_irq_disable();<br>
sub_preempt_count(PREEMPT_ACTIVE);<br>
<br>
/*<br>
* Check again in case we missed a preemption<br>
opportunity<br>
* between schedule and now.<br>
*/<br>
barrier();<br>
} while (need_resched());<br>
<div>}<br>
<br>
><br>
> It may indeed sound suprising that we schedule from an interrupt but<br>
</div>It is really *surprising* that we do scheduling from interrupt context.<br>
Doesn't Do's and Don't of scheduling from interrupt context apply here?<br></blockquote><div><br></div><div>A search in the entire subtree of arch/x86/ and including all its subdirectories, (for 3.2.0 kernel) return only TWO result where preempt_schedule_irq is called: kernel/entry_64.S and kernel/entry_32.S. And the called is in fact resume_kernel(), ie, it is NOT called from timer interrupt, but from wakeup context of the CPU, and is only executed ONCE upon waking up from hibernation. </div>
<div><br></div><div>for example, calling from here:</div><div><br></div><div><a href="https://lkml.org/lkml/2012/5/2/298">https://lkml.org/lkml/2012/5/2/298</a></div>
<div><br></div><div>so definitely this preempt_schedule_irq() calling from irq mode is rare - at least for x86.</div><div><br></div><div>but the code u have shown above is for ARM, i tried to understand it, but could not comment much....except that it CONFIG_PREEMPT is still very popular: out of 121 of different ARM boards, about 46 still need it to be "y".</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
So how does the regular call to schedule() occur when task(process) time<br>
slice is over?<br>
<div>> it's actually fine. Later on, the scheduler restores the previous task<br>
> to the middle of preempt_schedule_irq() and the irq completes its<br>
</div>Sorry didn't understand this sentence i.e. "scheduler restores the<br>
previous task to the middle of preempt_schedule_irq()".<br>
<div><div>> return to what it interrupted. The state of the processor prior to the<br>
> interrupt is stored on the task stack. So we can restore that anytime.<br>
> Note if the irq interrupted userspace, it can do about the same thing,<br>
> except it calls schedule() directly instead of preempt_schedule_irq().<br>
><br>
> _______________________________________________<br>
> Kernelnewbies mailing list<br>
> <a href="mailto:Kernelnewbies@kernelnewbies.org" target="_blank">Kernelnewbies@kernelnewbies.org</a><br>
> <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
<br>
<br>
<br>
_______________________________________________<br>
Kernelnewbies mailing list<br>
<a href="mailto:Kernelnewbies@kernelnewbies.org" target="_blank">Kernelnewbies@kernelnewbies.org</a><br>
<a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>Regards,<br>Peter Teoh