aboutsummaryrefslogtreecommitdiffstats
path: root/litmus
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2011-04-09 09:25:47 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2011-04-09 09:25:47 -0400
commitd3f99f11f3440d70658b9d9df756bbd9b63f8058 (patch)
treeb4caf603c530cfd21a1515e496f83cd296e0d0fc /litmus
parentc05eaa8091d2cadc20363d44a85ee454262f4bc2 (diff)
Bias task scheduling towards previous CPU.
Added the option to allow tasks to be scheduled on their previous CPU if that CPU is not currently executing real-time work. Helps preserve cache affinity and reduction in migration costs. See CONFIG_CPU_SCHED_BIAS help for more information. Solution developed by Jonathan Herman.
Diffstat (limited to 'litmus')
-rw-r--r--litmus/Kconfig18
-rw-r--r--litmus/sched_cedf.c24
-rw-r--r--litmus/sched_gsn_edf.c28
3 files changed, 64 insertions, 6 deletions
diff --git a/litmus/Kconfig b/litmus/Kconfig
index ad8dc8308cf0..651b66a77c65 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -36,6 +36,24 @@ config RELEASE_MASTER
36 36
37endmenu 37endmenu
38 38
39menu "Performance Hacks"
40
41config CPU_SCHED_BIAS
42 bool "Tasks prefer previous CPU(s)."
43 default n
44 help
45 Allow tasks to be rescheduled on their previously used CPU(s) if that
46 CPU(s) is not currently not executing real-time work. This may improve
47 performance through the possible preservation of cache affinity.
48
49 Warning: May make bugs harder to find as tasks will migrate less
50 frequently.
51
52 Only bias towards previously used CPU is currently implemented. In the
53 future: bias on CPU topology.
54
55endmenu
56
39menu "Real-Time Synchronization" 57menu "Real-Time Synchronization"
40 58
41config NP_SECTION 59config NP_SECTION
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c
index 73fe1c442a0d..851de716de0a 100644
--- a/litmus/sched_cedf.c
+++ b/litmus/sched_cedf.c
@@ -261,17 +261,35 @@ static noinline void requeue(struct task_struct* task)
261static void check_for_preemptions(cedf_domain_t *cluster) 261static void check_for_preemptions(cedf_domain_t *cluster)
262{ 262{
263 struct task_struct *task; 263 struct task_struct *task;
264 cpu_entry_t* last; 264 cpu_entry_t *last;
265
266#ifdef CONFIG_CPU_SCHED_BIAS
267 cpu_entry_t *pref;
268#endif
265 269
266 for(last = lowest_prio_cpu(cluster); 270 for(last = lowest_prio_cpu(cluster);
267 edf_preemption_needed(&cluster->domain, last->linked); 271 edf_preemption_needed(&cluster->domain, last->linked);
268 last = lowest_prio_cpu(cluster)) { 272 last = lowest_prio_cpu(cluster)) {
269 /* preemption necessary */ 273 /* preemption necessary */
270 task = __take_ready(&cluster->domain); 274 task = __take_ready(&cluster->domain);
271 TRACE("check_for_preemptions: attempting to link task %d to %d\n", 275
272 task->pid, last->cpu); 276#ifdef CONFIG_CPU_SCHED_BIAS
277 /* where was task last scheduled? */
278 pref = &per_cpu(cedf_cpu_entries, task_cpu(task));
279
280 if (!pref->linked) {
281 last = pref;
282 }
283 else if (last->linked) {
284 requeue(last->linked);
285 }
286#else /* end CONFIG_CPU_SCHED_BIAS */
273 if (last->linked) 287 if (last->linked)
274 requeue(last->linked); 288 requeue(last->linked);
289#endif
290
291 TRACE("check_for_preemptions: attempting to link task %d to %d\n",
292 task->pid, last->cpu);
275 link_task_to_cpu(task, last); 293 link_task_to_cpu(task, last);
276 preempt(last); 294 preempt(last);
277 } 295 }
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index c5c9600c33d8..dd670f5219c1 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -257,17 +257,39 @@ static noinline void requeue(struct task_struct* task)
257static void check_for_preemptions(void) 257static void check_for_preemptions(void)
258{ 258{
259 struct task_struct *task; 259 struct task_struct *task;
260 cpu_entry_t* last; 260 cpu_entry_t *last;
261
262#ifdef CONFIG_CPU_SCHED_BIAS
263 cpu_entry_t *pref;
264#endif
261 265
262 for(last = lowest_prio_cpu(); 266 for(last = lowest_prio_cpu();
263 edf_preemption_needed(&gsnedf, last->linked); 267 edf_preemption_needed(&gsnedf, last->linked);
264 last = lowest_prio_cpu()) { 268 last = lowest_prio_cpu()) {
265 /* preemption necessary */ 269 /* preemption necessary */
266 task = __take_ready(&gsnedf); 270 task = __take_ready(&gsnedf);
267 TRACE("check_for_preemptions: attempting to link task %d to %d\n", 271
268 task->pid, last->cpu); 272#ifdef CONFIG_CPU_SCHED_BIAS
273 /* where was task last scheduled? */
274 pref = &per_cpu(gsnedf_cpu_entries, task_cpu(task));
275
276 if (!pref->linked
277#ifdef CONFIG_RELEASE_MASTER
278 && (pref->cpu != gsnedf.release_master)
279#endif
280 ) {
281 last = pref;
282 }
283 else if (last->linked) {
284 requeue(last->linked);
285 }
286#else /* end CONFIG_CPU_SCHED_BIAS */
269 if (last->linked) 287 if (last->linked)
270 requeue(last->linked); 288 requeue(last->linked);
289#endif
290
291 TRACE("check_for_preemptions: attempting to link task %d to %d\n",
292 task->pid, last->cpu);
271 link_task_to_cpu(task, last); 293 link_task_to_cpu(task, last);
272 preempt(last); 294 preempt(last);
273 } 295 }