天下网吧 >> 网吧系统 >> 系统教程 >> 正文

详解Linux系统内核抢占补丁的相关原理

2014-8-1不详佚名
68239">

  CPU在内核中运行时并不是处处不可抢占的,内核中存在一些空隙,在这时进行抢占是安全的,内核抢占补丁的基本原理就是将SMP可并行的代码段看成是可以进行内核抢占的区域。

  2.4内核正好细化了多CPU下的内核线程同步机构,对不可并行的指令块用spinlock和rwlock作了细致的表示,该补丁的实现可谓水到渠成。具体的方法就是在进程的任务结构上增加一个preempt_count变量作为内核抢占锁,它随着spinlock和rwlock一起加锁和解锁。当preempt_count为0时表示可以进行内核调度。内核调度器的入口为preempt_schedule(),它将当前进程标记为TASK_PREEMPTED状态再调用schedule(),在TASK_PREEMPTED状态,SChedule()不会将进程从运行队列中删除。

  下面是内核抢占补丁的主要代码示意:

  arch/i386/kernel/entry.S:

  preempt_count = 4 # 将task_struct中的flags用作preempt_count,flags被移到了别

  的位置

  ret_from_exception: # 从异常返回

  #ifdef CONFIG_SMP

  GET_CURRENT(%ebx)

  movl processor(%ebx),%eax

  shll $CONFIG_X86_L1_CACHE_SHIFT,%eax

  movl SYMBOL_NAME(irq_stat)(,%eax),%ecx # softirq_active

  testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx # softirq_mask

  #else

  movl SYMBOL_NAME(irq_stat),%ecx # softirq_active

  testl SYMBOL_NAME(irq_stat)+4,%ecx # softirq_mask

  #endif

  jne handle_softirq

  #ifdef CONFIG_PREEMPT

  cli

  incl preempt_count(%ebx) # 异常的入口没有禁止内核调度的指令,与ret_from_intr

  匹配一下

  #endif

  ENTRY(ret_from_intr) # 硬件中断的返回

  GET_CURRENT(%ebx)

  #ifdef CONFIG_PREEMPT

  cli

  decl preempt_count(%ebx) # 恢复内核抢占标志

  #endif

  movl EFLAGS(%esp),%eax # mix EFLAGS and CS

  moVB CS(%esp),%al

  testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?

  jne ret_with_reSChedule

  #ifdef CONFIG_PREEMPT

  cmpl $0,preempt_count(%ebx)

  jnz restore_all # 如果preempt_count非零则表示禁止内核抢占


本文来源:不详 作者:佚名

声明
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。若文章侵犯了您的相关权益,请及时与我们联系,我们会及时处理,感谢您对本站的支持!联系Email:support@txwb.com,系统开号,技术支持,服务联系QQ:1175525021本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧·网吧天下