diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-15 21:53:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-15 21:53:35 -0400 |
commit | 420c1c572d4ceaa2f37b6311b7017ac6cf049fe2 (patch) | |
tree | df04e6b4b756b7a46d9887462d54a3ad0e1f91d5 /kernel/hrtimer.c | |
parent | 9620639b7ea3843983f4ced8b4c81eb4d8974838 (diff) | |
parent | 6e6823d17b157f185be09f4c70181299f9273f0b (diff) |
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (62 commits)
posix-clocks: Check write permissions in posix syscalls
hrtimer: Remove empty hrtimer_init_hres_timer()
hrtimer: Update hrtimer->state documentation
hrtimer: Update base[CLOCK_BOOTTIME].offset correctly
timers: Export CLOCK_BOOTTIME via the posix timers interface
timers: Add CLOCK_BOOTTIME hrtimer base
time: Extend get_xtime_and_monotonic_offset() to also return sleep
time: Introduce get_monotonic_boottime and ktime_get_boottime
hrtimers: extend hrtimer base code to handle more then 2 clockids
ntp: Remove redundant and incorrect parameter check
mn10300: Switch do_timer() to xtimer_update()
posix clocks: Introduce dynamic clocks
posix-timers: Cleanup namespace
posix-timers: Add support for fd based clocks
x86: Add clock_adjtime for x86
posix-timers: Introduce a syscall for clock tuning.
time: Splitout compat timex accessors
ntp: Add ADJ_SETOFFSET mode bit
time: Introduce timekeeping_inject_offset
posix-timer: Update comment
...
Fix up new system-call-related conflicts in
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/unistd_32.h
arch/x86/include/asm/unistd_64.h
arch/x86/kernel/syscall_table_32.S
(name_to_handle_at()/open_by_handle_at() vs clock_adjtime()), and some
due to movement of get_jiffies_64() in:
kernel/time.c
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e38f5a073d0..9017478c5d4 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -53,11 +53,10 @@ | |||
53 | /* | 53 | /* |
54 | * The timer bases: | 54 | * The timer bases: |
55 | * | 55 | * |
56 | * Note: If we want to add new timer bases, we have to skip the two | 56 | * There are more clockids then hrtimer bases. Thus, we index |
57 | * clock ids captured by the cpu-timers. We do this by holding empty | 57 | * into the timer bases by the hrtimer_base_type enum. When trying |
58 | * entries rather than doing math adjustment of the clock ids. | 58 | * to reach a base using a clockid, hrtimer_clockid_to_base() |
59 | * This ensures that we capture erroneous accesses to these clock ids | 59 | * is used to convert from clockid to the proper hrtimer_base_type. |
60 | * rather than moving them into the range of valid clock id's. | ||
61 | */ | 60 | */ |
62 | DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | 61 | DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = |
63 | { | 62 | { |
@@ -74,30 +73,39 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | |||
74 | .get_time = &ktime_get, | 73 | .get_time = &ktime_get, |
75 | .resolution = KTIME_LOW_RES, | 74 | .resolution = KTIME_LOW_RES, |
76 | }, | 75 | }, |
76 | { | ||
77 | .index = CLOCK_BOOTTIME, | ||
78 | .get_time = &ktime_get_boottime, | ||
79 | .resolution = KTIME_LOW_RES, | ||
80 | }, | ||
77 | } | 81 | } |
78 | }; | 82 | }; |
79 | 83 | ||
84 | static int hrtimer_clock_to_base_table[MAX_CLOCKS]; | ||
85 | |||
86 | static inline int hrtimer_clockid_to_base(clockid_t clock_id) | ||
87 | { | ||
88 | return hrtimer_clock_to_base_table[clock_id]; | ||
89 | } | ||
90 | |||
91 | |||
80 | /* | 92 | /* |
81 | * Get the coarse grained time at the softirq based on xtime and | 93 | * Get the coarse grained time at the softirq based on xtime and |
82 | * wall_to_monotonic. | 94 | * wall_to_monotonic. |
83 | */ | 95 | */ |
84 | static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | 96 | static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) |
85 | { | 97 | { |
86 | ktime_t xtim, tomono; | 98 | ktime_t xtim, mono, boot; |
87 | struct timespec xts, tom; | 99 | struct timespec xts, tom, slp; |
88 | unsigned long seq; | ||
89 | 100 | ||
90 | do { | 101 | get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); |
91 | seq = read_seqbegin(&xtime_lock); | ||
92 | xts = __current_kernel_time(); | ||
93 | tom = __get_wall_to_monotonic(); | ||
94 | } while (read_seqretry(&xtime_lock, seq)); | ||
95 | 102 | ||
96 | xtim = timespec_to_ktime(xts); | 103 | xtim = timespec_to_ktime(xts); |
97 | tomono = timespec_to_ktime(tom); | 104 | mono = ktime_add(xtim, timespec_to_ktime(tom)); |
98 | base->clock_base[CLOCK_REALTIME].softirq_time = xtim; | 105 | boot = ktime_add(mono, timespec_to_ktime(slp)); |
99 | base->clock_base[CLOCK_MONOTONIC].softirq_time = | 106 | base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; |
100 | ktime_add(xtim, tomono); | 107 | base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; |
108 | base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; | ||
101 | } | 109 | } |
102 | 110 | ||
103 | /* | 111 | /* |
@@ -184,10 +192,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, | |||
184 | struct hrtimer_cpu_base *new_cpu_base; | 192 | struct hrtimer_cpu_base *new_cpu_base; |
185 | int this_cpu = smp_processor_id(); | 193 | int this_cpu = smp_processor_id(); |
186 | int cpu = hrtimer_get_target(this_cpu, pinned); | 194 | int cpu = hrtimer_get_target(this_cpu, pinned); |
195 | int basenum = hrtimer_clockid_to_base(base->index); | ||
187 | 196 | ||
188 | again: | 197 | again: |
189 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); | 198 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); |
190 | new_base = &new_cpu_base->clock_base[base->index]; | 199 | new_base = &new_cpu_base->clock_base[basenum]; |
191 | 200 | ||
192 | if (base != new_base) { | 201 | if (base != new_base) { |
193 | /* | 202 | /* |
@@ -617,24 +626,23 @@ static int hrtimer_reprogram(struct hrtimer *timer, | |||
617 | static void retrigger_next_event(void *arg) | 626 | static void retrigger_next_event(void *arg) |
618 | { | 627 | { |
619 | struct hrtimer_cpu_base *base; | 628 | struct hrtimer_cpu_base *base; |
620 | struct timespec realtime_offset, wtm; | 629 | struct timespec realtime_offset, wtm, sleep; |
621 | unsigned long seq; | ||
622 | 630 | ||
623 | if (!hrtimer_hres_active()) | 631 | if (!hrtimer_hres_active()) |
624 | return; | 632 | return; |
625 | 633 | ||
626 | do { | 634 | get_xtime_and_monotonic_and_sleep_offset(&realtime_offset, &wtm, |
627 | seq = read_seqbegin(&xtime_lock); | 635 | &sleep); |
628 | wtm = __get_wall_to_monotonic(); | ||
629 | } while (read_seqretry(&xtime_lock, seq)); | ||
630 | set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); | 636 | set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); |
631 | 637 | ||
632 | base = &__get_cpu_var(hrtimer_bases); | 638 | base = &__get_cpu_var(hrtimer_bases); |
633 | 639 | ||
634 | /* Adjust CLOCK_REALTIME offset */ | 640 | /* Adjust CLOCK_REALTIME offset */ |
635 | raw_spin_lock(&base->lock); | 641 | raw_spin_lock(&base->lock); |
636 | base->clock_base[CLOCK_REALTIME].offset = | 642 | base->clock_base[HRTIMER_BASE_REALTIME].offset = |
637 | timespec_to_ktime(realtime_offset); | 643 | timespec_to_ktime(realtime_offset); |
644 | base->clock_base[HRTIMER_BASE_BOOTTIME].offset = | ||
645 | timespec_to_ktime(sleep); | ||
638 | 646 | ||
639 | hrtimer_force_reprogram(base, 0); | 647 | hrtimer_force_reprogram(base, 0); |
640 | raw_spin_unlock(&base->lock); | 648 | raw_spin_unlock(&base->lock); |
@@ -679,14 +687,6 @@ static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) | |||
679 | } | 687 | } |
680 | 688 | ||
681 | /* | 689 | /* |
682 | * Initialize the high resolution related parts of a hrtimer | ||
683 | */ | ||
684 | static inline void hrtimer_init_timer_hres(struct hrtimer *timer) | ||
685 | { | ||
686 | } | ||
687 | |||
688 | |||
689 | /* | ||
690 | * When High resolution timers are active, try to reprogram. Note, that in case | 690 | * When High resolution timers are active, try to reprogram. Note, that in case |
691 | * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry | 691 | * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry |
692 | * check happens. The timer gets enqueued into the rbtree. The reprogramming | 692 | * check happens. The timer gets enqueued into the rbtree. The reprogramming |
@@ -731,8 +731,9 @@ static int hrtimer_switch_to_hres(void) | |||
731 | return 0; | 731 | return 0; |
732 | } | 732 | } |
733 | base->hres_active = 1; | 733 | base->hres_active = 1; |
734 | base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES; | 734 | base->clock_base[HRTIMER_BASE_REALTIME].resolution = KTIME_HIGH_RES; |
735 | base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES; | 735 | base->clock_base[HRTIMER_BASE_MONOTONIC].resolution = KTIME_HIGH_RES; |
736 | base->clock_base[HRTIMER_BASE_BOOTTIME].resolution = KTIME_HIGH_RES; | ||
736 | 737 | ||
737 | tick_setup_sched_timer(); | 738 | tick_setup_sched_timer(); |
738 | 739 | ||
@@ -756,7 +757,6 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, | |||
756 | return 0; | 757 | return 0; |
757 | } | 758 | } |
758 | static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } | 759 | static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } |
759 | static inline void hrtimer_init_timer_hres(struct hrtimer *timer) { } | ||
760 | 760 | ||
761 | #endif /* CONFIG_HIGH_RES_TIMERS */ | 761 | #endif /* CONFIG_HIGH_RES_TIMERS */ |
762 | 762 | ||
@@ -1127,6 +1127,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1127 | enum hrtimer_mode mode) | 1127 | enum hrtimer_mode mode) |
1128 | { | 1128 | { |
1129 | struct hrtimer_cpu_base *cpu_base; | 1129 | struct hrtimer_cpu_base *cpu_base; |
1130 | int base; | ||
1130 | 1131 | ||
1131 | memset(timer, 0, sizeof(struct hrtimer)); | 1132 | memset(timer, 0, sizeof(struct hrtimer)); |
1132 | 1133 | ||
@@ -1135,8 +1136,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1135 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) | 1136 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) |
1136 | clock_id = CLOCK_MONOTONIC; | 1137 | clock_id = CLOCK_MONOTONIC; |
1137 | 1138 | ||
1138 | timer->base = &cpu_base->clock_base[clock_id]; | 1139 | base = hrtimer_clockid_to_base(clock_id); |
1139 | hrtimer_init_timer_hres(timer); | 1140 | timer->base = &cpu_base->clock_base[base]; |
1140 | timerqueue_init(&timer->node); | 1141 | timerqueue_init(&timer->node); |
1141 | 1142 | ||
1142 | #ifdef CONFIG_TIMER_STATS | 1143 | #ifdef CONFIG_TIMER_STATS |
@@ -1171,9 +1172,10 @@ EXPORT_SYMBOL_GPL(hrtimer_init); | |||
1171 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | 1172 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) |
1172 | { | 1173 | { |
1173 | struct hrtimer_cpu_base *cpu_base; | 1174 | struct hrtimer_cpu_base *cpu_base; |
1175 | int base = hrtimer_clockid_to_base(which_clock); | ||
1174 | 1176 | ||
1175 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); | 1177 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); |
1176 | *tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution); | 1178 | *tp = ktime_to_timespec(cpu_base->clock_base[base].resolution); |
1177 | 1179 | ||
1178 | return 0; | 1180 | return 0; |
1179 | } | 1181 | } |
@@ -1720,6 +1722,10 @@ static struct notifier_block __cpuinitdata hrtimers_nb = { | |||
1720 | 1722 | ||
1721 | void __init hrtimers_init(void) | 1723 | void __init hrtimers_init(void) |
1722 | { | 1724 | { |
1725 | hrtimer_clock_to_base_table[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME; | ||
1726 | hrtimer_clock_to_base_table[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC; | ||
1727 | hrtimer_clock_to_base_table[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME; | ||
1728 | |||
1723 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, | 1729 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, |
1724 | (void *)(long)smp_processor_id()); | 1730 | (void *)(long)smp_processor_id()); |
1725 | register_cpu_notifier(&hrtimers_nb); | 1731 | register_cpu_notifier(&hrtimers_nb); |