中断处理中的延迟调度和内核抢占

init_IRQ()
    set_intr_gate
    设置中断处理例程为:push $vector;
                                  jmp  common_interrupt;

common_interrupt
    SAVE_ALL
    do_irq
        irq_enter


        if(需要切换堆栈)
                切换堆栈

        desc->handle_irq(如:8259A,在init_IRQ中通过set_irq_chip_and_handler_name函数把handle_irq设置为handle_level_irq)
        handle_level_irq()
        mask_ack_irq(向中断控制器发出中断应答,并通知中断控制器屏蔽这条中断请求线,对于某些多处理器来水,该行仅在当前CPU上屏蔽该中断)
        handle_IRQ_event
            do
            {
                action->handler();
                action=action->next;
            }
            while(action)

        if(需要切换堆栈)
            切换堆栈        
        irq_exit
            do_softirq
                __do_softirq
    jmp ret_from_intr
1 处理延迟的调度请求
    这里通过一个例子更容易理解,假设有ph和pl两个进程,进程ph优先级大于pl,现在ph通过系统调用(比如sys_read),进入内核态,它进行磁盘IO操作,但磁盘缓存队列中没有现成的数据,于是磁盘磁盘驱动程序向磁盘发出读请求,此时进程ph主动放弃CPU,进入等待队列。然后进程pl被调度运行,片刻后,磁盘完成读操作并向CPU发出中断,磁盘中断服务历程通知调度器把进程ph重新加入就绪队列,调度器此时发现就绪队列中ph的优先级大于当前进程pl,于是请求调度ph。但是延迟到中断处理结束。此时pl没有主动放弃CPU,而是被进程ph抢占了cpu资源。进程ph的调度时机分为以下两种情况:
        1)中断发生时,pl运行在用户态环境,此时中断处理结束后,在返回进程pl用户态前,内核检查到这个延迟的调度请求,于是通知调度器重新调度。调度器根据调度算法选择进程ph运行。

        如果是在中断处理过程中发生了异常,而异常处理程序也会走到这段代码,并且异常处理程序可能已经修复了这个异常,此时被你异常中断的中断处理程序更为紧急,所以这种情况下,先不处理延迟的调度,等中断处理返回时在处理这个延迟的调度。

        2)中断发生时,pl运行在内核态,此时如果内核在编译时配置了CONFIG_PREEMPT,则直接通知调度器重新调度,如果没有,则不允许在内核态发生抢占。于是恢复中断现场,返回进程pl的内核态继续运行。当进程pl在内核态因请求某种资源得不到满足而主动放弃CPU,或者进程pl要返回用户空态前时,这个延迟的请求调度才会被处理。
2 延迟的信号处理。
3 vm86模式处理。
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值