Thanks Frederic. On Sat, 2013-02-09 at 08:44 +0100, Frederic Weisbecker wrote: > 2013/2/8 Gaurav Jain <gjainroorkee@xxxxxxxxx>: > > 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? 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@xxxxxxxxxxxxxxxxx > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies