aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-09-23 14:30:19 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2013-09-23 14:30:19 -0400
commit0feedf723aaa61958ad81dca9d7135a69220d7b4 (patch)
tree07d4dd83770934aaf4808e667dc31680ea1dce07
parente8768d1ca3abd748be9e25c8899b9631c501f00f (diff)
Fix critical bug in GPU tracker.wip-2012.3-gpu-rtss13
-rw-r--r--include/litmus/gpu_affinity.h21
-rw-r--r--litmus/gpu_affinity.c4
-rw-r--r--litmus/litmus.c7
-rw-r--r--litmus/locking.c7
-rw-r--r--litmus/sched_litmus.c14
5 files changed, 41 insertions, 12 deletions
diff --git a/include/litmus/gpu_affinity.h b/include/litmus/gpu_affinity.h
index f610f58b1f3b..197d4438d4f9 100644
--- a/include/litmus/gpu_affinity.h
+++ b/include/litmus/gpu_affinity.h
@@ -16,22 +16,33 @@ static inline void reset_gpu_tracker(struct task_struct* t)
16 16
17static inline void start_gpu_tracker(struct task_struct* t) 17static inline void start_gpu_tracker(struct task_struct* t)
18{ 18{
19 t->rt_param.gpu_time_stamp = litmus_clock(); 19 lt_t now = litmus_clock();
20
21 TRACE_TASK(t, "+++ starting gpu tracker @ %llu\n", now);
22// WARN_ON(t->rt_param.gpu_time_stamp != 0); // already running!
23
24 if (likely(!t->rt_param.gpu_time_stamp))
25 t->rt_param.gpu_time_stamp = now;
20} 26}
21 27
22static inline void stop_gpu_tracker(struct task_struct* t) 28static inline void stop_gpu_tracker(struct task_struct* t)
23{ 29{
24 lt_t now = litmus_clock(); 30 lt_t now = litmus_clock();
25 t->rt_param.accum_gpu_time += (now - t->rt_param.gpu_time_stamp); 31
26 t->rt_param.gpu_time_stamp = 0; 32 TRACE_TASK(t, "--- stopping gpu tracker @ %llu\n", now);
33// WARN_ON(t->rt_param.gpu_time_stamp == 0); // already stopped!
34
35 if (likely(t->rt_param.gpu_time_stamp)) {
36 t->rt_param.accum_gpu_time += (now - t->rt_param.gpu_time_stamp);
37 t->rt_param.gpu_time_stamp = 0;
38 }
27} 39}
28 40
29static inline lt_t get_gpu_time(struct task_struct* t) 41static inline lt_t get_gpu_time(struct task_struct* t)
30{ 42{
31 lt_t accum = t->rt_param.accum_gpu_time; 43 lt_t accum = t->rt_param.accum_gpu_time;
32 if (t->rt_param.gpu_time_stamp != 0) { 44 if (t->rt_param.gpu_time_stamp != 0)
33 accum += (litmus_clock() - t->rt_param.gpu_time_stamp); 45 accum += (litmus_clock() - t->rt_param.gpu_time_stamp);
34 }
35 return accum; 46 return accum;
36} 47}
37 48
diff --git a/litmus/gpu_affinity.c b/litmus/gpu_affinity.c
index e59814b998d3..b3415112eeb1 100644
--- a/litmus/gpu_affinity.c
+++ b/litmus/gpu_affinity.c
@@ -111,13 +111,13 @@ void update_gpu_estimate(struct task_struct *t, lt_t observed)
111 lower = est->avg - MIN(range, est->avg); // no underflow. 111 lower = est->avg - MIN(range, est->avg); // no underflow.
112 112
113 if (unlikely(observed < lower)) { 113 if (unlikely(observed < lower)) {
114 TRACE_TASK(t, "Observation is too small: %llu\n", observed); 114 TRACE_TASK(t, "Observation is too small. %llu < %llu (avg: %llu)\n", observed, lower, est->avg);
115 return; 115 return;
116 } 116 }
117 117
118 upper = est->avg + range; 118 upper = est->avg + range;
119 if (unlikely(observed > upper)) { 119 if (unlikely(observed > upper)) {
120 TRACE_TASK(t, "Observation is too large: %llu\n", observed); 120 TRACE_TASK(t, "Observation is too large: %llu > %llu (avg: %llu)\n", observed, upper, est->avg);
121 return; 121 return;
122 } 122 }
123 } 123 }
diff --git a/litmus/litmus.c b/litmus/litmus.c
index ceaa31405884..05221405ddc4 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -136,8 +136,7 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param)
136 { 136 {
137 printk(KERN_INFO "litmus: real-time task %d rejected " 137 printk(KERN_INFO "litmus: real-time task %d rejected "
138 "because task density > 1.0: exec_cost = %llu, deadline = %llu\n", 138 "because task density > 1.0: exec_cost = %llu, deadline = %llu\n",
139 tp.exec_cost, min(tp.relative_deadline, tp.period), 139 pid, tp.exec_cost, min(tp.relative_deadline, tp.period));
140 pid);
141 goto out_unlock; 140 goto out_unlock;
142 } 141 }
143 if (tp.cls != RT_CLASS_HARD && 142 if (tp.cls != RT_CLASS_HARD &&
@@ -583,13 +582,13 @@ long litmus_admit_task(struct task_struct* tsk)
583 min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { 582 min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) {
584 printk("%s/%d " 583 printk("%s/%d "
585 "litmus admit: invalid task parameters " 584 "litmus admit: invalid task parameters "
586 "(e = %lu, p = %lu, d = %lu)\n", 585 "(e = %llu, p = %llu, d = %llu)\n",
587 tsk->comm, tsk->pid, 586 tsk->comm, tsk->pid,
588 get_exec_cost(tsk), get_rt_period(tsk), 587 get_exec_cost(tsk), get_rt_period(tsk),
589 get_rt_relative_deadline(tsk)); 588 get_rt_relative_deadline(tsk));
590 TRACE_TASK(tsk, 589 TRACE_TASK(tsk,
591 "litmus admit: invalid task parameters " 590 "litmus admit: invalid task parameters "
592 "(e = %lu, p = %lu, d = %lu)\n", 591 "(e = %llu, p = %llu, d = %llu)\n",
593 get_exec_cost(tsk), get_rt_period(tsk), 592 get_exec_cost(tsk), get_rt_period(tsk),
594 get_rt_relative_deadline(tsk)); 593 get_rt_relative_deadline(tsk));
595 retval = -EINVAL; 594 retval = -EINVAL;
diff --git a/litmus/locking.c b/litmus/locking.c
index 513b5d3844c8..c3f085c079f8 100644
--- a/litmus/locking.c
+++ b/litmus/locking.c
@@ -887,7 +887,11 @@ void suspend_for_lock(void)
887#if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA) 887#if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA)
888 // disable tracking 888 // disable tracking
889 if(tsk_rt(t)->held_gpus) 889 if(tsk_rt(t)->held_gpus)
890 {
891 // tracking is actually stopped in schedule(), where it
892 // is also stopped upon preemption
890 tsk_rt(t)->suspend_gpu_tracker_on_block = 1; 893 tsk_rt(t)->suspend_gpu_tracker_on_block = 1;
894 }
891#endif 895#endif
892 896
893 schedule(); 897 schedule();
@@ -895,7 +899,10 @@ void suspend_for_lock(void)
895#if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA) 899#if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA)
896 // re-enable tracking 900 // re-enable tracking
897 if(tsk_rt(t)->held_gpus) 901 if(tsk_rt(t)->held_gpus)
902 {
898 tsk_rt(t)->suspend_gpu_tracker_on_block = 0; 903 tsk_rt(t)->suspend_gpu_tracker_on_block = 0;
904// start_gpu_tracker(t); // we have to turn tracking back on here
905 }
899#endif 906#endif
900 907
901#if defined(CONFIG_REALTIME_AUX_TASKS) || defined(CONFIG_LITMUS_NVIDIA) 908#if defined(CONFIG_REALTIME_AUX_TASKS) || defined(CONFIG_LITMUS_NVIDIA)
diff --git a/litmus/sched_litmus.c b/litmus/sched_litmus.c
index 3a594cd51a44..63f893c232af 100644
--- a/litmus/sched_litmus.c
+++ b/litmus/sched_litmus.c
@@ -5,6 +5,8 @@
5#include <litmus/sched_plugin.h> 5#include <litmus/sched_plugin.h>
6#include <litmus/preempt.h> 6#include <litmus/preempt.h>
7 7
8#include <litmus/gpu_affinity.h>
9
8static void update_time_litmus(struct rq *rq, struct task_struct *p) 10static void update_time_litmus(struct rq *rq, struct task_struct *p)
9{ 11{
10 u64 delta = rq->clock - p->se.exec_start; 12 u64 delta = rq->clock - p->se.exec_start;
@@ -155,8 +157,18 @@ litmus_schedule(struct rq *rq, struct task_struct *prev)
155 next->rt_param.stack_in_use = rq->cpu; 157 next->rt_param.stack_in_use = rq->cpu;
156 next->se.exec_start = rq->clock; 158 next->se.exec_start = rq->clock;
157 159
158 if (is_realtime(next)) 160 if (is_realtime(next)) {
159 budget_state_machine(next,on_scheduled); 161 budget_state_machine(next,on_scheduled);
162
163 // turn gpu tracking back on if needed
164 if(tsk_rt(next)->held_gpus) {
165 // tracker might already be running if we're waking
166 // up from using the GPU
167 if(0 == tsk_rt(next)->gpu_time_stamp) {
168 start_gpu_tracker(next);
169 }
170 }
171 }
160 } 172 }
161 173
162 return next; 174 return next;