调度器40—sched_features
基于 msm-5.4
一、features 框架实现
1. features的定义
相关文件:
kernel/sched/features.h
kernel/sched/sched.h
kernel/sched/debug.c
kernel/sched/core.c
1.1 kernel/sched/sched.h
//(1) #define SCHED_FEAT(name, enabled) \ __SCHED_FEAT_##name , enum { #include "features.h" __SCHED_FEAT_NR, }; #undef SCHED_FEAT //(2) #define SCHED_FEAT(name, enabled) \ static __always_inline bool static_branch_##name(struct static_key *key) \ { \ return static_key_##enabled(key); \ } #include "features.h" #undef SCHED_FEAT extern struct static_key sched_feat_keys[__SCHED_FEAT_NR]; #define sched_feat(x) (static_branch_##x(&sched_feat_keys[__SCHED_FEAT_##x]))
(1) 有个 enum 联合体, 里面每个元素都是 __SCHED_FEAT_<Name>, 总个数为 __SCHED_FEAT_NR 个。
(2) 导出下面 debug.c 中定义的 sched_feat_keys[], 并提供 sched_feat(x) 给使用者判断此 feature 是否使能了。
kernel/sched/debug.c
//(3) #define SCHED_FEAT(name, enabled) \ #name , static const char * const sched_feat_names[] = { #include "features.h" }; #undef SCHED_FEAT //(4) #define jump_label_key__true STATIC_KEY_INIT_TRUE #define jump_label_key__false STATIC_KEY_INIT_FALSE #define SCHED_FEAT(name, enabled) \ jump_label_key__##enabled , struct static_key sched_feat_keys[__SCHED_FEAT_NR] = { #include "features.h" }; #undef SCHED_FEAT
(3) sched_feat_names[] 是一个由 features 名字组成的数组
(4) sched_feat_keys[] 中每个 feature 的位置都根据其定义状态存储为 STATIC_KEY_INIT_TRUE 或 STATIC_KEY_INIT_FALSE
kernel/sched/core.c
//(5) #define SCHED_FEAT(name, enabled) \ (1UL << __SCHED_FEAT_##name) * enabled | const_debug unsigned int sysctl_sched_features = #include "features.h" 0; #undef SCHED_FEAT
(5) 定义一个全局变量 sysctl_sched_features, 其值是所有使能 features 的位掩码。
2. feature 判断接口
给外界判断此 feature 是否使能的接口就是 sched_feat(), 例如 if (sched_feat(TTWU_QUEUE))
3. feature 动态开关接口
(1) /sys/kernel/debug/sched_features
//kernel/sched/debug.c static int sched_feat_show(struct seq_file *m, void *v) { int i; for (i = 0; i < __SCHED_FEAT_NR; i++) { /* 对于disable的feature打印"NO_"开头,对于使能的feature直接打印feature的名字 */ if (!(sysctl_sched_features & (1UL << i))) seq_puts(m, "NO_"); seq_printf(m, "%s ", sched_feat_names[i]); } seq_puts(m, "\n"); return 0; } static int sched_feat_set(char *cmp) { int i; int neg = 0; /* 若是 echo “NO_” 就是关闭指定 feature */ if (strncmp(cmp, "NO_", 3) == 0) { neg = 1; cmp += 3; } /* 返回匹配到的feature的下标,若是没有匹配到返回小于0的值 */ i = match_string(sched_feat_names, __SCHED_FEAT_NR, cmp); if (i < 0) return i; if (neg) { sysctl_sched_features &= ~(1UL << i); /* 将 sched_feat_keys[i] 中的值也设置成正确的状态,这里是disable,下面是enable */ sched_feat_disable(i); } else { sysctl_sched_features |= (1UL << i); sched_feat_enable(i); } return 0; }
实验:
# cat /sys/kernel/debug/sched_features GENTLE_FAIR_SLEEPERS START_DEBIT NO_NEXT_BUDDY LAST_BUDDY CACHE_HOT_BUDDY WAKEUP_PREEMPTION NO_HRTICK NO_DOUBLE_TICK NONTASK_CAPACITY NO_TTWU_QUEUE
NO_SIS_AVG_CPU SIS_PROP NO_WARN_DOUBLE_CLOCK RT_PUSH_IPI NO_RT_RUNTIME_SHARE NO_LB_MIN ATTACH_AGE_LOAD WA_IDLE WA_WEIGHT WA_BIAS UTIL_EST
NO_SUGOV_RT_MAX_FREQ UTIL_EST_FASTUP # echo TTWU_QUEUE > /sys/kernel/debug/sched_features # cat /sys/kernel/debug/sched_features GENTLE_FAIR_SLEEPERS START_DEBIT NO_NEXT_BUDDY LAST_BUDDY CACHE_HOT_BUDDY WAKEUP_PREEMPTION NO_HRTICK NO_DOUBLE_TICK NONTASK_CAPACITY TTWU_QUEUE
NO_SIS_AVG_CPU SIS_PROP NO_WARN_DOUBLE_CLOCK RT_PUSH_IPI NO_RT_RUNTIME_SHARE NO_LB_MIN ATTACH_AGE_LOAD WA_IDLE WA_WEIGHT WA_BIAS UTIL_EST
NO_SUGOV_RT_MAX_FREQ UTIL_EST_FASTUP
小结: cat sched_features 文件,对于 disable 的 feature 打印"NO_"开头的名字,对于使能的feature直接打印feature的名字。echo 名字是使能此feature,echo "NO_"开头的名字是关闭此feature。
注1: user版本也有这个文件。
注2: kernel-5.15 中还有一个导出位置 /proc/sched_features
(2) /proc/sched_debug
static void sched_debug_header(struct seq_file *m) { ... P(sysctl_sched_features); ... } //实验: / # cat /proc/sched_debug .sysctl_sched_features : 6236475
小结: cat 依十进制打印使能的 features 的掩码。
posted on 2022-10-02 20:51 Hello-World3 阅读(675) 评论(0) 收藏 举报
浙公网安备 33010602011771号