aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-04 01:17:08 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-05-04 01:17:08 -0400
commit5b0c2aac1d78f1db36c85bd5cd1e215c7cbd2dd6 (patch)
treec5183d5dc2a84fcc36cc30aa38d00bb4b0e1d892
parente20dd584519687867aedc46535c447102e52c70e (diff)
rt domain: evil hack to avoid recursive hrtimer lock acquisition
This is a really dirty hack, but works for now since our real-time tasks do not use hrtimer_wakeup(). The need for this will go away when we port since newer versions of the Linux kernel allow timers to be activated directly in the scheduler.
-rw-r--r--kernel/hrtimer.c8
-rw-r--r--litmus/norqlock.c24
2 files changed, 28 insertions, 4 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 2bd9fc2a59..7b8576b6bd 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1314,6 +1314,9 @@ void hrtimer_run_queues(void)
1314 run_hrtimer_queue(cpu_base, i); 1314 run_hrtimer_queue(cpu_base, i);
1315} 1315}
1316 1316
1317/* FIXME: this won't be needed anymore once we port to Linux > 2.6.24 */
1318void hrtimer_wakeup_hack(int onoff);
1319
1317/* 1320/*
1318 * Sleep related functions: 1321 * Sleep related functions:
1319 */ 1322 */
@@ -1324,8 +1327,11 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
1324 struct task_struct *task = t->task; 1327 struct task_struct *task = t->task;
1325 1328
1326 t->task = NULL; 1329 t->task = NULL;
1327 if (task) 1330 if (task) {
1331 hrtimer_wakeup_hack(1);
1328 wake_up_process(task); 1332 wake_up_process(task);
1333 hrtimer_wakeup_hack(0);
1334 }
1329 1335
1330 return HRTIMER_NORESTART; 1336 return HRTIMER_NORESTART;
1331} 1337}
diff --git a/litmus/norqlock.c b/litmus/norqlock.c
index 769240075a..b812f34960 100644
--- a/litmus/norqlock.c
+++ b/litmus/norqlock.c
@@ -8,9 +8,10 @@
8 8
9struct worklist { 9struct worklist {
10 struct no_rqlock_work* next; 10 struct no_rqlock_work* next;
11 int hrtimer_hack;
11}; 12};
12 13
13static DEFINE_PER_CPU(struct worklist, norq_worklist) = {NULL}; 14static DEFINE_PER_CPU(struct worklist, norq_worklist) = {NULL, 0};
14 15
15void init_no_rqlock_work(struct no_rqlock_work* w, work_t work, 16void init_no_rqlock_work(struct no_rqlock_work* w, work_t work,
16 unsigned long arg) 17 unsigned long arg)
@@ -33,15 +34,32 @@ void __do_without_rqlock(struct no_rqlock_work *work)
33 local_irq_restore(flags); 34 local_irq_restore(flags);
34} 35}
35 36
37void hrtimer_wakeup_hack(int onoff)
38{
39 preempt_disable();
40 __get_cpu_var(norq_worklist).hrtimer_hack = onoff;
41 preempt_enable();
42}
43
36void tick_no_rqlock(void) 44void tick_no_rqlock(void)
37{ 45{
38 long flags; 46 long flags;
39 struct no_rqlock_work *todo, *next; 47 struct no_rqlock_work *todo, *next;
48 struct worklist* wl;
49
40 50
41 local_irq_save(flags); 51 local_irq_save(flags);
42 52
43 next = __get_cpu_var(norq_worklist).next; 53 wl = &__get_cpu_var(norq_worklist);
44 __get_cpu_var(norq_worklist).next = NULL; 54
55 if (wl->hrtimer_hack) {
56 /* bail out! */
57 local_irq_restore(flags);
58 return;
59 }
60
61 next = wl->next;
62 wl->next = NULL;
45 63
46 local_irq_restore(flags); 64 local_irq_restore(flags);
47 65