资源描述:
《Linux内核抢占补丁的基本原理》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Linux内核抢占补丁的基本原理-ChinaLinuxForum中国Linux论坛首页技术论坛
2、文章荟萃
3、藏经阁
4、项目计划
5、在线调查
6、网站镜像
7、软件仓库
8、关于本站
9、讨论区列表
10、搜寻文章
11、新用户注册
12、登入论坛
13、在线用户
14、常见问题Linux高级应用此话题阅读次数:2821上一篇索引下一篇平坦模式树状模式>>Linux内核技术打印jklLinux内核抢占补丁的基本原理(addict)01-04-18CPU在内核中运行时并不是处处不可抢占的,内核中存在一些空隙,在这时进行抢占是安全的,内?br>饲勒疾苟〉幕•驹•砭褪墙玈13:45MP可并行的代
15、码段看成是可以进行内核抢占的区域。2.4内核正好细化了多CPU下的内核线程同步机构,对不可并行的指令块用spinlock和rwlock作了细致的表示,该苟〉氖迪挚晌剿•角•伞?具体的方法就是在进程的任务结构上增加一个preempt_count变量作为内核抢占锁,它随着spinlock和rwlock一起加锁和解锁。当preempt_count为0时表示可以进行内核调度。内核调度器的入口为preempt_schedule(),它将当前进程标记为TASK_PREEMPTED状态再调用schedule(),在TASK_PREEMPTED状态,s
16、chedule()不会将进程从运行队列中删除。下面是内核抢占补丁的主要代码示意:arch/i386/kernel/entry.S:preempt_count=4#将task_struct中的flags用作preempt_count,flags被移到了别的位置ret_from_exception:#从异常返回#ifdefCONFIG_SMPGET_CURRENT(%ebx)movlprocessor(%ebx),%eaxshll$CONFIG_X86_L1_CACHE_SHIFT,%eaxmovlSYMBOL_NAME(irq_stat)
17、(,%eax),%ecx#softirq_activetestlSYMBOL_NAME(irq_stat)+4(,%eax),%ecx#softirq_mask#elsemovlSYMBOL_NAME(irq_stat),%ecx#softirq_activetestlSYMBOL_NAME(irq_stat)+4,%ecx#softirq_mask#endifjnehandle_softirq#ifdefCONFIG_PREEMPTcliinclpreempt_count(%ebx)#异常的入口没有禁止内核调度的指令,与ret_fro
18、m_intr匹配一下#endifENTRY(ret_from_intr)#硬件中断的返回GET_CURRENT(%ebx)#ifdefCONFIG_PREEMPTclideclpreempt_count(%ebx)#恢复内核抢占标志#endifmovlEFLAGS(%esp),%eax#mixEFLAGSandCSmovbCS(%esp),%altestl$(VM_MASK
19、3),%eax#returntoVM86modeornon-supervisor?jneret_with_reschedule#ifdefCONFIG_PREEMP
20、Tcmpl$0,preempt_count(%ebx)jnzrestore_all#如果preempt_count非零则表示禁止内核抢占cmpl$0,need_resched(%ebx)http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=linuxK&Number=103261&page=&view=&sb=&o=(1of7)2005-4-2811:41:30Linux内核抢占补丁的基本原理-ChinaLinuxForumjzrestore_all#movlSYMBOL
21、_NAME(irq_stat)+irq_stat_local_bh_countCPU_INDX,%ecxaddlSYMBOL_NAME(irq_stat)+irq_stat_local_irq_countCPU_INDX,%ecxjnzrestore_allinclpreempt_count(%ebx)sticallSYMBOL_NAME(preempt_schedule)jmpret_from_intr#新进程返回,返回ret_from_intr恢复抢占标志后再返回#elsejmprestore_all#endifALIGNhandl
22、e_softirq:#ifdefCONFIG_PREEMPTcliGET_CURRENT(%ebx)inclpreempt_count(%ebx)sti#endifcallSYMBOL_NAME(do_so