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