aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-02 12:48:54 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-02 12:48:54 -0400
commit41301f22043f92a0a3ee0b7cea8c717555fbe796 (patch)
treeb6b463e9b1e7c9f3842884ee995fbff2008bfa4a
parentfb9c387a4c5b6966369b7e916aef68d07a79e6f6 (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.c21
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