Kernel code interrupted by Timer
Peter Teoh
htmldeveloper at gmail.com
Sat Feb 9 11:13:21 EST 2013
On Sat, Feb 9, 2013 at 8:07 PM, anish kumar <anish198519851985 at gmail.com>wrote:
> Thanks Frederic.
> On Sat, 2013-02-09 at 08:44 +0100, Frederic Weisbecker wrote:
> > 2013/2/8 Gaurav Jain <gjainroorkee at gmail.com>:
> > > What happens if the kernel executing in some process context (let's say
> > > executing a time-consuming syscall) gets interrupted by the Timer -
> which is
> > > apparently allowed in 2.6 onwards kernels.
> > >
> > > My understanding is that once the interrupt handler is done executing,
> we
> > > should switch back to where the kernel code was executing.
> >
> > Exactly. At the end of the interrupt, the state of the processor
> > (register values) as it was before being interrupted is restored.
> >
> > > Specifically, the
> > > interrupt handler for the Timer interrupt should not schedule some
> other
> > > task since that might leave kernel data in an inconsistent state -
> kernel
> > > didn't finish doing whatever it was doing when interrupted.
> > >
> > > So, does the Timer interrupt handler include such a policy for the
> above
> > > case?
> >
> > In the case you have CONFIG_PREEMPT and it's the turn for some other
> > task to be scheduled, the function preempt_schedule_irq() is called
> > right before the irq return to the interrupted code. If the irq
> > interrupted preemptible code (code that was not under a
> > preempt_disable() section) then the scheduler may well schedule
> > another task.
> However if the code is under preempt_disable() when irq happened then it
> won't choose any other task and will come back immediately to the task
> which was preempted by the irq handler.
>
> I think what you are referring is below code:
>
> __irq_svc:
> svc_entry
> irq_handler
>
> #ifdef CONFIG_PREEMPT
> get_thread_info tsk
> ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
> ldr r0, [tsk, #TI_FLAGS] @ get flags
> teq r8, #0 @ if preempt count != 0
> movne r0, #0 @ force flags to 0
> tst r0, #_TIF_NEED_RESCHED
> blne svc_preempt
> #endif
>
> #ifdef CONFIG_PREEMPT
> svc_preempt:
> mov r8, lr
> 1: bl preempt_schedule_irq @ irq en/disable is done
> inside
> ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
> tst r0, #_TIF_NEED_RESCHED
> moveq pc, r8 @ go again
> b 1b
> #endif
>
>
> /*
> * this is the entry point to schedule() from kernel preemption
> * off of irq context.
> * Note, that this is called and return with irqs disabled. This will
> * protect us against recursive calling from irq.
> */
> asmlinkage void __sched preempt_schedule_irq(void)
> {
> struct thread_info *ti = current_thread_info();
>
> /* Catch callers which need to be fixed */
> BUG_ON(ti->preempt_count || !irqs_disabled());
>
> user_exit();
> do {
> add_preempt_count(PREEMPT_ACTIVE);
> local_irq_enable();
> __schedule();
> local_irq_disable();
> sub_preempt_count(PREEMPT_ACTIVE);
>
> /*
> * Check again in case we missed a preemption
> opportunity
> * between schedule and now.
> */
> barrier();
> } while (need_resched());
> }
>
> >
> > It may indeed sound suprising that we schedule from an interrupt but
> It is really *surprising* that we do scheduling from interrupt context.
> Doesn't Do's and Don't of scheduling from interrupt context apply here?
>
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.
for example, calling from here:
https://lkml.org/lkml/2012/5/2/298
so definitely this preempt_schedule_irq() calling from irq mode is rare -
at least for x86.
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".
>
> So how does the regular call to schedule() occur when task(process) time
> slice is over?
> > it's actually fine. Later on, the scheduler restores the previous task
> > to the middle of preempt_schedule_irq() and the irq completes its
> Sorry didn't understand this sentence i.e. "scheduler restores the
> previous task to the middle of preempt_schedule_irq()".
> > return to what it interrupted. The state of the processor prior to the
> > interrupt is stored on the task stack. So we can restore that anytime.
> > Note if the irq interrupted userspace, it can do about the same thing,
> > except it calls schedule() directly instead of preempt_schedule_irq().
> >
> > _______________________________________________
> > Kernelnewbies mailing list
> > Kernelnewbies at kernelnewbies.org
> > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
--
Regards,
Peter Teoh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130210/7b26666b/attachment.html
More information about the Kernelnewbies
mailing list