linux抢占式内核的描述
2012-02-16 10:36
253 查看
User Preemption
User preemptionoccurs 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 touser-space, it knows it is in a safe
quiescent state. In other words, if it issafe to continue executing the current task, it is also safe to pick a new taskto execute. Consequently, whenever the kernel is preparing to return touser-space either on return from an interrupt or after a system call,
the valueof need_resched is checked. If it is set, the scheduler is invoked to select anew (more fit) process to execute. Both the return paths for return frominterrupt and return from system call are architecture dependent and typicallyimplemented in assembly
in entry.S (which, aside from kernel entry code, alsocontains kernel exit code).
In short, userpreemption can occur
When returning touser-space from a system call
When returning touser-space from an interrupt handler
Kernel Preemption
The Linux kernel,unlike most other Unix variants and many other operating systems, is a fullypreemptive kernel. In non-preemptive kernels, kernel code runs untilcompletion. That is, the scheduler
is not capable of rescheduling a task whileit is in the kernelkernel code is scheduled cooperatively, not preemptively.Kernel code runs until it finishes (returns to user-space) or explicitlyblocks. In the 2.6 kernel, however, the Linux kernel became preemptive:
It isnow possible to preempt a task at any point, so long as the kernel is in astate in which it is safe to reschedule.
So when is it safeto reschedule? The kernel is capable of preempting a task running in the kernelso long as it does not hold a lock. That is, locks are used as markers ofregions of non-preemptibility.
Because the kernel is SMP-safe, if a lock is notheld, the current code is reentrant and capable of being preempted.
The first change insupporting kernel preemption was the addition of a preemption counter,preempt_count, to each process's thread_info. This counter begins at zero andincrements once for each lock
that is acquired and decrements once for eachlock that is released. When the counter is zero, the kernel is preemptible.Upon return from interrupt, if returning to kernel-space, the kernel checks thevalues of need_resched and preempt_count. If need_resched
is set andpreempt_count is zero, then a more important task is runnable and it is safe topreempt. Thus, the scheduler is invoked. If preempt_count is nonzero, a lock isheld and it is unsafe to reschedule. In that case, the interrupt returns asusual to the
currently executing task. When all the locks that the current taskis holding are released, preempt_count returns to zero. At that time, theunlock code checks whether need_resched is set. If so, the scheduler isinvoked. Enabling and disabling kernel preemption
is sometimes required inkernel code and is discussed in Chapter 9.
Kernel preemptioncan also occur explicitly, when a task in the kernel blocks or explicitly callsschedule(). This form of kernel preemption has always been supported because noadditional logic is required
to ensure that the kernel is in a state that issafe to preempt. It is assumed that the code that explicitly calls schedule()knows it is safe to reschedule.
Kernel preemptioncan occur
When an interrupthandler exits, before returning to kernel-space
When kernel codebecomes preemptible again
If a task in thekernel explicitly calls schedule()
If a task in thekernel blocks (which results in a call to schedule())
User preemptionoccurs 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 touser-space, it knows it is in a safe
quiescent state. In other words, if it issafe to continue executing the current task, it is also safe to pick a new taskto execute. Consequently, whenever the kernel is preparing to return touser-space either on return from an interrupt or after a system call,
the valueof need_resched is checked. If it is set, the scheduler is invoked to select anew (more fit) process to execute. Both the return paths for return frominterrupt and return from system call are architecture dependent and typicallyimplemented in assembly
in entry.S (which, aside from kernel entry code, alsocontains kernel exit code).
In short, userpreemption can occur
When returning touser-space from a system call
When returning touser-space from an interrupt handler
Kernel Preemption
The Linux kernel,unlike most other Unix variants and many other operating systems, is a fullypreemptive kernel. In non-preemptive kernels, kernel code runs untilcompletion. That is, the scheduler
is not capable of rescheduling a task whileit is in the kernelkernel code is scheduled cooperatively, not preemptively.Kernel code runs until it finishes (returns to user-space) or explicitlyblocks. In the 2.6 kernel, however, the Linux kernel became preemptive:
It isnow possible to preempt a task at any point, so long as the kernel is in astate in which it is safe to reschedule.
So when is it safeto reschedule? The kernel is capable of preempting a task running in the kernelso long as it does not hold a lock. That is, locks are used as markers ofregions of non-preemptibility.
Because the kernel is SMP-safe, if a lock is notheld, the current code is reentrant and capable of being preempted.
The first change insupporting kernel preemption was the addition of a preemption counter,preempt_count, to each process's thread_info. This counter begins at zero andincrements once for each lock
that is acquired and decrements once for eachlock that is released. When the counter is zero, the kernel is preemptible.Upon return from interrupt, if returning to kernel-space, the kernel checks thevalues of need_resched and preempt_count. If need_resched
is set andpreempt_count is zero, then a more important task is runnable and it is safe topreempt. Thus, the scheduler is invoked. If preempt_count is nonzero, a lock isheld and it is unsafe to reschedule. In that case, the interrupt returns asusual to the
currently executing task. When all the locks that the current taskis holding are released, preempt_count returns to zero. At that time, theunlock code checks whether need_resched is set. If so, the scheduler isinvoked. Enabling and disabling kernel preemption
is sometimes required inkernel code and is discussed in Chapter 9.
Kernel preemptioncan also occur explicitly, when a task in the kernel blocks or explicitly callsschedule(). This form of kernel preemption has always been supported because noadditional logic is required
to ensure that the kernel is in a state that issafe to preempt. It is assumed that the code that explicitly calls schedule()knows it is safe to reschedule.
Kernel preemptioncan occur
When an interrupthandler exits, before returning to kernel-space
When kernel codebecomes preemptible again
If a task in thekernel explicitly calls schedule()
If a task in thekernel blocks (which results in a call to schedule())
相关文章推荐
- 嵌入式linux内核启动过程简明描述
- Linux 内核clk相关数据结构描述
- Linux信号处理内核情景描述(转)
- linux系统下抢占式内核与非抢占式内核的区别
- Linux 内核设备驱动之GPIO驱动之GPIO 控制器描述
- Linux 内核设备驱动之GPIO驱动之GPIO 控制器设备描述
- Linux 内核设备驱动之GPIO驱动之GPIO 管脚描述
- linux物理内存描述(接近新版本内核)
- linux2.6内核内存描述符与线性区分析
- Linux 内核clk框架描述
- Linux 内核学习之内存管理(一) 总体描述
- linux查看内核版本、系统版本、系统位数(32or64)
- 详解Linux2.6内核中基于platform机制的驱动模型
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序 (学习老罗的)
- linux2.6.37.4内核在XC2440开发板上移植(八)USB HOST驱动移植
- linux内核——list_for_each_entry
- Linux计算机进程地址空间与内核装载ELF
- Linux下进程及其描述task_struct
- linux 内核调试
- linux内核移植-移植2.6.35.4内核到s3c2440