如何创build一个新的Linux内核调度程序

查看调度程序源代码(2.6.34,kernel / sched.c),我可以看到“可插拔”调度程序是如何使用的,我相信我理解要实现的接口。 我不明白的是如何让我的代码内置到内核。 至less,指向其他网站,将不胜感激。

现在,我在内核源代码树中查找SCHED_FIFO,SCHED_RR和SCHED_NORMAL,所以我正在寻找更有见地的方式来看看它:-)

编辑:作为一些背景,我非常熟悉FreeBSD调度程序(以及一般的FreeBSD内核),所以我不在寻找如何执行进程/线程级调度的指针。 我正在寻找一种方法来将我自己的调度程序与普通的linux调度程序(类似于SCHED_FIFO)一起添加。

编辑#2:下面的BFS指针是一个好的开始,但它仍然将CFS从内核中剥离出来。 sched.c现在看起来像:

#ifdef CONFIG_SCHED_BFS #include "sched_bfs.c" #else // original sched.c #endif // CONFIG_SCHED_BFS 

我很乐意看到一个答案或一个指示,说明如何做得更好(即保持CFS,至less现在)。

编辑#3:我已经回答了我自己的问题,因为我想我已经知道了。

Solutions Collecting From Web of "如何创build一个新的Linux内核调度程序"

我已经想出了我的问题的答案,所以我想我会在这里添加它。 下面是将添加一个新的调度程序到2.6.34 vanilla内核的补丁。 现在,我只编译了内核。 我完全期望用这个EXACT补丁运行一个系统会导致它崩溃 – 所以请自担风险:-)

 diff --git a/include/linux/sched.hb/include/linux/sched.h index 2b7b81d..a2a2b21 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -37,6 +37,7 @@ #define SCHED_RR 2 #define SCHED_BATCH 3 /* SCHED_ISO: reserved but not implemented yet */ +#define SCHED_NEW 4 /* Stealing from SCHED_ISO */ #define SCHED_IDLE 5 /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ #define SCHED_RESET_ON_FORK 0x40000000 diff --git a/init/Kconfig b/init/Kconfig index eb77e8c..0055d26 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -23,6 +23,11 @@ config CONSTRUCTORS menu "General setup" +config SCHED_NEW + bool "NEW cpu scheduler" + ---help--- + Brand new scheduler + config EXPERIMENTAL bool "Prompt for development and/or incomplete code/drivers" ---help--- diff --git a/kernel/sched.cb/kernel/sched.c index 3c2a54f..588960d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1931,6 +1931,7 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) #include "sched_idletask.c" #include "sched_fair.c" +#include "sched_new.c" #include "sched_rt.c" #ifdef CONFIG_SCHED_DEBUG # include "sched_debug.c" diff --git a/kernel/sched_new.cb/kernel/sched_new.c new file mode 100644 index 0000000..c2e269e --- /dev/null +++ b/kernel/sched_new.c @@ -0,0 +1,140 @@ +#ifdef CONFIG_SCHED_NEW + +/* + * Starting with a simple, 1 runq per cpu scheduler. Don't care + * about fairness for right now. Just get it up and running to + * verify that we have the interface correct + */ + +static void +enqueue_task_new(struct rq *rq, struct task_struct *p, int wakeup, bool head) +{ +} + +static void dequeue_task_new(struct rq *rq, struct task_struct *p, int sleep) +{ +} + +static void yield_task_new(struct rq *rq) +{ +} + +static void check_preempt_curr_new(struct rq *rq, struct task_struct *p, int flags) +{ +} + +static struct task_struct *pick_next_task_new(struct rq *rq) +{ +} + +static void put_prev_task_new(struct rq *rq, struct task_struct *p) +{ +} + +#ifdef CONFIG_SMP +static int select_task_rq_new(struct task_struct *p, int sd_flag, int flags) +{ +} +static void pre_schedule_new(struct rq *rq, struct task_struct *prev) +{ +} + +static void post_schedule_new(struct rq *rq) +{ +} + +static void task_woken_new(struct rq *rq, struct task_struct *p) +{ +} + +static void task_waking_new(struct rq *this_rq, struct task_struct *task) +{ +} +static void set_cpus_allowed_new(struct task_struct *p, + const struct cpumask *new_mask) +{ +} +/* Assumes rq->lock is held */ +static void rq_online_new(struct rq *rq) +{ +} + +/* Assumes rq->lock is held */ +static void rq_offline_new(struct rq *rq) +{ +} +#endif /* COMFIG_SMP */ + +static void set_curr_task_new(struct rq *rq) +{ +} + + +static void task_tick_new(struct rq *rq, struct task_struct *p, int queued) +{ +} + +static void task_fork_new(struct task_struct *p) +{ +} +static void switched_from_new(struct rq *rq, struct task_struct *p, + int running) +{ +} +static void switched_to_new(struct rq *this_rq, struct task_struct *task, + int running) +{ +} +static void prio_changed_new(struct rq *rq, struct task_struct *p, + int oldprio, int running) +{ +} +static unsigned int get_rr_interval_new(struct rq *rq, struct task_struct *task) +{ +} + + + +static const struct sched_class new_sched_class = { + .next = &fair_sched_class, + .enqueue_task = enqueue_task_new, + .dequeue_task = dequeue_task_new, + .yield_task = yield_task_new, + + .check_preempt_curr = check_preempt_curr_new, + + .pick_next_task = pick_next_task_new, + .put_prev_task = put_prev_task_new, + +#ifdef CONFIG_SMP + .select_task_rq = select_task_rq_new, + + .pre_schedule = pre_schedule_new, + .post_schedule = post_schedule_new, + + .task_waking = task_waking_new, + .task_woken = task_woken_new, + + .set_cpus_allowed = set_cpus_allowed_new, + + .rq_online = rq_online_new, + .rq_offline = rq_offline_new, +#endif + + .set_curr_task = set_curr_task_new, + .task_tick = task_tick_new, + .task_fork = task_fork_new, + + .switched_from = switched_from_new, + .switched_to = switched_to_new, + + .prio_changed = prio_changed_new, + + .get_rr_interval = get_rr_interval_new, +#ifdef CONFIG_FAIR_GROUP_SCHED + .moved_group = NULL +#endif +}; + +#endif /* CONFIG_SCHED_NEW */ diff --git a/kernel/sched_rt.cb/kernel/sched_rt.c index b5b920a..aaf4beb 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1731,7 +1731,11 @@ static unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task) } static const struct sched_class rt_sched_class = { +#ifdef CONFIG_SCHED_NEW + .next = &new_sched_class, +#else .next = &fair_sched_class, +#endif /* CONFIG_SCHED_NEW */ .enqueue_task = enqueue_task_rt, .dequeue_task = dequeue_task_rt, .yield_task = yield_task_rt, 

Embedded.com有一个由3部分组成的条目,通过实现一个简单的实时调度器:

  • 第1部分
  • 第2部分
  • 第3部分

与其他答案不同,这个是作为教程创建的:

在文献中,我们没有找到解释如何实施Linux新调度策略的文档。

[…]

在本文中,我们已经深入介绍了实施新调度策略所需的所有步骤。

[…]

这是该调度算法的简单实现。 然而,高级的问题,如中断,定时器和多处理器系统,只是提到一些,超出了本文的范围。

Con Kolivas Brainfuck调度程序 。 我刚刚通过Google搜索发现。 这可能是一个例子。