2010-06-21 8 views
27

Durch den Scheduler-Quellcode (2.6.34, kernel/sched.c) schauend, kann ich sehen, wie die "steckbaren" Scheduler verwendet werden, und ich glaube, ich verstehe die Schnittstelle implementiert. Was ich noch nicht verstehe ist, wie ich meinen Code in den Kernel einbauen kann. Zumindest würden Hinweise auf andere Websites geschätzt werden.Wie man einen neuen Linux-Kernel-Scheduler erstellt

Gerade jetzt, ich bin greppen für SCHED_FIFO, SCHED_RR und SCHED_NORMAL im Baum Kernel-Quelle, so wirklich für eine interessante Art und Weise es ich bin auf der Suche sehen :-)

EDIT: Wie einige Hintergrund, ich kenne den FreeBSD-Scheduler (und den FreeBSD-Kernel im Allgemeinen) sehr gut, daher suche ich nicht nach Hinweisen zur Prozess-/Thread-Ebenen-Planung. Ich suche nach einer Möglichkeit, meinen eigenen Scheduler neben den normalen Linux-Schedulern hinzuzufügen (ähnlich wie bei SCHED_FIFO).

EDIT # 2: Der BFS-Zeiger unten ist ein guter Anfang, aber es reißt CFS immer noch aus dem Kernel. sched.c sieht nun wie:

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

Ich würde gerne eine Antwort oder einen Zeiger auf, um zu sehen, wie diese ein wenig besser zu machen (dh hält CFS, zumindest für jetzt).

EDIT # 3: Ich habe meine eigene Frage unten beantwortet, da ich denke, dass ich es herausgefunden habe.

+1

Meinen Sie die entsprechenden Bits in kconfig hinzufügen, damit Ihr Scheduler ausgewählt/verwendet werden kann? –

+0

Das ist ziemlich genau das, was ich suche - ich habe ein wenig Hintergrund zur ursprünglichen Frage hinzugefügt (das FreeBSD-Zeug), um hoffentlich das, wonach ich suche, klarer zu machen. –

Antwort

17

Ich habe die Antwort auf meine Frage gefunden, also dachte ich, ich würde sie hier hinzufügen. Unten ist der Patch, der dem 2.6.34 Vanilla Kernel einen neuen Scheduler hinzufügt. Im Moment habe ich nur den Kernel kompiliert. Ich kann es vollständig zu Absturz verursachen erwarten ein System mit diesem EXACT Patch laufen wird - so auf eigene Gefahr :-)

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. Ich habe das gerade durch googeln gefunden. Es kann ein Beispiel sein, von dem aus man anfangen kann.

+0

Ich habe das Design von BFS durchgesehen und es ist definitiv interessant. Es ist einfach großartig. Ich möchte jedoch einen Scheduler hinzufügen, der mit CFS koexistiert (und SCHED_FIFO, usw.), und ich suche, wie man die Konfiguration richtig macht, nicht, wie man den vorhandenen Scheduler herausreißt und meinen eigenen neu implementiert. –

+4

Also verbrachte ich ein bisschen mehr Zeit mit dem BFS-Patch, und ich lag falsch. Es hat mindestens eine Möglichkeit gezeigt, einen neuen Scheduler hinzuzufügen, der mir eine Verknüpfung zum Hinzufügen meines Codes gibt. Danke für den Zeiger blm! –

13

Embedded.com hat einen 3-teiligen Eintrag, der eine einfache Echt durch Umsetzung Wanderungen Zeitplaner:

Im Gegensatz zu den anderen Antworten wird diese als Tutorial erstellt:

[...] in der Literatur wir Dokumente nicht finden, die erklären, wie eine neue Planungsrichtlinie für Linux zu implementieren.

[...]

In diesem Dokument haben wir in einer [sic] ausführliche Beschreibung aller Schritte vorgestellt erforderlich, um eine neue Planungsrichtlinie umzusetzen.

[...]

Dies ist eine einfache Implementierung dieses Scheduling-Algorithmus. Jedoch, erweiterte Probleme, wie Unterbrechungen, Timer und Multiprozessorsysteme, um nur einige zu nennen, sind nicht im Rahmen dieses Artikels.

+0

Die Links sind kaputt. Ich konnte sie nirgendwo anders im Internet finden. – zeronone

+0

@zeronone sie scheinen heute für mich in Ordnung. Vielleicht waren sie nur vorübergehend kaputt? –

+0

es funktioniert jetzt. Vielen Dank :) – zeronone