versiones todas que para las existen crear como cargar c linux linux-kernel scheduling scheduler

c - todas - linux y sus versiones



Cómo crear un nuevo programador de kernel de Linux (3)

Embedded.com tiene una entrada de 3 partes que explica la implementación de un planificador simple en tiempo real:

A diferencia de las otras respuestas, esta se crea como un tutorial:

en la literatura no encontramos documentos que expliquen cómo implementar una nueva política de programación para Linux.

[...]

En este documento, hemos presentado en una [sic] descripción detallada todos los pasos necesarios para implementar una nueva política de programación.

[...]

Esta es una implementación simple de ese algoritmo de programación. Sin embargo, los problemas avanzados, como interrupciones, temporizadores y sistemas multiprocesador, solo por mencionar algunos, están fuera del alcance de este artículo.

Mirando a través del código fuente del programador (2.6.34, kernel / sched.c), puedo ver cómo se usan los programadores "conectables", y creo que entiendo la interfaz que se debe implementar. Lo que aún no entiendo es cómo hacer que mi código esté integrado en el kernel. Por lo menos, se agradecerían los punteros a otros sitios.

En este momento, estoy solicitando SCHED_FIFO, SCHED_RR y SCHED_NORMAL en el árbol de fuentes del núcleo, así que realmente estoy buscando una manera más perspicaz de verlo :-)

EDITAR: Como fondo, estoy muy familiarizado con el programador de FreeBSD (y el kernel de FreeBSD en general), por lo que no estoy buscando indicaciones sobre cómo realizar la programación a nivel de proceso / subproceso. Estoy buscando una manera de agregar mi propio programador junto con los programadores normales de Linux (similar a SCHED_FIFO).

EDICIÓN # 2: El puntero BFS a continuación es un buen comienzo, pero aún así extrae CFS del núcleo. sched.c ahora se ve como:

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

Me encantaría ver una respuesta o un indicador sobre cómo hacer esto un poco mejor (es decir, mantener el CFS, al menos por ahora).

EDIT # 3: He respondido mi propia pregunta a continuación, ya que creo que lo he descubierto.


He descubierto la respuesta a mi pregunta, así que pensé que la añadiría aquí. A continuación se muestra el parche que agregará un nuevo programador al kernel de vainilla 2.6.34. En este momento, solo he compilado el kernel. Espero que la ejecución de un sistema con este parche EXACTO cause que se bloquee, así que úselo bajo su propio riesgo :-)

diff --git a/include/linux/sched.h b/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.c b/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.c b/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.c b/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,