diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-02 12:48:54 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-02 12:48:54 -0400 |
commit | 41301f22043f92a0a3ee0b7cea8c717555fbe796 (patch) | |
tree | b6b463e9b1e7c9f3842884ee995fbff2008bfa4a | |
parent | fb9c387a4c5b6966369b7e916aef68d07a79e6f6 (diff) |
rt domain: don't arm the same release heap timer twice (bugfix)
If the timeout was realy close and the timing unfortunate, the
timer callback got invoked twice, with oopsing consequences.
-rw-r--r-- | litmus/rt_domain.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index f2e77f828d..e02ec03ca1 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
@@ -124,8 +124,6 @@ static void arm_release_timer(unsigned long _rt) | |||
124 | struct list_head *pos, *safe; | 124 | struct list_head *pos, *safe; |
125 | struct task_struct* t; | 125 | struct task_struct* t; |
126 | struct release_heap* rh; | 126 | struct release_heap* rh; |
127 | int armed; | ||
128 | lt_t release = 0; | ||
129 | 127 | ||
130 | /* We only have to defend against the ISR since norq callbacks | 128 | /* We only have to defend against the ISR since norq callbacks |
131 | * are serialized. | 129 | * are serialized. |
@@ -146,29 +144,26 @@ static void arm_release_timer(unsigned long _rt) | |||
146 | rh = get_release_heap(rt, t); | 144 | rh = get_release_heap(rt, t); |
147 | heap_insert(rt->order, &rh->heap, tsk_rt(t)->heap_node); | 145 | heap_insert(rt->order, &rh->heap, tsk_rt(t)->heap_node); |
148 | TRACE_TASK(t, "arm_release_timer(): added to release heap\n"); | 146 | TRACE_TASK(t, "arm_release_timer(): added to release heap\n"); |
149 | if (rt->release_master == NO_CPU) | ||
150 | armed = hrtimer_active(&rh->timer); | ||
151 | else | ||
152 | armed = atomic_read(&rh->info.state) | ||
153 | != HRTIMER_START_ON_INACTIVE; | ||
154 | release = rh->release_time; | ||
155 | spin_unlock_irqrestore(&rt->release_lock, flags); | 147 | spin_unlock_irqrestore(&rt->release_lock, flags); |
156 | 148 | ||
157 | /* activate timer if necessary */ | 149 | /* To avoid arming the timer multiple times, we only let the |
158 | if (!armed) { | 150 | * owner do the arming (which is the "first" task to reference |
151 | * this release_heap anyway). | ||
152 | */ | ||
153 | if (rh == tsk_rt(t)->rel_heap) { | ||
159 | TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); | 154 | TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); |
160 | if (rt->release_master == NO_CPU) | 155 | if (rt->release_master == NO_CPU) |
161 | hrtimer_start(&rh->timer, | 156 | hrtimer_start(&rh->timer, |
162 | ns_to_ktime(release), | 157 | ns_to_ktime(rh->release_time), |
163 | HRTIMER_MODE_ABS); | 158 | HRTIMER_MODE_ABS); |
164 | else | 159 | else |
165 | hrtimer_start_on(rt->release_master, | 160 | hrtimer_start_on(rt->release_master, |
166 | &rh->info, | 161 | &rh->info, |
167 | &rh->timer, | 162 | &rh->timer, |
168 | ns_to_ktime(release), | 163 | ns_to_ktime(rh->release_time), |
169 | HRTIMER_MODE_ABS); | 164 | HRTIMER_MODE_ABS); |
170 | } else | 165 | } else |
171 | TRACE_TASK(t, "timer already armed.\n"); | 166 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); |
172 | } | 167 | } |
173 | } | 168 | } |
174 | 169 | ||