以下宏在./kernel/sched/sched.h
#define sched_feat(x) (static_branch_##x(&sched_feat_keys[__SCHED_FEAT_##x]))
#else /* !(SCHED_DEBUG && HAVE_JUMP_LABEL) */
#define sched_feat(x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x))
#endif /* SCHED_DEBUG && HAVE_JUMP_LABEL */
我无法理解它扮演的角色。
答案 0 :(得分:4)
调度程序代码中使用sched_feat()
宏来测试是否启用了某个调度程序功能。例如,在kernel/sched/core.c
中,有一段代码
int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner)
{
if (!sched_feat(OWNER_SPIN))
return 0;
正在测试是否设置了“如果互斥锁所有者正在运行时互斥获取的自旋等待”功能。您可以在kernel/sched/features.h
中看到调度程序功能的完整列表,但简短的总结是它们是可在运行时设置的可调参数,而无需通过/sys/kernel/debug/sched_features
重建内核。
例如,如果您未更改系统上的默认设置,则会在/sys/kernel/debug/sched_features
中看到“OWNER_SPIN”,这意味着上面代码段中的!sched_feat(OWNER_SPIN)
将评估为false并且调度程序代码将继续存入mutex_spin_on_owner()
中的其余代码。
您部分复制的宏定义比您预期的更复杂的原因是它在可用时使用jump labels功能,并且需要在频繁运行的调度程序代码路径中消除这些条件测试的开销。 (跳转标签版本仅在配置中设置HAVE_JUMP_LABEL
时使用,原因很明显,并且设置SCHED_DEBUG
时,因为否则调度程序功能位在运行时不能更改)您可以按照将上面的链接链接到lwn.net以获取更多详细信息,但简而言之,跳转标签是一种使用运行时二进制修补的方法,以更便宜的方式对标志进行条件测试,但代价是更换标志更加昂贵。
您还可以查看scheduler commit that introduced jump label use,了解代码过去是如何更简单但效率不高。