ARM64架构下Linux进程何时抢占?

    Linux系统下,进程调度有主动和被动之分,最终是调用schedule()函数。主动是指进程需要等待资源而主动让出CPU,被动就是抢占(PREEMPT)。

    主动schedule由业务代码自行决定,运行在Linux抢占式内核上要确保进程的运行时间就需要关注抢占。

抢占的过程分为两步:

设置调度标记   

    为CPU上正在运行的进程thread_info结构体里的flags成员设置TIF_NEED_RESCHED

执行抢占  

    kernel判断当前进程标记TIF_NEED_RESCHED并调用schedule()函数切换上下文

 

那么,什么时候设置TIF_NEED_RESCHED呢 ?

1.timer时钟中断

    时钟中断处理函数会调用scheduler_tick

从而调用当前进程调度类里的task_tick(rq, curr, 0)函数

最后由check_preempt_tick检测是否需要重新调度,如果需要就会设置调度标记。

2. 创建新进程的时候

    do_fork函数会调用task_fork设置TIF_NEED_RESCHED

对于实时调度类里面并没有设置task_fork回调函数,也就是说一个实时进程fork一个新进程的话不会设置调度标记。

3.唤醒进程的时候

    ttwu_do_wakeup 会调用 check_preempt_curr设置调度标志,设置的条件是

当前为CFS进程或者当前为RT进程但是新进程的优先级更高。

4.修改进程nice值的时候

    set_user_nice函数设置TIF_NEED_RESCHED的条件为正在运行的进程降低优先级或者其他进程增加优先级

5.负载均衡的时候

    CFS调度器3.18版本的kernel已经用smp_send_reschedule()

替代 resched_cpu()了

    RT调度器如果当前cpu上多于一个RT进程,就调用push_rt_task推给别的cpu,并且设置TIF_NEED_RESCHED

6.用户空间调用sched_setscheduler()设置调度policy

    用户态调用sched_setscheduler()设置调度policy的时候如果sched_class从低优先级switch到高优先级则会调用resched_curr()函数设置TIF_NEED_RESCHED

 

抢占的时机:

    设置TIF_NEED_RESCHED后就需要等待kernel在一定的时候去检测该flags从而调用schedule()函数切换上下文,kernel空间是可以关抢占的,user空间是无法关抢占的。抢占可分为内核态抢占和用户态抢占

1.用户态抢占

    arch/arm64/kernel/entry.S文件里

    在ret_to_user入口处最后会检查标志位再调用schedule

2.内核态抢占

    在中断返回内核态的入口el1_irq最后会调用

preempt_schedule_irq进而再调schedule

    当kernel调用preempt_enable函数的时候会执行preempt_schedule_common该函数再调用schedule

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值