作家
登录

Linux内核态抢占机制分析

作者: 来源: 2017-08-17 12:19:20 阅读 我要评论

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

  1. struct thread_info {   
  2.  
  3.     struct task_struct  *task;      /* main task structure */   
  4.  
  5.     struct exec_domain  *exec_domain;   /* execution domain */   
  6.  
  7.     /**  
  8.  
  9.      * 如不雅有TIF_NEED_RESCHED标记,则必须调用调剂法度榜样。  
  10.  
  11.      */   
  12.  
  13.     unsigned long       flags;      /* low level flags */   
  14.  
  15.     /**  
  16.  
  17.      * 线程标记:  
  18.  
  19.      *     TS_USEDFPU:表示过程在当前履行过程中,是否应用过FPU、MMX和XMM存放器。  

      推荐阅读

      PHP如何实现依赖注入

    【51CTO晃荡】8.26 带你深度懂得清华大年夜学、搜狗基于算法的IT运维实践与摸索 摘要: 控制反转(Inversion of Control,英文缩写为IoC)是框架的重要特点。控制反转(IOC)是一种思惟,依附>>>详细阅读


    本文标题:Linux内核态抢占机制分析

    地址:http://www.17bianji.com/lsqh/36756.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)