Chinaunix首页 | 论坛 | 博客
  • 博客访问: 358432
  • 博文数量: 167
  • 博客积分: 2867
  • 博客等级: 少校
  • 技术积分: 1306
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-12 00:08
文章分类

全部博文(167)

文章存档

2017年(10)

2016年(5)

2015年(9)

2014年(10)

2013年(5)

2012年(17)

2011年(110)

2010年(1)

我的朋友

分类: LINUX

2011-05-03 13:40:38

Linux抢占式内核就是由Robert Love修改实现的。在他的书中有如下描述:
-----------
User Preemption
User preemption occurs when the kernel is about to return to user-space, need_resched is set, and therefore, the scheduler is invoked. If the kernel is returning to user-space, it knows it is in a safe quiescent state. In other words, if it is safe to continue executing the current task, it is also safe to pick a new task to execute. Consequently, whenever the kernel is preparing to return to user-space either on return from an interrupt or after a system call, the value of need_resched is checked. If it is set, the scheduler is invoked to select a new (more fit) process to execute. Both the return paths for return from interrupt and return from system call are architecture dependent and typically implemented in assembly in entry.S (which, aside from kernel entry code, also contains kernel exit code).
In short, user preemption can occur
When returning to user-space from a system call
When returning to user-space from an interrupt handler
用户空间的抢占发生在内核就要返回用户空间的时候,此时如果need_resched被设置,那么,scheduleer就会被调度。如果内核在返回用户空间的时候,它知道此时抢占的安全时刻。换句话说,如果它能够安全的执行当前的进程,那么重新调度一个新的进程来执行也是安全的。这样,当内核返回用户空间的时候,无论是从中断处理程序中返回,还是从系统调用中返回,它都会去检测need_resched的数值.如果need_resched被设置,调度器就会选择一个新的进程来运行。两个返回路径:从中断中返回和从系统调用中返回都是依赖于架构的,在文件entry.S中实现,这里不仅包含了内核进入代码,也包含了内核退出代码。
总之,用户空间的抢占发生在:
当内核从系统调用返回用户空间的时候
当内核从中断处理函数返回用户空间的时候

Kernel Preemption
The Linux kernel, unlike most other Unix variants and many other operating systems, is a fully preemptive kernel. In non-preemptive kernels, kernel code runs until completion. That is, the scheduler is not capable of rescheduling a task while it is in the kernel,kernel code is scheduled cooperatively, not preemptively. Kernel code runs until it finishes (returns to user-space) or explicitly blocks. In the 2.6 kernel, however, the Linux kernel became preemptive: It is now possible to preempt a task at any point, so long as the kernel is in a state in which it is safe to reschedule.
内核抢占
linux内核,不象其它大多数unix变种和许多别的操作系统那样,是完全内核抢占。在非抢占内核中,内核代码一直运行知道结束。也就是说,调度器是不能够重新调度进程的当运行在内核空间时。内核代码的调度是互相合作的,是不可抢占的。内核代码一直运行知道自己结束或者被显示的阻塞。然而在2.6内核中,内核变成可抢占的:现在可以在任何时间点抢占一个任务,只要内核处在重新调度安全的状态。
So when is it safe to reschedule? The kernel is capable of preempting a task running in the kernel so long as it does not hold a lock. That is, locks are used as markers of regions of non-preemptibility. Because the kernel is SMP-safe, if a lock is not held, the current code is reentrant and capable of being preempted.
那么什么时候重新调度是安全的呢?内核能够抢占一个运行在内核空间的任务,只要这个任务进程不持有锁。也就是说锁被用来当做非抢占区域的标志。因为内核是SMP安全的,如果锁没有被持有,那么当前代码就是可重入的,能够被抢占。
The first change in supporting kernel preemption was the addition of a preemption counter, preempt_count, to each process's thread_info. This counter begins at zero and increments once for each lock that is acquired and decrements once for each lock that is released. When the counter is zero, the kernel is preemptible. Upon return from interrupt, if returning to kernel-space, the kernel checks the values of need_resched and preempt_count. If need_resched is set and preempt_count is zero, then a more important task is runnable and it is safe to preempt. Thus, the scheduler is invoked. If preempt_count is nonzero, a lock is held and it is unsafe to reschedule. In that case, the interrupt returns as usual to the currently executing task. When all the locks that the current task is holding are released, preempt_count returns to zero. At that time, the unlock code checks whether need_resched is set. If so, the scheduler is invoked. Enabling and disabling kernel preemption is sometimes required in kernel code and is discussed in Chapter 9.
在支持可抢占内核中的第一个变化就是在每个进程的thread_info结构体中增加了一个抢占计数器,preempt_count。这个计数器从零开始,进程获得一次锁,这个值就增加一,释放一次锁,这个值就减一。当这个计数器是零时,内核就是可抢占的。从中断返回的时候,如果是返回到内核空间,内核会检查need_resched, preempt_count这两个数值,如果need_resched被设置,且preempt_count是零,那么更加重要的进程任务就会编程可运行状态,此时抢占是安全的。这样,调度器就会被调用。如果preempt_count不是非零,那么当前进程持有锁,这时候抢占是不安全的,在那种情况下,中断象通常一样返回到当前执行的任务。当当前进程持有的所有的锁都释放掉的时候,preempt_count = 0,这个时候,解锁的代码检查need_resched是否被设置,
如果被设置,调度器会被调用。允许和禁止内核抢占有时候在内核代码中被要求,这个会在第九章讨论。
Kernel preemption can also occur explicitly, when a task in the kernel blocks or explicitly calls schedule(). This form of kernel preemption has always been supported because no additional logic is required to ensure that the kernel is in a state that is safe to preempt. It is assumed that the code that explicitly calls schedule() knows it is safe to reschedule.
内核抢占也能显示的发生,当一个运行在内核空间的进程阻塞住了或者调用了schedule()函数。这种形式的内核抢占一直都被支持,因为没有额外的逻辑需要来保证内核处于抢占安全的状态。既然代码显示的调用了schedule(),那么就认为重新调度是安全的。
Kernel preemption can occur
When an interrupt handler exits, before returning to kernel-space
When kernel code becomes preemptible again
If a task in the kernel explicitly calls schedule()
If a task in the kernel blocks (which results in a call to schedule())
内核抢占发生时机:
当中断处理程序退出,返回内核空间前。
当一个在内核空间的进程显示的调用schedule()的时候
当一个在内核空间的进程发生阻塞的时候(结果也是调用schedule())
阅读(1116) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~