2010-06-21 9 views
27

Al mirar 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 que la interfaz implementado. Lo que aún no entiendo es cómo incorporar mi código en el kernel. Por lo menos, se apreciarán los indicadores a otros sitios.Cómo crear un nuevo planificador de kernel de Linux

En este momento, estoy grepping para SCHED_FIFO, SCHED_RR y SCHED_NORMAL en el árbol de fuentes del núcleo, así que realmente estoy buscando una manera más detallada a mirarlo :-)

EDIT: Como algunos En segundo lugar, estoy muy familiarizado con el planificador de FreeBSD (y el kernel de FreeBSD en general), por lo que no estoy buscando punteros sobre cómo hacer el proceso/programación a nivel de subprocesos. Estoy buscando una forma de agregar mi propio programador junto con los programadores normales de Linux (similar a SCHED_FIFO).

EDIT # 2: El puntero BFS a continuación es un buen comienzo, pero aún arranca CFS del kernel. sched.c ahora queda como:

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

Me gustaría ver una respuesta o un puntero sobre la manera de hacer esto un poco mejor (es decir, mantener el SFC, al menos por ahora).

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

+1

Qué quiere decir la adición de los bits apropiados en kconfig por lo que su planificador puede ser seleccionado/utilizado? –

+0

Eso es más o menos exactamente lo que estoy buscando - He añadido un poco de fondo a la pregunta original (las cosas FreeBSD), es de esperar para hacer lo que estoy buscando más clara. –

Respuesta

17

He encontrado la respuesta a mi pregunta, así que pensé en agregarla aquí. A continuación se muestra el parche que agregará un nuevo programador al núcleo vanilla 2.6.34. En este momento, solo he compilado el kernel. Estoy totalmente de esperar que ejecuta un sistema con este parche exacto hacer que se caiga - a fin de utilizar a 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, 
8

Con Kolivas Brainfuck Scheduler. Acabo de encontrar esto buscando en Google. Puede ser un ejemplo para comenzar.

+0

He mirado a través del diseño de BFS, y es sin duda interesante. Su simplicidad es asombrosa. Sin embargo, quiero añadir un planificador que coexiste con el SFC (y SCHED_FIFO, etc.), y yo estoy buscando la manera de obtener la configuración deseada, no la forma de arrancar el programador existente y volver a desarrollar mi propia. –

+4

Así, pasé un poco más de tiempo buscando en el parche BFS, y yo estaba equivocado. Demostró al menos una forma de agregar un nuevo programador dándome un acceso directo para agregar mi código. Gracias por la BLM puntero! –

13

Embedded.com tiene una entrada de 3 partes que camina a través de la implementación de una sencilla real planificador de tiempo:

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

[...] en la literatura no encontramos documentos que explican cómo para implementar una nueva política de planificación para Linux.

[...]

En este documento, hemos presentado en una descripción en profundidad [sic] todas las medidas necesarios para implementar una nueva política de planificación.

[...]

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

+0

Los enlaces están rotos. No pude encontrarlos en ningún otro lugar en Internet. – zeronone

+0

@zeronone parecen estar bien para mí hoy. Tal vez solo se rompieron temporalmente? –

+0

está funcionando ahora. Gracias :) – zeronone

Cuestiones relacionadas