set_tsk_need_resched():设置指定过程中的need_resched标记
[cpp] view plain copy
clear_tsk need_resched():清除指定过程中的need_resched标记
什么时刻须要从新调剂:
- 时钟中断处理例程检查当前义务的时光片,当义务的时光片消费完时,scheduler_tick()函数就会设置need_resched标记;
- 旌旗灯号量、比及队列、completion等机制唤醒时都是基于waitqueue的,而waitqueue的唤醒函数为default_wake_function,其调用try_to_wake_up将被唤醒的义务更改为就绪状况并设置need_resched标记。
- 设置用户过程的nice值瓯,可能会使高优先级的义务进入就绪状况;
- 改变义务的优先级时,可能会使高优先级的义务进入就绪状况;
- 新建一个义务时,可能会使高优先级的义务进入就绪状况;
- 对CPU(SMP)进行负载均衡时,当前义务可能须要放到别的一个CPU上运行;
3.4 抢占产生的机会(何时检查可抢占前提)
- 当一个中断处理例程退出,在返回到内核态时(kernel-space)。这是隐式的调用schedule()函数,当前义务没有主动放弃CPU应用权,而是被剥夺了CPU应用权。
- 当kernel code大年夜弗成抢占状况变为可抢占状况时(preemptible again)。也就是preempt_count大年夜正整数变为0时。这也是隐式的调用schedule()函数。
- 一个义务在内核态中显式的调用schedule()函数。义务主动放弃CPU应用权。
- 一个义务在内核态中被壅塞,导致须要调用schedule()函数。义务主动放弃CPU应用权。
3.5 禁用/使能可抢占前提的操作
对preempt_count操作的函数有add_preempt_count()、sub_preempt_count()、inc_preempt_count()、dec_preempt_count()。
使能可抢占前提的操作是preempt_enable(),它调用dec_preempt_count()函数,然后再调用preempt_check_resched()函数去检查是否须要从新调剂。
禁用可抢占前提的操作是preempt_disable(),它调用inc_preempt_count()函数。
在内核中有很多函数调用了preempt_enable()和preempt_disable()。比如spin_lock()函数调用了preempt_disable()函数,spin_unlock()函数调用了preempt_enable()函数。
3.6 什么时刻不许可抢占
preempt_count()函数用于获取preempt_count的值,preemptible()用于断定内核是否可抢占。
有几种情况Linux内核不该该被抢占,除此之外,Linux内核在随便率性一点都可被抢占。这几种情况是:
- 内核正进行中断处理。在Linux内核中过程不克不及抢占中断(中断只能被其他中断中断、抢占,过程不克不及中断、抢占中断),在中断例程中不许可进行过程调剂。过程调剂函数schedule()会对此作出断定,如不雅是在中断中调用,会打印掉足信息。
- 内核正在进行中断高低文的Bottom Half(中断的下半部)处理。硬件中断返回前会履行软中断,此时仍然处于中断高低文中。
- 内核的代码段正持有spinlock自旋锁、writelock/readlock读写锁等锁,处干这些锁的保护状况中。内核中的┞封些锁是为了在SMP体系中短时光内包管不合CPU上运行的过程并发履行的┞俘确性。当持有这些锁时,内核不该该被抢占,不然因为抢占将导致其他CPU经久不克不及获得锁而逝世等。
- 内核正在履行调剂法度榜样Scheduler。抢占的原因就是为了进行新的调剂,没有来由将调剂法度榜样抢占掉落再运行调剂法度榜样。
- 内核正在对每个CPU“私有”的数据构造操作(Per-CPU date structures)。在SMP中,对于per-CPU数据构造未竽暌姑spinlocks保护,因为这些数据构造隐含地被保护了(不合的CPU有不一样的per-CPU数据,其他CPU上运行的过程不会用到另一个CPU的per-CPU数据)。然则如不雅许可抢占,但一个过程被抢占后从新调剂,有可能调剂到其他的CPU上去,这时定义的Per-CPU变量就会有问题,这时应禁抢占。
4. Linux内核态抢占的实现
[cpp] view plain copy
- struct thread_info {
- struct task_struct *task; /* main task structure */
- struct exec_domain *exec_domain; /* execution domain */
- /**
- * 如不雅有TIF_NEED_RESCHED标记,则必须调用调剂法度榜样。
- */
- unsigned long flags; /* low level flags */
- /**
- * 线程标记:
- * TS_USEDFPU:表示过程在当前履行过程中,是否应用过FPU、MMX和XMM存放器。
推荐阅读
【51CTO晃荡】8.26 带你深度懂得清华大年夜学、搜狗基于算法的IT运维实践与摸索 摘要: 控制反转(Inversion of Control,英文缩写为IoC)是框架的重要特点。控制反转(IOC)是一种思惟,依附>>>详细阅读
本文标题:Linux内核态抢占机制分析
地址:http://www.17bianji.com/lsqh/36756.html
1/2 1