linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jake Moilanen <moilanen@austin.ibm.com>
To: linux-kernel@vger.kernel.org
Subject: [ANNOUNCE 4/4][RFC] Genetic Algorithm Library
Date: Thu, 6 Jan 2005 10:27:42 -0600	[thread overview]
Message-ID: <20050106102742.050d508f@localhost> (raw)
In-Reply-To: <20050106100844.53a762a0@localhost>

The hooked zaphod CPU scheduler patch.  

It depends on the zaphod-v6 patch.  

The ranges for the tunables could be tweaked better.

Signed-off-by: Jake Moilanen <moilanen@austin.ibm.com>

---


diff -puN kernel/sched_zaphod.c~genetic-zaphod-cpu-sched kernel/sched_zaphod.c
--- linux-2.6.9/kernel/sched_zaphod.c~genetic-zaphod-cpu-sched	Wed Jan  5 15:46:00 2005
+++ linux-2.6.9-moilanen/kernel/sched_zaphod.c	Wed Jan  5 15:46:00 2005
@@ -21,15 +21,12 @@
  */
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/genetic.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 
-enum zaphod_mode_enum {
-	ZAPHOD_MODE_PRIORITY_BASED,
-	ZAPHOD_MODE_ENTITLEMENT_BASED
-};
-
-static enum zaphod_mode_enum zaphod_mode = ZAPHOD_MODE_PRIORITY_BASED;
+enum zaphod_mode_enum zaphod_mode = ZAPHOD_MODE_PRIORITY_BASED;
 
 #ifdef CONFIG_SYSCTL
 static const char *zaphod_mode_names[] = {
@@ -720,3 +717,81 @@ int proc_zaphod_mode(ctl_table *ctp, int
 
 	return res;
 }
+
+#ifdef CONFIG_GENETIC_CPU_SCHED
+
+extern unsigned long sched_rr_time_slice;
+extern unsigned long base_prom_interval;
+static void zaphod_sched_create_child(genetic_child_t *);
+static void genetic_mutate_proportion(genetic_child_t *, unsigned long);
+void zaphod_sched_set_child_genes(void *);
+void zaphod_sched_calc_fitness(genetic_child_t *);
+
+struct genetic_ops zaphod_sched_genetic_ops = {
+	.create_child = zaphod_sched_create_child,
+	.set_child_genes = zaphod_sched_set_child_genes,
+	.calc_fitness = zaphod_sched_calc_fitness,
+	.combine_genes = genetic_generic_combine_genes,
+	.mutate_child = genetic_generic_mutate_child,
+};
+
+/* Each gene and their attributes */
+gene_param_t zaphod_sched_gene_param[ZAPHOD_SCHED_NUM_GENES] = {
+	{ MIN_TIMESLICE, MAX_TIMESLICE, DEF_TIMESLICE, 0 },		/* time_slice */
+	{ MIN_TIMESLICE, MAX_TIMESLICE, (100 * HZ / 1000), 0 },		/* sched_rr_time_slice */
+//	{ MIN_TIMESLICE, ULONG_MAX, ((DEF_TIMESLICE * 15) / 10), 0 },	/* base_prom_interval */
+	{ MIN_TIMESLICE, MAX_TIMESLICE, ((DEF_TIMESLICE * 15) / 10), 0 },	/* base_prom_interval */
+	{ 0, MAX_MAX_IA_BONUS, DEFAULT_MAX_IA_BONUS, 0 },		/* max_ia_bonus */
+	{ 0, MAX_MAX_IA_BONUS, 1, 0 },					/* initial_ia_bonus */
+	{ 1, 1000, DEFAULT_IA_THRESHOLD, 0 },  				/* ia_threshold */
+	{ 1, 1000, DEFAULT_CPU_HOG_THRESHOLD, 0 }, 			/* cpu_hog_threshold */
+	{ 0, MAX_MAX_TPT_BONUS, DEFAULT_MAX_TPT_BONUS, 0 },		/* max_tpt_bonus */
+	{ 1, 1000, DEFAULT_UNPRIV_RT_THRESHOLD, 0 }, 			/* unpriv_rt_threshold */
+	{ 1, 100, 1, 0 }, 						/* bgnd_time_slice_multiplier */
+	{ 0, 1, 0, 0 },							/* zaphod_mode */
+};
+
+void __init genetic_cpu_sched_init()
+{
+	if(genetic_init(0, &zaphod_sched_genetic_ops, ZAPHOD_SCHED_NUM_CHILDREN,
+			ZAPHOD_SCHED_CHILD_LIFESPAN, "zaphod-sched"))
+		panic("zaphod sched: failed to init genetic lib");
+}
+
+void zaphod_sched_create_child(genetic_child_t * child)
+{
+	int i;
+	static int child_num = 0;
+	unsigned long range;
+	int range_incr;
+	unsigned long * genes;
+	
+	BUG_ON(!child);
+	
+	child->genes = (void *)kmalloc(sizeof(struct zaphod_sched_genes), GFP_KERNEL);
+	if (!child->genes) 
+		panic("zaphod_sched_create_child: error kmalloc'n space");
+
+	child->gene_param = zaphod_sched_gene_param;
+
+	genes = (unsigned long *)child->genes;
+		
+	for (i = 0; i < ZAPHOD_SCHED_NUM_GENES; i++) {
+		range = child->gene_param[i].max - child->gene_param[i].min + 1;
+		range_incr = range / ZAPHOD_SCHED_NUM_CHILDREN;
+		if (range_incr)
+			genes[i] = child->gene_param[i].min +
+				(range_incr * child_num);
+		else
+			genes[i] = child->gene_param[i].min +
+				(child_num / (ZAPHOD_SCHED_NUM_CHILDREN / range));
+	}
+
+	child->num_genes = ZAPHOD_SCHED_NUM_GENES;
+	
+	child_num++;
+}
+
+core_initcall(genetic_cpu_sched_init);
+
+#endif /* CONFIG_GENETIC_CPU_SCHED */
diff -puN lib/Kconfig~genetic-zaphod-cpu-sched lib/Kconfig
--- linux-2.6.9/lib/Kconfig~genetic-zaphod-cpu-sched	Wed Jan  5 15:46:00 2005
+++ linux-2.6.9-moilanen/lib/Kconfig	Wed Jan  5 15:46:00 2005
@@ -36,6 +36,13 @@ config GENETIC_LIB
 	  This option will build in a genetic library that will tweak
 	  kernel parameters autonomically to improve performance.
 
+config GENETIC_CPU_SCHED
+	bool "Genetic Library - Zaphod CPU scheduler"
+	depends on GENETIC_LIB && EXPERIMENTAL && SCHEDSTATS
+	help
+	  This option will enable the genetic library on the zaphod
+	  CPU scheduler.
+
 #
 # compression support is select'ed if needed
 #
diff -puN kernel/sched.c~genetic-zaphod-cpu-sched kernel/sched.c
--- linux-2.6.9/kernel/sched.c~genetic-zaphod-cpu-sched	Wed Jan  5 15:46:00 2005
+++ linux-2.6.9-moilanen/kernel/sched.c	Wed Jan  5 15:46:00 2005
@@ -43,6 +43,7 @@
 #include <linux/kthread.h>
 #include <linux/seq_file.h>
 #include <linux/times.h>
+#include <linux/genetic.h>
 #include <asm/tlb.h>
 
 #include <asm/unistd.h>
@@ -71,19 +72,8 @@
 #define NS_TO_JIFFIES(TIME)	((TIME) / (1000000000 / HZ))
 #define JIFFIES_TO_NS(TIME)	((TIME) * (1000000000 / HZ))
 
-/*
- * These are the 'tuning knobs' of the scheduler:
- *
- * Default configurable timeslice is 100 msecs, maximum configurable
- * timeslice is 1000 msecs and minumum configurable timeslice is 1 jiffy.
- * Timeslices get renewed on task creation, on wake up and after they expire.
- */
-#define MIN_TIMESLICE		1
-#define DEF_TIMESLICE		(100 * HZ / 1000)
-#define MAX_TIMESLICE		(1000 * HZ / 1000)
-
 unsigned long time_slice = DEF_TIMESLICE;
-static unsigned long sched_rr_time_slice = (100 * HZ / 1000);
+unsigned long sched_rr_time_slice = (100 * HZ / 1000);
 
 static unsigned long task_timeslice(const task_t *p)
 {
@@ -116,6 +106,13 @@ struct prio_slot {
 	struct list_head queue;
 };
 
+static DEFINE_PER_CPU(struct runqueue, runqueues);
+
+#define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
+#define this_rq()		(&__get_cpu_var(runqueues))
+#define task_rq(p)		((p)->rq)
+#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
+
 /*
  * This is the main, per-CPU runqueue data structure.
  *
@@ -199,8 +196,6 @@ struct runqueue {
 #endif
 };
 
-static DEFINE_PER_CPU(struct runqueue, runqueues);
-
 /*
  * sched-domains (multiprocessor balancing) declarations:
  */
@@ -338,11 +333,6 @@ struct sched_domain {
 #define for_each_domain(cpu, domain) \
 	for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent)
 
-#define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
-#define this_rq()		(&__get_cpu_var(runqueues))
-#define task_rq(p)		((p)->rq)
-#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
-
 #ifdef CONFIG_SMP
 void fastcall set_task_cpu(struct task_struct *p, unsigned int cpu)
 {
@@ -1357,7 +1347,7 @@ void fastcall wake_up_new_task(task_t * 
 /**
  * (Optionally) log scheduler statistics at exit.
  */
-static int log_at_exit = 0;
+int log_at_exit = 0;
 /*
  * No more timeslice fiddling on exit
  */
@@ -4938,3 +4928,60 @@ ctl_table cpu_sched_table[] = {
 	{ .ctl_name = CPU_SCHED_END_OF_LIST }
 };
 #endif
+
+#ifdef CONFIG_GENETIC_CPU_SCHED
+
+extern enum zaphod_mode_enum zaphod_mode;
+
+void zaphod_sched_set_child_genes(void * in_genes)
+{
+	struct zaphod_sched_genes * genes = (struct zaphod_sched_genes *)in_genes;
+	int cpu;
+	runqueue_t * rq;
+
+	time_slice = genes->time_slice;
+	sched_rr_time_slice = genes->sched_rr_time_slice;
+	base_prom_interval = genes->base_prom_interval;
+	max_ia_bonus = genes->max_ia_bonus;
+	initial_ia_bonus = genes->initial_ia_bonus;
+	ia_threshold = ppt_to_proportion(genes->ia_threshold);
+	cpu_hog_threshold = ppt_to_proportion(genes->cpu_hog_threshold);
+	max_tpt_bonus = genes->max_tpt_bonus;
+	unpriv_rt_threshold = ppt_to_proportion(genes->unpriv_rt_threshold);
+	bgnd_time_slice_multiplier = genes->bgnd_time_slice_multiplier;
+	zaphod_mode = genes->zaphod_mode;
+	
+	/* Get snapshot for this child */
+	for_each_online_cpu(cpu) {
+		rq = cpu_rq(cpu);
+
+		rq->rq_sched_info.cpu_time_snapshot = rq->rq_sched_info.cpu_time;
+		rq->rq_sched_info.run_delay_snapshot = rq->rq_sched_info.run_delay;
+		rq->rq_sched_info.pcnt_snapshot = rq->rq_sched_info.pcnt;
+	}
+}
+
+void zaphod_sched_calc_fitness(genetic_child_t * child)
+{
+	int cpu;
+	runqueue_t * rq;
+	long cpu_time = 0;
+	long run_delay = 0;
+	long pcnt = 0;
+
+	/* XXX at some point make sure onlining or offlining a CPU
+	   doesn't screw us */
+	for_each_online_cpu(cpu) {
+		rq = cpu_rq(cpu);
+
+		cpu_time += rq->rq_sched_info.cpu_time - rq->rq_sched_info.cpu_time_snapshot;
+		run_delay += rq->rq_sched_info.run_delay - rq->rq_sched_info.run_delay_snapshot;
+		pcnt += rq->rq_sched_info.pcnt - rq->rq_sched_info.pcnt_snapshot;
+	}
+
+	child->fitness = cpu_time - run_delay;
+//	child->fitness = 1 - run_delay;
+}
+
+#endif
+
diff -puN include/linux/sched.h~genetic-zaphod-cpu-sched include/linux/sched.h
--- linux-2.6.9/include/linux/sched.h~genetic-zaphod-cpu-sched	Wed Jan  5 15:46:00 2005
+++ linux-2.6.9-moilanen/include/linux/sched.h	Wed Jan  5 15:46:00 2005
@@ -138,6 +138,17 @@ struct sched_param {
 #include <linux/spinlock.h>
 
 /*
+ * These are the 'tuning knobs' of the scheduler:
+ *
+ * Default configurable timeslice is 100 msecs, maximum configurable
+ * timeslice is 1000 msecs and minumum configurable timeslice is 1 jiffy.
+ * Timeslices get renewed on task creation, on wake up and after they expire.
+ */
+#define MIN_TIMESLICE		1
+#define DEF_TIMESLICE		(100 * HZ / 1000)
+#define MAX_TIMESLICE		(1000 * HZ / 1000)
+
+/*
  * This serializes "schedule()" and also protects
  * the run-queue from deletions/modifications (but
  * _adding_ to the beginning of the run-queue has
@@ -392,6 +403,12 @@ struct sched_info {
 	/* timestamps */
 	unsigned long	last_arrival,	/* when we last ran on a cpu */
 			last_queued;	/* when we were last queued to run */
+
+#ifdef CONFIG_GENETIC_CPU_SCHED
+	unsigned long	cpu_time_snapshot;
+	unsigned long	run_delay_snapshot;
+	unsigned long	pcnt_snapshot;
+#endif	
 };
 
 extern struct file_operations proc_schedstat_operations;
@@ -657,6 +674,8 @@ extern int task_nice(const task_t *p);
 extern int task_curr(const task_t *p);
 extern int idle_cpu(int cpu);
 
+extern void genetic_cpu_sched_init(void);
+
 void yield(void);
 
 /*
@@ -1031,8 +1050,35 @@ static inline void arch_pick_mmap_layout
 }
 #endif
 
+enum zaphod_mode_enum {
+	ZAPHOD_MODE_PRIORITY_BASED,
+	ZAPHOD_MODE_ENTITLEMENT_BASED
+};
+
+#ifdef CONFIG_GENETIC_CPU_SCHED
 extern long sched_setaffinity(pid_t pid, cpumask_t new_mask);
 extern long sched_getaffinity(pid_t pid, cpumask_t *mask);
+
+
+#define ZAPHOD_SCHED_NUM_GENES 11
+#define ZAPHOD_SCHED_NUM_CHILDREN 8
+//#define ZAPHOD_SCHED_CHILD_LIFESPAN (9 * (HZ / 2))
+#define ZAPHOD_SCHED_CHILD_LIFESPAN (4 * HZ)
+
+struct zaphod_sched_genes {
+	unsigned long time_slice;
+	unsigned long sched_rr_time_slice;
+	unsigned long base_prom_interval;
+	unsigned long max_ia_bonus;
+	unsigned long initial_ia_bonus;
+	unsigned long ia_threshold;
+	unsigned long cpu_hog_threshold;
+	unsigned long max_tpt_bonus;
+	unsigned long unpriv_rt_threshold;
+	unsigned long bgnd_time_slice_multiplier;
+	unsigned long zaphod_mode;
+};
+#endif /* CONFIG_GENETIC_CPU_SCHED */
 
 #endif /* __KERNEL__ */
 

_

  parent reply	other threads:[~2005-01-06 16:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-06 16:08 [ANNOUNCE 0/4][RFC] Genetic Algorithm Library Jake Moilanen
2005-01-06 16:14 ` [ANNOUNCE 1/4][RFC] " Jake Moilanen
2005-01-06 17:20   ` Cal Peake
2005-01-06 17:26     ` Cal Peake
2005-01-06 16:18 ` [ANNOUNCE 2/4][RFC] " Jake Moilanen
2005-01-06 16:22 ` [ANNOUNCE 3/4][RFC] " Jake Moilanen
2005-01-06 16:27 ` Jake Moilanen [this message]
2005-01-08 14:05 ` [ANNOUNCE 0/4][RFC] " James Bruce
2005-01-08 14:19   ` James Bruce
2005-01-08 22:56     ` Jake Moilanen
2005-01-08 15:37 ` Pedro Larroy
2005-01-10 15:54   ` Jake Moilanen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050106102742.050d508f@localhost \
    --to=moilanen@austin.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).