调度器类sched_class
内核版本:linux 6.15.7按优先级,从高到低:STOP>RT>FAIR>EXT>IDLE二、调度器类存在哪调度器类按照优先级存在__sched_class_highest开始、以__sched_class_lowest结束的段中。每个调度器类存在在对应的xx_sched_class段中。链接脚本vmlinux.lds.h控制了各个调度器类在段中的位置顺序,这个顺序决定了优先级关系。__se
内核版本:linux 6.15.7
一、sched_class种类
按优先级,从高到低:STOP > RT > FAIR(cfs) > EXT(sched_ext) > IDLE
[root@hadoop02 linux-6.15.7]# grep -nr "DEFINE_SCHED_CLASS"
kernel/sched/ext.c:4121:DEFINE_SCHED_CLASS(ext) = {
kernel/sched/deadline.c:3140:DEFINE_SCHED_CLASS(dl) = {
kernel/sched/rt.c:2613:DEFINE_SCHED_CLASS(rt) = {
kernel/sched/fair.c:13627:DEFINE_SCHED_CLASS(fair) = {
kernel/sched/idle.c:516:DEFINE_SCHED_CLASS(idle) = {
kernel/sched/stop_task.c:97:DEFINE_SCHED_CLASS(stop) = {
二、sched_class作用
sched_class(Scheduling Class)描述不同类别任务的调度逻辑,比如实时任务(RT),normal任务(FAIR等),struct sched_class提供一个通用模板,具体的调度器类需要实现其中的函数。
struct sched_class {
#ifdef CONFIG_UCLAMP_TASK
int uclamp_enabled;
#endif
void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
bool (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
void (*yield_task) (struct rq *rq);
bool (*yield_to_task)(struct rq *rq, struct task_struct *p);
void (*wakeup_preempt)(struct rq *rq, struct task_struct *p, int flags);
……
三、调度器类存在哪
调度器类按照优先级存在__sched_class_highest开始、以__sched_class_lowest结束的段中。
每个调度器类存在对应的xx_sched_class段中。
链接脚本vmlinux.lds.h控制了各个调度器类在段中的位置顺序,这个顺序决定了优先级关系。
__section("__" #name "_sched_class")定义了各调度器类存放的段名xx_sched_class。
kernel/sched/sched.h
#define DEFINE_SCHED_CLASS(name) \
const struct sched_class name##_sched_class \
__aligned(__alignof__(struct sched_class)) \
__section("__" #name "_sched_class")
__sched_class_highest和__sched_class_lowest两个变量是在vmlinux.lds.h中定义的,调度器类按照优先级存在__sched_class_highest开始的段中。
kernel/sched/sched.c
/* Defined in include/asm-generic/vmlinux.lds.h */
extern struct sched_class __sched_class_highest[];
extern struct sched_class __sched_class_lowest[];
vmlinux.lds.h中决定了这些调度器类在段中的存放位置顺序。
include/asm-generic/vmlinux.lds.h
/*
* The order of the sched class addresses are important, as they are
* used to determine the order of the priority of each sched class in
* relation to each other.
*/
#define SCHED_DATA \
STRUCT_ALIGN(); \
__sched_class_highest = .; \
*(__stop_sched_class) \
*(__dl_sched_class) \
*(__rt_sched_class) \
*(__fair_sched_class) \
*(__ext_sched_class) \
*(__idle_sched_class) \
__sched_class_lowest = .;
四、调度器的遍历操作
kernel/sched/sched.h
#define for_each_class(class) \
for_class_range(class, __sched_class_highest, __sched_class_lowest)
一个 task在任意时刻只能属于一个 sched_class,由struct task_struct->sched_class决定:
struct task_struct {
const struct sched_class *sched_class;
五、调度器类的函数集
以struct sched_class为模板,各个调度器类需要实现部分或全部函数接口,在代码中可以搜索关键字"DEFINE_SCHED_CLASS",以sched_ext调度器类为例:
DEFINE_SCHED_CLASS(ext) = {
.enqueue_task = enqueue_task_scx,
.dequeue_task = dequeue_task_scx,
.yield_task = yield_task_scx,
.yield_to_task = yield_to_task_scx,
.wakeup_preempt = wakeup_preempt_scx,
.balance = balance_scx,
.pick_task = pick_task_scx,
.put_prev_task = put_prev_task_scx,
.set_next_task = set_next_task_scx,
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_scx,
.task_woken = task_woken_scx,
.set_cpus_allowed = set_cpus_allowed_scx,
.rq_online = rq_online_scx,
.rq_offline = rq_offline_scx,
#endif
.task_tick = task_tick_scx,
.switching_to = switching_to_scx,
.switched_from = switched_from_scx,
.switched_to = switched_to_scx,
.reweight_task = reweight_task_scx,
.prio_changed = prio_changed_scx,
.update_curr = update_curr_scx,
#ifdef CONFIG_UCLAMP_TASK
.uclamp_enabled = 1,
#endif
}
更多推荐
所有评论(0)