diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2013-09-23 14:30:19 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-09-23 14:30:19 -0400 |
commit | 0feedf723aaa61958ad81dca9d7135a69220d7b4 (patch) | |
tree | 07d4dd83770934aaf4808e667dc31680ea1dce07 | |
parent | e8768d1ca3abd748be9e25c8899b9631c501f00f (diff) |
Fix critical bug in GPU tracker.wip-2012.3-gpu-rtss13
-rw-r--r-- | include/litmus/gpu_affinity.h | 21 | ||||
-rw-r--r-- | litmus/gpu_affinity.c | 4 | ||||
-rw-r--r-- | litmus/litmus.c | 7 | ||||
-rw-r--r-- | litmus/locking.c | 7 | ||||
-rw-r--r-- | litmus/sched_litmus.c | 14 |
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 | ||
17 | static inline void start_gpu_tracker(struct task_struct* t) | 17 | static 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 | ||
22 | static inline void stop_gpu_tracker(struct task_struct* t) | 28 | static 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 | ||
29 | static inline lt_t get_gpu_time(struct task_struct* t) | 41 | static 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 | |||
8 | static void update_time_litmus(struct rq *rq, struct task_struct *p) | 10 | static 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; |