内核抢占
这两个概念分别是核心进程抢占有权与用户态进程抢占有权。那么什么是核心进程抢占有权呢?当程序在执行系统调用时(即处于核心进程运行状态时),会被其他核心线程抢占有权。
有2种情况是不会也不应被抢占的:
- 内核不应被调度函数所抢占
- 内核位于同步区域内执行自旋锁定机制
除了以上情况以外,就可能被抢占了。
如何知道当前是否为抢占系统
vim /boot/config-3.10.0-123.9.3.el7.x86_64
查看相应的选项
如何配置抢占
2.6版本的内核增加了支持内核抢占功能。
具体配置参数如下:
- 配置模式为PREEMPT_NONE时,默认关闭CONFIG_PREEMPT和CONFIG_PREEMPT_VOLUNTARY,并确保在内核态不会被抢占调度,并且might_resched()函数也不会主动切换。
- 适合低延迟场景的配置模式仅启用CONFIG_PREEMPT VOLUNTARY参数,并使might_resch()函数执行相应的操作;此时的 内 kernel 态依然保持稳定。
- 高优先级任务模式下同时启用(CONFIG PRE EM PT 和 CONFIG PRE EM PT VOL U NT ARY)两个参数;当中断返回到 kernel 态时会检查 TIF NEED RESHED 标志位;若该标志位有效,则自动触发 schedule 任务并进行调度。
CONFIG_PREEMPT_VOLUNTARY代表了资源发生抢占的情况,在执行耗时操作期间,内核会不时插入一行代码以主动申请加入队列。
CONFIG_PREEMPT则表示一种被动地发生抢劫行为。
The Linux 2.6配置选项CONFIG_PREEMPT_VOLUNTARY通过包含针对常见长时间延迟原因的检查机制来优化性能,从而允许内核在等待执行的高优先级任务之间自愿地剥夺控制权,这对提升系统效率非常有用。然而,虽然该配置能够显著减少长时间延迟的发生次数(从几毫秒到可能达到几秒甚至更长时间),但它并不能完全消除这些延迟。与configured_preempt不同的是,CONFIG_PREEMPT_VOLUNTARY对系统的整体吞吐量影响较小,因此更适合大多数普通用途场景。(如同往常一样,在现代计算平台上,随着CPU速度的提升,通常会通过减少吞吐量来换取更低延迟的效果;但对于那些无需最低延迟保证的服务器类系统来说,选择使用CONFIG_PREEMPT_VOLUNTARY或者采用传统的非预 emptible内核设计都是合理的选择)
抢占使用得越凶猛,则针对高优先级的任务将具有更低的延迟。然而由于抢占本身就需要耗费一定的时间,在频繁发生的情况下必然会影响到系统的吞吐量水平。因此整体性能会有所下降一点。这样做通常是合算的毕竟当前使用的处理器性能已经非常强大即使略微降低一些性能也不会有明显的影响但如果确实不需要特别追求低延迟的需求则可以选择关闭整个抢占机制或者仅启用自愿型抢占(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
