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; |
