Kernel code interrupted by Timer

anish kumar anish198519851985 at gmail.com
Sat Feb 9 07:07:01 EST 2013


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?

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





More information about the Kernelnewbies mailing list