diff options
author | John Stultz <john.stultz@linaro.org> | 2010-09-20 22:19:17 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2010-12-10 14:54:35 -0500 |
commit | 998adc3dda59f811966b3ccb21eb223680b25ec4 (patch) | |
tree | 791597e9afe00877a3fb1a71c1178e8573767647 /kernel | |
parent | 9bb99b147018945366c763b3d4d7008927dc8557 (diff) |
hrtimers: Convert hrtimers to use timerlist infrastructure
Converts the hrtimer code to use the new timerlist infrastructure
Signed-off-by: John Stultz <john.stultz@linaro.org>
LKML Reference: <1290136329-18291-3-git-send-email-john.stultz@linaro.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
CC: Alessandro Zummo <a.zummo@towertech.it>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Richard Cochran <richardcochran@gmail.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 86 | ||||
-rw-r--r-- | kernel/time/timer_list.c | 8 |
2 files changed, 34 insertions, 60 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index ce669174f355..93976ad42f5a 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -516,10 +516,13 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) | |||
516 | 516 | ||
517 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { | 517 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { |
518 | struct hrtimer *timer; | 518 | struct hrtimer *timer; |
519 | struct timerqueue_node *next; | ||
519 | 520 | ||
520 | if (!base->first) | 521 | next = timerqueue_getnext(&base->active); |
522 | if (!next) | ||
521 | continue; | 523 | continue; |
522 | timer = rb_entry(base->first, struct hrtimer, node); | 524 | timer = container_of(next, struct hrtimer, node); |
525 | |||
523 | expires = ktime_sub(hrtimer_get_expires(timer), base->offset); | 526 | expires = ktime_sub(hrtimer_get_expires(timer), base->offset); |
524 | /* | 527 | /* |
525 | * clock_was_set() has changed base->offset so the | 528 | * clock_was_set() has changed base->offset so the |
@@ -840,48 +843,17 @@ EXPORT_SYMBOL_GPL(hrtimer_forward); | |||
840 | static int enqueue_hrtimer(struct hrtimer *timer, | 843 | static int enqueue_hrtimer(struct hrtimer *timer, |
841 | struct hrtimer_clock_base *base) | 844 | struct hrtimer_clock_base *base) |
842 | { | 845 | { |
843 | struct rb_node **link = &base->active.rb_node; | ||
844 | struct rb_node *parent = NULL; | ||
845 | struct hrtimer *entry; | ||
846 | int leftmost = 1; | ||
847 | |||
848 | debug_activate(timer); | 846 | debug_activate(timer); |
849 | 847 | ||
850 | /* | 848 | timerqueue_add(&base->active, &timer->node); |
851 | * Find the right place in the rbtree: | ||
852 | */ | ||
853 | while (*link) { | ||
854 | parent = *link; | ||
855 | entry = rb_entry(parent, struct hrtimer, node); | ||
856 | /* | ||
857 | * We dont care about collisions. Nodes with | ||
858 | * the same expiry time stay together. | ||
859 | */ | ||
860 | if (hrtimer_get_expires_tv64(timer) < | ||
861 | hrtimer_get_expires_tv64(entry)) { | ||
862 | link = &(*link)->rb_left; | ||
863 | } else { | ||
864 | link = &(*link)->rb_right; | ||
865 | leftmost = 0; | ||
866 | } | ||
867 | } | ||
868 | 849 | ||
869 | /* | 850 | /* |
870 | * Insert the timer to the rbtree and check whether it | ||
871 | * replaces the first pending timer | ||
872 | */ | ||
873 | if (leftmost) | ||
874 | base->first = &timer->node; | ||
875 | |||
876 | rb_link_node(&timer->node, parent, link); | ||
877 | rb_insert_color(&timer->node, &base->active); | ||
878 | /* | ||
879 | * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the | 851 | * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the |
880 | * state of a possibly running callback. | 852 | * state of a possibly running callback. |
881 | */ | 853 | */ |
882 | timer->state |= HRTIMER_STATE_ENQUEUED; | 854 | timer->state |= HRTIMER_STATE_ENQUEUED; |
883 | 855 | ||
884 | return leftmost; | 856 | return (&timer->node == base->active.next); |
885 | } | 857 | } |
886 | 858 | ||
887 | /* | 859 | /* |
@@ -901,12 +873,7 @@ static void __remove_hrtimer(struct hrtimer *timer, | |||
901 | if (!(timer->state & HRTIMER_STATE_ENQUEUED)) | 873 | if (!(timer->state & HRTIMER_STATE_ENQUEUED)) |
902 | goto out; | 874 | goto out; |
903 | 875 | ||
904 | /* | 876 | if (&timer->node == timerqueue_getnext(&base->active)) { |
905 | * Remove the timer from the rbtree and replace the first | ||
906 | * entry pointer if necessary. | ||
907 | */ | ||
908 | if (base->first == &timer->node) { | ||
909 | base->first = rb_next(&timer->node); | ||
910 | #ifdef CONFIG_HIGH_RES_TIMERS | 877 | #ifdef CONFIG_HIGH_RES_TIMERS |
911 | /* Reprogram the clock event device. if enabled */ | 878 | /* Reprogram the clock event device. if enabled */ |
912 | if (reprogram && hrtimer_hres_active()) { | 879 | if (reprogram && hrtimer_hres_active()) { |
@@ -919,7 +886,7 @@ static void __remove_hrtimer(struct hrtimer *timer, | |||
919 | } | 886 | } |
920 | #endif | 887 | #endif |
921 | } | 888 | } |
922 | rb_erase(&timer->node, &base->active); | 889 | timerqueue_del(&base->active, &timer->node); |
923 | out: | 890 | out: |
924 | timer->state = newstate; | 891 | timer->state = newstate; |
925 | } | 892 | } |
@@ -1123,11 +1090,13 @@ ktime_t hrtimer_get_next_event(void) | |||
1123 | if (!hrtimer_hres_active()) { | 1090 | if (!hrtimer_hres_active()) { |
1124 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { | 1091 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { |
1125 | struct hrtimer *timer; | 1092 | struct hrtimer *timer; |
1093 | struct timerqueue_node *next; | ||
1126 | 1094 | ||
1127 | if (!base->first) | 1095 | next = timerqueue_getnext(&base->active); |
1096 | if (!next) | ||
1128 | continue; | 1097 | continue; |
1129 | 1098 | ||
1130 | timer = rb_entry(base->first, struct hrtimer, node); | 1099 | timer = container_of(next, struct hrtimer, node); |
1131 | delta.tv64 = hrtimer_get_expires_tv64(timer); | 1100 | delta.tv64 = hrtimer_get_expires_tv64(timer); |
1132 | delta = ktime_sub(delta, base->get_time()); | 1101 | delta = ktime_sub(delta, base->get_time()); |
1133 | if (delta.tv64 < mindelta.tv64) | 1102 | if (delta.tv64 < mindelta.tv64) |
@@ -1157,6 +1126,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1157 | 1126 | ||
1158 | timer->base = &cpu_base->clock_base[clock_id]; | 1127 | timer->base = &cpu_base->clock_base[clock_id]; |
1159 | hrtimer_init_timer_hres(timer); | 1128 | hrtimer_init_timer_hres(timer); |
1129 | timerqueue_init(&timer->node); | ||
1160 | 1130 | ||
1161 | #ifdef CONFIG_TIMER_STATS | 1131 | #ifdef CONFIG_TIMER_STATS |
1162 | timer->start_site = NULL; | 1132 | timer->start_site = NULL; |
@@ -1270,14 +1240,14 @@ retry: | |||
1270 | 1240 | ||
1271 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { | 1241 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { |
1272 | ktime_t basenow; | 1242 | ktime_t basenow; |
1273 | struct rb_node *node; | 1243 | struct timerqueue_node *node; |
1274 | 1244 | ||
1275 | basenow = ktime_add(now, base->offset); | 1245 | basenow = ktime_add(now, base->offset); |
1276 | 1246 | ||
1277 | while ((node = base->first)) { | 1247 | while ((node = timerqueue_getnext(&base->active))) { |
1278 | struct hrtimer *timer; | 1248 | struct hrtimer *timer; |
1279 | 1249 | ||
1280 | timer = rb_entry(node, struct hrtimer, node); | 1250 | timer = container_of(node, struct hrtimer, node); |
1281 | 1251 | ||
1282 | /* | 1252 | /* |
1283 | * The immediate goal for using the softexpires is | 1253 | * The immediate goal for using the softexpires is |
@@ -1433,7 +1403,7 @@ void hrtimer_run_pending(void) | |||
1433 | */ | 1403 | */ |
1434 | void hrtimer_run_queues(void) | 1404 | void hrtimer_run_queues(void) |
1435 | { | 1405 | { |
1436 | struct rb_node *node; | 1406 | struct timerqueue_node *node; |
1437 | struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); | 1407 | struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); |
1438 | struct hrtimer_clock_base *base; | 1408 | struct hrtimer_clock_base *base; |
1439 | int index, gettime = 1; | 1409 | int index, gettime = 1; |
@@ -1442,9 +1412,11 @@ void hrtimer_run_queues(void) | |||
1442 | return; | 1412 | return; |
1443 | 1413 | ||
1444 | for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) { | 1414 | for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) { |
1445 | base = &cpu_base->clock_base[index]; | 1415 | struct timerqueue_node *next; |
1446 | 1416 | ||
1447 | if (!base->first) | 1417 | base = &cpu_base->clock_base[index]; |
1418 | next = timerqueue_getnext(&base->active); | ||
1419 | if (!next) | ||
1448 | continue; | 1420 | continue; |
1449 | 1421 | ||
1450 | if (gettime) { | 1422 | if (gettime) { |
@@ -1454,10 +1426,10 @@ void hrtimer_run_queues(void) | |||
1454 | 1426 | ||
1455 | raw_spin_lock(&cpu_base->lock); | 1427 | raw_spin_lock(&cpu_base->lock); |
1456 | 1428 | ||
1457 | while ((node = base->first)) { | 1429 | while ((node = next)) { |
1458 | struct hrtimer *timer; | 1430 | struct hrtimer *timer; |
1459 | 1431 | ||
1460 | timer = rb_entry(node, struct hrtimer, node); | 1432 | timer = container_of(node, struct hrtimer, node); |
1461 | if (base->softirq_time.tv64 <= | 1433 | if (base->softirq_time.tv64 <= |
1462 | hrtimer_get_expires_tv64(timer)) | 1434 | hrtimer_get_expires_tv64(timer)) |
1463 | break; | 1435 | break; |
@@ -1622,8 +1594,10 @@ static void __cpuinit init_hrtimers_cpu(int cpu) | |||
1622 | 1594 | ||
1623 | raw_spin_lock_init(&cpu_base->lock); | 1595 | raw_spin_lock_init(&cpu_base->lock); |
1624 | 1596 | ||
1625 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) | 1597 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { |
1626 | cpu_base->clock_base[i].cpu_base = cpu_base; | 1598 | cpu_base->clock_base[i].cpu_base = cpu_base; |
1599 | timerqueue_init_head(&cpu_base->clock_base[i].active); | ||
1600 | } | ||
1627 | 1601 | ||
1628 | hrtimer_init_hres(cpu_base); | 1602 | hrtimer_init_hres(cpu_base); |
1629 | } | 1603 | } |
@@ -1634,10 +1608,10 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, | |||
1634 | struct hrtimer_clock_base *new_base) | 1608 | struct hrtimer_clock_base *new_base) |
1635 | { | 1609 | { |
1636 | struct hrtimer *timer; | 1610 | struct hrtimer *timer; |
1637 | struct rb_node *node; | 1611 | struct timerqueue_node *node; |
1638 | 1612 | ||
1639 | while ((node = rb_first(&old_base->active))) { | 1613 | while ((node = timerqueue_getnext(&old_base->active))) { |
1640 | timer = rb_entry(node, struct hrtimer, node); | 1614 | timer = container_of(node, struct hrtimer, node); |
1641 | BUG_ON(hrtimer_callback_running(timer)); | 1615 | BUG_ON(hrtimer_callback_running(timer)); |
1642 | debug_deactivate(timer); | 1616 | debug_deactivate(timer); |
1643 | 1617 | ||
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index ab8f5e33fa92..32a19f9397fc 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
@@ -79,26 +79,26 @@ print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base, | |||
79 | { | 79 | { |
80 | struct hrtimer *timer, tmp; | 80 | struct hrtimer *timer, tmp; |
81 | unsigned long next = 0, i; | 81 | unsigned long next = 0, i; |
82 | struct rb_node *curr; | 82 | struct timerqueue_node *curr; |
83 | unsigned long flags; | 83 | unsigned long flags; |
84 | 84 | ||
85 | next_one: | 85 | next_one: |
86 | i = 0; | 86 | i = 0; |
87 | raw_spin_lock_irqsave(&base->cpu_base->lock, flags); | 87 | raw_spin_lock_irqsave(&base->cpu_base->lock, flags); |
88 | 88 | ||
89 | curr = base->first; | 89 | curr = timerqueue_getnext(&base->active); |
90 | /* | 90 | /* |
91 | * Crude but we have to do this O(N*N) thing, because | 91 | * Crude but we have to do this O(N*N) thing, because |
92 | * we have to unlock the base when printing: | 92 | * we have to unlock the base when printing: |
93 | */ | 93 | */ |
94 | while (curr && i < next) { | 94 | while (curr && i < next) { |
95 | curr = rb_next(curr); | 95 | curr = timerqueue_iterate_next(curr); |
96 | i++; | 96 | i++; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (curr) { | 99 | if (curr) { |
100 | 100 | ||
101 | timer = rb_entry(curr, struct hrtimer, node); | 101 | timer = container_of(curr, struct hrtimer, node); |
102 | tmp = *timer; | 102 | tmp = *timer; |
103 | raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags); | 103 | raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags); |
104 | 104 | ||