diff options
-rw-r--r-- | litmus/rt_domain.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index d27af48e0298..81a5ac16f164 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
@@ -21,6 +21,15 @@ | |||
21 | 21 | ||
22 | #include <litmus/bheap.h> | 22 | #include <litmus/bheap.h> |
23 | 23 | ||
24 | /* Uncomment when debugging timer races... */ | ||
25 | #if 0 | ||
26 | #define VTRACE_TASK TRACE_TASK | ||
27 | #define VTRACE TRACE | ||
28 | #else | ||
29 | #define VTRACE_TASK(t, fmt, args...) /* shut up */ | ||
30 | #define VTRACE(fmt, args...) /* be quiet already */ | ||
31 | #endif | ||
32 | |||
24 | static int dummy_resched(rt_domain_t *rt) | 33 | static int dummy_resched(rt_domain_t *rt) |
25 | { | 34 | { |
26 | return 0; | 35 | return 0; |
@@ -47,18 +56,18 @@ static enum hrtimer_restart on_release_timer(struct hrtimer *timer) | |||
47 | unsigned long flags; | 56 | unsigned long flags; |
48 | struct release_heap* rh; | 57 | struct release_heap* rh; |
49 | 58 | ||
50 | TRACE("on_release_timer(0x%p) starts.\n", timer); | 59 | VTRACE("on_release_timer(0x%p) starts.\n", timer); |
51 | 60 | ||
52 | TS_RELEASE_START; | 61 | TS_RELEASE_START; |
53 | 62 | ||
54 | rh = container_of(timer, struct release_heap, timer); | 63 | rh = container_of(timer, struct release_heap, timer); |
55 | 64 | ||
56 | raw_spin_lock_irqsave(&rh->dom->release_lock, flags); | 65 | raw_spin_lock_irqsave(&rh->dom->release_lock, flags); |
57 | TRACE("CB has the release_lock 0x%p\n", &rh->dom->release_lock); | 66 | VTRACE("CB has the release_lock 0x%p\n", &rh->dom->release_lock); |
58 | /* remove from release queue */ | 67 | /* remove from release queue */ |
59 | list_del(&rh->list); | 68 | list_del(&rh->list); |
60 | raw_spin_unlock_irqrestore(&rh->dom->release_lock, flags); | 69 | raw_spin_unlock_irqrestore(&rh->dom->release_lock, flags); |
61 | TRACE("CB returned release_lock 0x%p\n", &rh->dom->release_lock); | 70 | VTRACE("CB returned release_lock 0x%p\n", &rh->dom->release_lock); |
62 | 71 | ||
63 | /* call release callback */ | 72 | /* call release callback */ |
64 | rh->dom->release_jobs(rh->dom, &rh->heap); | 73 | rh->dom->release_jobs(rh->dom, &rh->heap); |
@@ -66,7 +75,7 @@ static enum hrtimer_restart on_release_timer(struct hrtimer *timer) | |||
66 | 75 | ||
67 | TS_RELEASE_END; | 76 | TS_RELEASE_END; |
68 | 77 | ||
69 | TRACE("on_release_timer(0x%p) ends.\n", timer); | 78 | VTRACE("on_release_timer(0x%p) ends.\n", timer); |
70 | 79 | ||
71 | return HRTIMER_NORESTART; | 80 | return HRTIMER_NORESTART; |
72 | } | 81 | } |
@@ -173,7 +182,7 @@ static void reinit_release_heap(struct task_struct* t) | |||
173 | #define arm_release_timer(t) arm_release_timer_on((t), NO_CPU) | 182 | #define arm_release_timer(t) arm_release_timer_on((t), NO_CPU) |
174 | static void arm_release_timer_on(rt_domain_t *_rt , int target_cpu) | 183 | static void arm_release_timer_on(rt_domain_t *_rt , int target_cpu) |
175 | #else | 184 | #else |
176 | static void arm_release_master(rt_domain_t *_rt) | 185 | static void arm_release_timer(rt_domain_t *_rt) |
177 | #endif | 186 | #endif |
178 | { | 187 | { |
179 | rt_domain_t *rt = _rt; | 188 | rt_domain_t *rt = _rt; |
@@ -182,7 +191,7 @@ static void arm_release_master(rt_domain_t *_rt) | |||
182 | struct task_struct* t; | 191 | struct task_struct* t; |
183 | struct release_heap* rh; | 192 | struct release_heap* rh; |
184 | 193 | ||
185 | TRACE("arm_release_timer() at %llu\n", litmus_clock()); | 194 | VTRACE("arm_release_timer() at %llu\n", litmus_clock()); |
186 | list_replace_init(&rt->tobe_released, &list); | 195 | list_replace_init(&rt->tobe_released, &list); |
187 | 196 | ||
188 | list_for_each_safe(pos, safe, &list) { | 197 | list_for_each_safe(pos, safe, &list) { |
@@ -193,36 +202,36 @@ static void arm_release_master(rt_domain_t *_rt) | |||
193 | 202 | ||
194 | /* put into release heap while holding release_lock */ | 203 | /* put into release heap while holding release_lock */ |
195 | raw_spin_lock(&rt->release_lock); | 204 | raw_spin_lock(&rt->release_lock); |
196 | TRACE_TASK(t, "I have the release_lock 0x%p\n", &rt->release_lock); | 205 | VTRACE_TASK(t, "I have the release_lock 0x%p\n", &rt->release_lock); |
197 | 206 | ||
198 | rh = get_release_heap(rt, t, 0); | 207 | rh = get_release_heap(rt, t, 0); |
199 | if (!rh) { | 208 | if (!rh) { |
200 | /* need to use our own, but drop lock first */ | 209 | /* need to use our own, but drop lock first */ |
201 | raw_spin_unlock(&rt->release_lock); | 210 | raw_spin_unlock(&rt->release_lock); |
202 | TRACE_TASK(t, "Dropped release_lock 0x%p\n", | 211 | VTRACE_TASK(t, "Dropped release_lock 0x%p\n", |
203 | &rt->release_lock); | 212 | &rt->release_lock); |
204 | 213 | ||
205 | reinit_release_heap(t); | 214 | reinit_release_heap(t); |
206 | TRACE_TASK(t, "release_heap ready\n"); | 215 | VTRACE_TASK(t, "release_heap ready\n"); |
207 | 216 | ||
208 | raw_spin_lock(&rt->release_lock); | 217 | raw_spin_lock(&rt->release_lock); |
209 | TRACE_TASK(t, "Re-acquired release_lock 0x%p\n", | 218 | VTRACE_TASK(t, "Re-acquired release_lock 0x%p\n", |
210 | &rt->release_lock); | 219 | &rt->release_lock); |
211 | 220 | ||
212 | rh = get_release_heap(rt, t, 1); | 221 | rh = get_release_heap(rt, t, 1); |
213 | } | 222 | } |
214 | bheap_insert(rt->order, &rh->heap, tsk_rt(t)->heap_node); | 223 | bheap_insert(rt->order, &rh->heap, tsk_rt(t)->heap_node); |
215 | TRACE_TASK(t, "arm_release_timer(): added to release heap\n"); | 224 | VTRACE_TASK(t, "arm_release_timer(): added to release heap\n"); |
216 | 225 | ||
217 | raw_spin_unlock(&rt->release_lock); | 226 | raw_spin_unlock(&rt->release_lock); |
218 | TRACE_TASK(t, "Returned the release_lock 0x%p\n", &rt->release_lock); | 227 | VTRACE_TASK(t, "Returned the release_lock 0x%p\n", &rt->release_lock); |
219 | 228 | ||
220 | /* To avoid arming the timer multiple times, we only let the | 229 | /* To avoid arming the timer multiple times, we only let the |
221 | * owner do the arming (which is the "first" task to reference | 230 | * owner do the arming (which is the "first" task to reference |
222 | * this release_heap anyway). | 231 | * this release_heap anyway). |
223 | */ | 232 | */ |
224 | if (rh == tsk_rt(t)->rel_heap) { | 233 | if (rh == tsk_rt(t)->rel_heap) { |
225 | TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); | 234 | VTRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); |
226 | /* we cannot arm the timer using hrtimer_start() | 235 | /* we cannot arm the timer using hrtimer_start() |
227 | * as it may deadlock on rq->lock | 236 | * as it may deadlock on rq->lock |
228 | * | 237 | * |
@@ -246,7 +255,7 @@ static void arm_release_master(rt_domain_t *_rt) | |||
246 | HRTIMER_MODE_ABS_PINNED); | 255 | HRTIMER_MODE_ABS_PINNED); |
247 | #endif | 256 | #endif |
248 | } else | 257 | } else |
249 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); | 258 | VTRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); |
250 | } | 259 | } |
251 | } | 260 | } |
252 | 261 | ||