kernel-内核抢占
这里有两个概念,内核抢占与用户态抢占。什么是内核抢占?就是指程序执行系统调用的时候(也就是执行于内核态的时候)被其他内核线程抢占走了。
有2种情况是不会也不应该被抢占的:
- 内核正在执行中断处理函数
- 内核处于临界区。正在执行自旋锁。
除了以上情况以外,就可能被抢占了。
如何知道当前是否为抢占系统vim /boot/config-3.10.0-123.9.3.el7.x86_64
查看相应的选项
如何配置抢占
2.6内核以后支持内核抢占。但需要配置:
内核抢占开关三个选项:
PREEMPT_NONE
———CONFIG_PREEMPT
和CONFIG_PREEMPT_VOLUNTARY
都不会设置,表示在内核态既不会被抢占,调might_resched()
函数也不会主动切换- Low latency desktop—-只配置
CONFIG_PREEMPT_VOLUNTARY
,might_resched()函数生效,内核态依然不会被抢占 - PREEMPT——————
CONFIG_PREEMPT
和CONFIG_PREEMPT_VOLUNTARY
同时生效,在中断返回内核态时会检查TIF_NEEDRESCHED
标志,如果需要调度,则会调schedule,内核态被抢占
CONFIG_PREEMPT_VOLUNTARY
是资源被抢占,是内核在耗时操作中间,时不时插入一行代码,主动要求被schedule。
CONFIG_PREEMPT
则是被动的抢占了。
The Linux 2.6 configuration option
CONFIG_PREEMPT_VOLUNTARY
introduces checks to the most common causes of long latencies, so that the kernel can voluntarily yield control to a higher priority task waiting to execute. This can be helpful, but while it reduces the occurences of long latencies (hundreds of milliseconds to potentially seconds or more), it does not eliminate them. However unlikeCONFIG_PREEMPT
(discussed below),CONFIG_PREEMPT_VOLUNTARY
has a much lower impact on the overall throughput of the system. (As always, there is a classical tradeoff between throughput — the overall efficiency of the system — and latency. With the faster CPU’s of modern-day systems, it often makes sense to trade off throughput for lower latencies, but server class systems that do not need minimum latency guarantees may very well choose to use eitherCONFIG_PREEMPT_VOLUNTARY
, or to stick with the traditional non-preemptible kernel design.)
The 2.6 Linux kernel has an additional configuration option,
CONFIG_PREEMPT
, which causes all kernel code outside of spinlock-protected regions and interrupt handlers to be eligible for non-voluntary preemption by higher priority kernel threads. With this option, worst case latency drops to (around) single digit milliseconds, although some device drivers can have interrupt handlers that will introduce latency much worse than that. If a real-time Linux application requires latencies smaller than single-digit milliseconds, use of theCONFIG_PREEMPT_RT
patch is highly recommended.
抢占用得越狠,那么对于高优先级的任务,latency就越低。但是抢占本身也是耗时的,频繁的上下文切换肯定影响系统吞吐量的,因此总体性能会降一点。一般这样都是划算的,反正现在CPU很强,稍微降一点关系不大。但是如果真的不需要对latency要求那么苛刻,那么关掉抢占,或者只打开自愿抢占(CONFIG_PREEMPT_VOLUNTARY
)也是可以的。目前一般是嵌入式实时系统打开这个选项。
服务器版 一般是 CONFIG_PREEMPT_NONE=y
个人版 一般是 CONFIG_PREEMPT_VOLUNTARY=y
#ifdef CONFIG_PREEMPT_VOLUNTARY
extern int _cond_resched(void);
# define might_resched() _cond_resched()
#else
# define might_resched() do { } while (0)
#endif