On Sat, Feb 9, 2013 at 8:07 PM, anish kumar <anish198519851...@gmail.com>wrote:
> Thanks Frederic. > On Sat, 2013-02-09 at 08:44 +0100, Frederic Weisbecker wrote: > > 2013/2/8 Gaurav Jain <gjainroor...@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@kernelnewbies.org > > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > > > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@kernelnewbies.org > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > -- Regards, Peter Teoh
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies