linux中断返回时的任务抢占

在退出中断程序的时候会判断是否需要进入调度器进行抢占,通过_TIF_NEED_RESCHED标记,代码如下:

__irq_svc:
    svc_entry
    irq_handler

#ifdef CONFIG_PREEMPTION
    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

    svc_exit r5, irq = 1            @ return from exception
 UNWIND(.fnend        )
ENDPROC(__irq_svc)

如果需要抢占则会进入svc_preempt -> preempt_schedule_irq -> __schedule
如果不进行抢占,由svc_exit执行中断退出(寄存器恢复到被中断的进程)
我的问题是:

  1. 因为抢占是不能进行在中断上下文中的(书上这么说的,我认为应该是中断栈不能单独保存的原因),所以执行__schedule的时候已经在进程上下文,但是为什么这里就是进程上下文了呢?堆栈不都还是在中断里吗。

  2. 例如在进程A的过程中触发了中断,在svc_preempt进行了抢占,切换到了任务B,这时的svc_exit没有得到执行,寄存器状态还在中断栈,从任务B再切换回来时中断栈可能已经被其他中断破坏,怎么能够返回到任务A呢?