diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-04 01:17:08 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-05-04 01:17:08 -0400 |
commit | 5b0c2aac1d78f1db36c85bd5cd1e215c7cbd2dd6 (patch) | |
tree | c5183d5dc2a84fcc36cc30aa38d00bb4b0e1d892 | |
parent | e20dd584519687867aedc46535c447102e52c70e (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.c | 8 | ||||
-rw-r--r-- | litmus/norqlock.c | 24 |
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 */ | ||
1318 | void 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 | ||
9 | struct worklist { | 9 | struct worklist { |
10 | struct no_rqlock_work* next; | 10 | struct no_rqlock_work* next; |
11 | int hrtimer_hack; | ||
11 | }; | 12 | }; |
12 | 13 | ||
13 | static DEFINE_PER_CPU(struct worklist, norq_worklist) = {NULL}; | 14 | static DEFINE_PER_CPU(struct worklist, norq_worklist) = {NULL, 0}; |
14 | 15 | ||
15 | void init_no_rqlock_work(struct no_rqlock_work* w, work_t work, | 16 | void 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 | ||
37 | void hrtimer_wakeup_hack(int onoff) | ||
38 | { | ||
39 | preempt_disable(); | ||
40 | __get_cpu_var(norq_worklist).hrtimer_hack = onoff; | ||
41 | preempt_enable(); | ||
42 | } | ||
43 | |||
36 | void tick_no_rqlock(void) | 44 | void 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 | ||