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 | |
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')
-rw-r--r-- | kernel/compat.c | 136 | ||||
-rw-r--r-- | kernel/hrtimer.c | 84 | ||||
-rw-r--r-- | kernel/posix-cpu-timers.c | 110 | ||||
-rw-r--r-- | kernel/posix-timers.c | 342 | ||||
-rw-r--r-- | kernel/time.c | 20 | ||||
-rw-r--r-- | kernel/time/Makefile | 3 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 1 | ||||
-rw-r--r-- | kernel/time/jiffies.c | 20 | ||||
-rw-r--r-- | kernel/time/ntp.c | 13 | ||||
-rw-r--r-- | kernel/time/posix-clock.c | 451 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 9 | ||||
-rw-r--r-- | kernel/time/tick-oneshot.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 1 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 141 | ||||
-rw-r--r-- | kernel/timer.c | 13 |
17 files changed, 995 insertions, 352 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index c9e2ec0b34a..38b1d2c1cbe 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -52,6 +52,64 @@ static int compat_put_timeval(struct compat_timeval __user *o, | |||
52 | put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; | 52 | put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp) | ||
56 | { | ||
57 | memset(txc, 0, sizeof(struct timex)); | ||
58 | |||
59 | if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) || | ||
60 | __get_user(txc->modes, &utp->modes) || | ||
61 | __get_user(txc->offset, &utp->offset) || | ||
62 | __get_user(txc->freq, &utp->freq) || | ||
63 | __get_user(txc->maxerror, &utp->maxerror) || | ||
64 | __get_user(txc->esterror, &utp->esterror) || | ||
65 | __get_user(txc->status, &utp->status) || | ||
66 | __get_user(txc->constant, &utp->constant) || | ||
67 | __get_user(txc->precision, &utp->precision) || | ||
68 | __get_user(txc->tolerance, &utp->tolerance) || | ||
69 | __get_user(txc->time.tv_sec, &utp->time.tv_sec) || | ||
70 | __get_user(txc->time.tv_usec, &utp->time.tv_usec) || | ||
71 | __get_user(txc->tick, &utp->tick) || | ||
72 | __get_user(txc->ppsfreq, &utp->ppsfreq) || | ||
73 | __get_user(txc->jitter, &utp->jitter) || | ||
74 | __get_user(txc->shift, &utp->shift) || | ||
75 | __get_user(txc->stabil, &utp->stabil) || | ||
76 | __get_user(txc->jitcnt, &utp->jitcnt) || | ||
77 | __get_user(txc->calcnt, &utp->calcnt) || | ||
78 | __get_user(txc->errcnt, &utp->errcnt) || | ||
79 | __get_user(txc->stbcnt, &utp->stbcnt)) | ||
80 | return -EFAULT; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc) | ||
86 | { | ||
87 | if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) || | ||
88 | __put_user(txc->modes, &utp->modes) || | ||
89 | __put_user(txc->offset, &utp->offset) || | ||
90 | __put_user(txc->freq, &utp->freq) || | ||
91 | __put_user(txc->maxerror, &utp->maxerror) || | ||
92 | __put_user(txc->esterror, &utp->esterror) || | ||
93 | __put_user(txc->status, &utp->status) || | ||
94 | __put_user(txc->constant, &utp->constant) || | ||
95 | __put_user(txc->precision, &utp->precision) || | ||
96 | __put_user(txc->tolerance, &utp->tolerance) || | ||
97 | __put_user(txc->time.tv_sec, &utp->time.tv_sec) || | ||
98 | __put_user(txc->time.tv_usec, &utp->time.tv_usec) || | ||
99 | __put_user(txc->tick, &utp->tick) || | ||
100 | __put_user(txc->ppsfreq, &utp->ppsfreq) || | ||
101 | __put_user(txc->jitter, &utp->jitter) || | ||
102 | __put_user(txc->shift, &utp->shift) || | ||
103 | __put_user(txc->stabil, &utp->stabil) || | ||
104 | __put_user(txc->jitcnt, &utp->jitcnt) || | ||
105 | __put_user(txc->calcnt, &utp->calcnt) || | ||
106 | __put_user(txc->errcnt, &utp->errcnt) || | ||
107 | __put_user(txc->stbcnt, &utp->stbcnt) || | ||
108 | __put_user(txc->tai, &utp->tai)) | ||
109 | return -EFAULT; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
55 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, | 113 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, |
56 | struct timezone __user *tz) | 114 | struct timezone __user *tz) |
57 | { | 115 | { |
@@ -617,6 +675,29 @@ long compat_sys_clock_gettime(clockid_t which_clock, | |||
617 | return err; | 675 | return err; |
618 | } | 676 | } |
619 | 677 | ||
678 | long compat_sys_clock_adjtime(clockid_t which_clock, | ||
679 | struct compat_timex __user *utp) | ||
680 | { | ||
681 | struct timex txc; | ||
682 | mm_segment_t oldfs; | ||
683 | int err, ret; | ||
684 | |||
685 | err = compat_get_timex(&txc, utp); | ||
686 | if (err) | ||
687 | return err; | ||
688 | |||
689 | oldfs = get_fs(); | ||
690 | set_fs(KERNEL_DS); | ||
691 | ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc); | ||
692 | set_fs(oldfs); | ||
693 | |||
694 | err = compat_put_timex(utp, &txc); | ||
695 | if (err) | ||
696 | return err; | ||
697 | |||
698 | return ret; | ||
699 | } | ||
700 | |||
620 | long compat_sys_clock_getres(clockid_t which_clock, | 701 | long compat_sys_clock_getres(clockid_t which_clock, |
621 | struct compat_timespec __user *tp) | 702 | struct compat_timespec __user *tp) |
622 | { | 703 | { |
@@ -951,58 +1032,17 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat | |||
951 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) | 1032 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) |
952 | { | 1033 | { |
953 | struct timex txc; | 1034 | struct timex txc; |
954 | int ret; | 1035 | int err, ret; |
955 | |||
956 | memset(&txc, 0, sizeof(struct timex)); | ||
957 | 1036 | ||
958 | if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) || | 1037 | err = compat_get_timex(&txc, utp); |
959 | __get_user(txc.modes, &utp->modes) || | 1038 | if (err) |
960 | __get_user(txc.offset, &utp->offset) || | 1039 | return err; |
961 | __get_user(txc.freq, &utp->freq) || | ||
962 | __get_user(txc.maxerror, &utp->maxerror) || | ||
963 | __get_user(txc.esterror, &utp->esterror) || | ||
964 | __get_user(txc.status, &utp->status) || | ||
965 | __get_user(txc.constant, &utp->constant) || | ||
966 | __get_user(txc.precision, &utp->precision) || | ||
967 | __get_user(txc.tolerance, &utp->tolerance) || | ||
968 | __get_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
969 | __get_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
970 | __get_user(txc.tick, &utp->tick) || | ||
971 | __get_user(txc.ppsfreq, &utp->ppsfreq) || | ||
972 | __get_user(txc.jitter, &utp->jitter) || | ||
973 | __get_user(txc.shift, &utp->shift) || | ||
974 | __get_user(txc.stabil, &utp->stabil) || | ||
975 | __get_user(txc.jitcnt, &utp->jitcnt) || | ||
976 | __get_user(txc.calcnt, &utp->calcnt) || | ||
977 | __get_user(txc.errcnt, &utp->errcnt) || | ||
978 | __get_user(txc.stbcnt, &utp->stbcnt)) | ||
979 | return -EFAULT; | ||
980 | 1040 | ||
981 | ret = do_adjtimex(&txc); | 1041 | ret = do_adjtimex(&txc); |
982 | 1042 | ||
983 | if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) || | 1043 | err = compat_put_timex(utp, &txc); |
984 | __put_user(txc.modes, &utp->modes) || | 1044 | if (err) |
985 | __put_user(txc.offset, &utp->offset) || | 1045 | return err; |
986 | __put_user(txc.freq, &utp->freq) || | ||
987 | __put_user(txc.maxerror, &utp->maxerror) || | ||
988 | __put_user(txc.esterror, &utp->esterror) || | ||
989 | __put_user(txc.status, &utp->status) || | ||
990 | __put_user(txc.constant, &utp->constant) || | ||
991 | __put_user(txc.precision, &utp->precision) || | ||
992 | __put_user(txc.tolerance, &utp->tolerance) || | ||
993 | __put_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
994 | __put_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
995 | __put_user(txc.tick, &utp->tick) || | ||
996 | __put_user(txc.ppsfreq, &utp->ppsfreq) || | ||
997 | __put_user(txc.jitter, &utp->jitter) || | ||
998 | __put_user(txc.shift, &utp->shift) || | ||
999 | __put_user(txc.stabil, &utp->stabil) || | ||
1000 | __put_user(txc.jitcnt, &utp->jitcnt) || | ||
1001 | __put_user(txc.calcnt, &utp->calcnt) || | ||
1002 | __put_user(txc.errcnt, &utp->errcnt) || | ||
1003 | __put_user(txc.stbcnt, &utp->stbcnt) || | ||
1004 | __put_user(txc.tai, &utp->tai)) | ||
1005 | ret = -EFAULT; | ||
1006 | 1046 | ||
1007 | return ret; | 1047 | return ret; |
1008 | } | 1048 | } |
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); |
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 05bb7173850..67fea9d25d5 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -176,7 +176,8 @@ static inline cputime_t virt_ticks(struct task_struct *p) | |||
176 | return p->utime; | 176 | return p->utime; |
177 | } | 177 | } |
178 | 178 | ||
179 | int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | 179 | static int |
180 | posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | ||
180 | { | 181 | { |
181 | int error = check_clock(which_clock); | 182 | int error = check_clock(which_clock); |
182 | if (!error) { | 183 | if (!error) { |
@@ -194,7 +195,8 @@ int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | |||
194 | return error; | 195 | return error; |
195 | } | 196 | } |
196 | 197 | ||
197 | int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) | 198 | static int |
199 | posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) | ||
198 | { | 200 | { |
199 | /* | 201 | /* |
200 | * You can never reset a CPU clock, but we check for other errors | 202 | * You can never reset a CPU clock, but we check for other errors |
@@ -317,7 +319,7 @@ static int cpu_clock_sample_group(const clockid_t which_clock, | |||
317 | } | 319 | } |
318 | 320 | ||
319 | 321 | ||
320 | int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) | 322 | static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) |
321 | { | 323 | { |
322 | const pid_t pid = CPUCLOCK_PID(which_clock); | 324 | const pid_t pid = CPUCLOCK_PID(which_clock); |
323 | int error = -EINVAL; | 325 | int error = -EINVAL; |
@@ -379,7 +381,7 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) | |||
379 | * This is called from sys_timer_create() and do_cpu_nanosleep() with the | 381 | * This is called from sys_timer_create() and do_cpu_nanosleep() with the |
380 | * new timer already all-zeros initialized. | 382 | * new timer already all-zeros initialized. |
381 | */ | 383 | */ |
382 | int posix_cpu_timer_create(struct k_itimer *new_timer) | 384 | static int posix_cpu_timer_create(struct k_itimer *new_timer) |
383 | { | 385 | { |
384 | int ret = 0; | 386 | int ret = 0; |
385 | const pid_t pid = CPUCLOCK_PID(new_timer->it_clock); | 387 | const pid_t pid = CPUCLOCK_PID(new_timer->it_clock); |
@@ -425,7 +427,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) | |||
425 | * If we return TIMER_RETRY, it's necessary to release the timer's lock | 427 | * If we return TIMER_RETRY, it's necessary to release the timer's lock |
426 | * and try again. (This happens when the timer is in the middle of firing.) | 428 | * and try again. (This happens when the timer is in the middle of firing.) |
427 | */ | 429 | */ |
428 | int posix_cpu_timer_del(struct k_itimer *timer) | 430 | static int posix_cpu_timer_del(struct k_itimer *timer) |
429 | { | 431 | { |
430 | struct task_struct *p = timer->it.cpu.task; | 432 | struct task_struct *p = timer->it.cpu.task; |
431 | int ret = 0; | 433 | int ret = 0; |
@@ -665,8 +667,8 @@ static int cpu_timer_sample_group(const clockid_t which_clock, | |||
665 | * If we return TIMER_RETRY, it's necessary to release the timer's lock | 667 | * If we return TIMER_RETRY, it's necessary to release the timer's lock |
666 | * and try again. (This happens when the timer is in the middle of firing.) | 668 | * and try again. (This happens when the timer is in the middle of firing.) |
667 | */ | 669 | */ |
668 | int posix_cpu_timer_set(struct k_itimer *timer, int flags, | 670 | static int posix_cpu_timer_set(struct k_itimer *timer, int flags, |
669 | struct itimerspec *new, struct itimerspec *old) | 671 | struct itimerspec *new, struct itimerspec *old) |
670 | { | 672 | { |
671 | struct task_struct *p = timer->it.cpu.task; | 673 | struct task_struct *p = timer->it.cpu.task; |
672 | union cpu_time_count old_expires, new_expires, old_incr, val; | 674 | union cpu_time_count old_expires, new_expires, old_incr, val; |
@@ -820,7 +822,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags, | |||
820 | return ret; | 822 | return ret; |
821 | } | 823 | } |
822 | 824 | ||
823 | void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | 825 | static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) |
824 | { | 826 | { |
825 | union cpu_time_count now; | 827 | union cpu_time_count now; |
826 | struct task_struct *p = timer->it.cpu.task; | 828 | struct task_struct *p = timer->it.cpu.task; |
@@ -1481,11 +1483,13 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1481 | return error; | 1483 | return error; |
1482 | } | 1484 | } |
1483 | 1485 | ||
1484 | int posix_cpu_nsleep(const clockid_t which_clock, int flags, | 1486 | static long posix_cpu_nsleep_restart(struct restart_block *restart_block); |
1485 | struct timespec *rqtp, struct timespec __user *rmtp) | 1487 | |
1488 | static int posix_cpu_nsleep(const clockid_t which_clock, int flags, | ||
1489 | struct timespec *rqtp, struct timespec __user *rmtp) | ||
1486 | { | 1490 | { |
1487 | struct restart_block *restart_block = | 1491 | struct restart_block *restart_block = |
1488 | ¤t_thread_info()->restart_block; | 1492 | ¤t_thread_info()->restart_block; |
1489 | struct itimerspec it; | 1493 | struct itimerspec it; |
1490 | int error; | 1494 | int error; |
1491 | 1495 | ||
@@ -1501,56 +1505,47 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags, | |||
1501 | 1505 | ||
1502 | if (error == -ERESTART_RESTARTBLOCK) { | 1506 | if (error == -ERESTART_RESTARTBLOCK) { |
1503 | 1507 | ||
1504 | if (flags & TIMER_ABSTIME) | 1508 | if (flags & TIMER_ABSTIME) |
1505 | return -ERESTARTNOHAND; | 1509 | return -ERESTARTNOHAND; |
1506 | /* | 1510 | /* |
1507 | * Report back to the user the time still remaining. | 1511 | * Report back to the user the time still remaining. |
1508 | */ | 1512 | */ |
1509 | if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) | 1513 | if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) |
1510 | return -EFAULT; | 1514 | return -EFAULT; |
1511 | 1515 | ||
1512 | restart_block->fn = posix_cpu_nsleep_restart; | 1516 | restart_block->fn = posix_cpu_nsleep_restart; |
1513 | restart_block->arg0 = which_clock; | 1517 | restart_block->nanosleep.index = which_clock; |
1514 | restart_block->arg1 = (unsigned long) rmtp; | 1518 | restart_block->nanosleep.rmtp = rmtp; |
1515 | restart_block->arg2 = rqtp->tv_sec; | 1519 | restart_block->nanosleep.expires = timespec_to_ns(rqtp); |
1516 | restart_block->arg3 = rqtp->tv_nsec; | ||
1517 | } | 1520 | } |
1518 | return error; | 1521 | return error; |
1519 | } | 1522 | } |
1520 | 1523 | ||
1521 | long posix_cpu_nsleep_restart(struct restart_block *restart_block) | 1524 | static long posix_cpu_nsleep_restart(struct restart_block *restart_block) |
1522 | { | 1525 | { |
1523 | clockid_t which_clock = restart_block->arg0; | 1526 | clockid_t which_clock = restart_block->nanosleep.index; |
1524 | struct timespec __user *rmtp; | ||
1525 | struct timespec t; | 1527 | struct timespec t; |
1526 | struct itimerspec it; | 1528 | struct itimerspec it; |
1527 | int error; | 1529 | int error; |
1528 | 1530 | ||
1529 | rmtp = (struct timespec __user *) restart_block->arg1; | 1531 | t = ns_to_timespec(restart_block->nanosleep.expires); |
1530 | t.tv_sec = restart_block->arg2; | ||
1531 | t.tv_nsec = restart_block->arg3; | ||
1532 | 1532 | ||
1533 | restart_block->fn = do_no_restart_syscall; | ||
1534 | error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it); | 1533 | error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it); |
1535 | 1534 | ||
1536 | if (error == -ERESTART_RESTARTBLOCK) { | 1535 | if (error == -ERESTART_RESTARTBLOCK) { |
1536 | struct timespec __user *rmtp = restart_block->nanosleep.rmtp; | ||
1537 | /* | 1537 | /* |
1538 | * Report back to the user the time still remaining. | 1538 | * Report back to the user the time still remaining. |
1539 | */ | 1539 | */ |
1540 | if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) | 1540 | if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) |
1541 | return -EFAULT; | 1541 | return -EFAULT; |
1542 | 1542 | ||
1543 | restart_block->fn = posix_cpu_nsleep_restart; | 1543 | restart_block->nanosleep.expires = timespec_to_ns(&t); |
1544 | restart_block->arg0 = which_clock; | ||
1545 | restart_block->arg1 = (unsigned long) rmtp; | ||
1546 | restart_block->arg2 = t.tv_sec; | ||
1547 | restart_block->arg3 = t.tv_nsec; | ||
1548 | } | 1544 | } |
1549 | return error; | 1545 | return error; |
1550 | 1546 | ||
1551 | } | 1547 | } |
1552 | 1548 | ||
1553 | |||
1554 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) | 1549 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) |
1555 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) | 1550 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) |
1556 | 1551 | ||
@@ -1594,38 +1589,37 @@ static int thread_cpu_timer_create(struct k_itimer *timer) | |||
1594 | timer->it_clock = THREAD_CLOCK; | 1589 | timer->it_clock = THREAD_CLOCK; |
1595 | return posix_cpu_timer_create(timer); | 1590 | return posix_cpu_timer_create(timer); |
1596 | } | 1591 | } |
1597 | static int thread_cpu_nsleep(const clockid_t which_clock, int flags, | 1592 | |
1598 | struct timespec *rqtp, struct timespec __user *rmtp) | 1593 | struct k_clock clock_posix_cpu = { |
1599 | { | 1594 | .clock_getres = posix_cpu_clock_getres, |
1600 | return -EINVAL; | 1595 | .clock_set = posix_cpu_clock_set, |
1601 | } | 1596 | .clock_get = posix_cpu_clock_get, |
1602 | static long thread_cpu_nsleep_restart(struct restart_block *restart_block) | 1597 | .timer_create = posix_cpu_timer_create, |
1603 | { | 1598 | .nsleep = posix_cpu_nsleep, |
1604 | return -EINVAL; | 1599 | .nsleep_restart = posix_cpu_nsleep_restart, |
1605 | } | 1600 | .timer_set = posix_cpu_timer_set, |
1601 | .timer_del = posix_cpu_timer_del, | ||
1602 | .timer_get = posix_cpu_timer_get, | ||
1603 | }; | ||
1606 | 1604 | ||
1607 | static __init int init_posix_cpu_timers(void) | 1605 | static __init int init_posix_cpu_timers(void) |
1608 | { | 1606 | { |
1609 | struct k_clock process = { | 1607 | struct k_clock process = { |
1610 | .clock_getres = process_cpu_clock_getres, | 1608 | .clock_getres = process_cpu_clock_getres, |
1611 | .clock_get = process_cpu_clock_get, | 1609 | .clock_get = process_cpu_clock_get, |
1612 | .clock_set = do_posix_clock_nosettime, | 1610 | .timer_create = process_cpu_timer_create, |
1613 | .timer_create = process_cpu_timer_create, | 1611 | .nsleep = process_cpu_nsleep, |
1614 | .nsleep = process_cpu_nsleep, | 1612 | .nsleep_restart = process_cpu_nsleep_restart, |
1615 | .nsleep_restart = process_cpu_nsleep_restart, | ||
1616 | }; | 1613 | }; |
1617 | struct k_clock thread = { | 1614 | struct k_clock thread = { |
1618 | .clock_getres = thread_cpu_clock_getres, | 1615 | .clock_getres = thread_cpu_clock_getres, |
1619 | .clock_get = thread_cpu_clock_get, | 1616 | .clock_get = thread_cpu_clock_get, |
1620 | .clock_set = do_posix_clock_nosettime, | 1617 | .timer_create = thread_cpu_timer_create, |
1621 | .timer_create = thread_cpu_timer_create, | ||
1622 | .nsleep = thread_cpu_nsleep, | ||
1623 | .nsleep_restart = thread_cpu_nsleep_restart, | ||
1624 | }; | 1618 | }; |
1625 | struct timespec ts; | 1619 | struct timespec ts; |
1626 | 1620 | ||
1627 | register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process); | 1621 | posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process); |
1628 | register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread); | 1622 | posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread); |
1629 | 1623 | ||
1630 | cputime_to_timespec(cputime_one_jiffy, &ts); | 1624 | cputime_to_timespec(cputime_one_jiffy, &ts); |
1631 | onecputick = ts.tv_nsec; | 1625 | onecputick = ts.tv_nsec; |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 93bd2eb2bc5..4c0124919f9 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/compiler.h> | 42 | #include <linux/compiler.h> |
43 | #include <linux/idr.h> | 43 | #include <linux/idr.h> |
44 | #include <linux/posix-clock.h> | ||
44 | #include <linux/posix-timers.h> | 45 | #include <linux/posix-timers.h> |
45 | #include <linux/syscalls.h> | 46 | #include <linux/syscalls.h> |
46 | #include <linux/wait.h> | 47 | #include <linux/wait.h> |
@@ -81,6 +82,14 @@ static DEFINE_SPINLOCK(idr_lock); | |||
81 | #error "SIGEV_THREAD_ID must not share bit with other SIGEV values!" | 82 | #error "SIGEV_THREAD_ID must not share bit with other SIGEV values!" |
82 | #endif | 83 | #endif |
83 | 84 | ||
85 | /* | ||
86 | * parisc wants ENOTSUP instead of EOPNOTSUPP | ||
87 | */ | ||
88 | #ifndef ENOTSUP | ||
89 | # define ENANOSLEEP_NOTSUP EOPNOTSUPP | ||
90 | #else | ||
91 | # define ENANOSLEEP_NOTSUP ENOTSUP | ||
92 | #endif | ||
84 | 93 | ||
85 | /* | 94 | /* |
86 | * The timer ID is turned into a timer address by idr_find(). | 95 | * The timer ID is turned into a timer address by idr_find(). |
@@ -94,11 +103,7 @@ static DEFINE_SPINLOCK(idr_lock); | |||
94 | /* | 103 | /* |
95 | * CLOCKs: The POSIX standard calls for a couple of clocks and allows us | 104 | * CLOCKs: The POSIX standard calls for a couple of clocks and allows us |
96 | * to implement others. This structure defines the various | 105 | * to implement others. This structure defines the various |
97 | * clocks and allows the possibility of adding others. We | 106 | * clocks. |
98 | * provide an interface to add clocks to the table and expect | ||
99 | * the "arch" code to add at least one clock that is high | ||
100 | * resolution. Here we define the standard CLOCK_REALTIME as a | ||
101 | * 1/HZ resolution clock. | ||
102 | * | 107 | * |
103 | * RESOLUTION: Clock resolution is used to round up timer and interval | 108 | * RESOLUTION: Clock resolution is used to round up timer and interval |
104 | * times, NOT to report clock times, which are reported with as | 109 | * times, NOT to report clock times, which are reported with as |
@@ -108,20 +113,13 @@ static DEFINE_SPINLOCK(idr_lock); | |||
108 | * necessary code is written. The standard says we should say | 113 | * necessary code is written. The standard says we should say |
109 | * something about this issue in the documentation... | 114 | * something about this issue in the documentation... |
110 | * | 115 | * |
111 | * FUNCTIONS: The CLOCKs structure defines possible functions to handle | 116 | * FUNCTIONS: The CLOCKs structure defines possible functions to |
112 | * various clock functions. For clocks that use the standard | 117 | * handle various clock functions. |
113 | * system timer code these entries should be NULL. This will | ||
114 | * allow dispatch without the overhead of indirect function | ||
115 | * calls. CLOCKS that depend on other sources (e.g. WWV or GPS) | ||
116 | * must supply functions here, even if the function just returns | ||
117 | * ENOSYS. The standard POSIX timer management code assumes the | ||
118 | * following: 1.) The k_itimer struct (sched.h) is used for the | ||
119 | * timer. 2.) The list, it_lock, it_clock, it_id and it_pid | ||
120 | * fields are not modified by timer code. | ||
121 | * | 118 | * |
122 | * At this time all functions EXCEPT clock_nanosleep can be | 119 | * The standard POSIX timer management code assumes the |
123 | * redirected by the CLOCKS structure. Clock_nanosleep is in | 120 | * following: 1.) The k_itimer struct (sched.h) is used for |
124 | * there, but the code ignores it. | 121 | * the timer. 2.) The list, it_lock, it_clock, it_id and |
122 | * it_pid fields are not modified by timer code. | ||
125 | * | 123 | * |
126 | * Permissions: It is assumed that the clock_settime() function defined | 124 | * Permissions: It is assumed that the clock_settime() function defined |
127 | * for each clock will take care of permission checks. Some | 125 | * for each clock will take care of permission checks. Some |
@@ -138,6 +136,7 @@ static struct k_clock posix_clocks[MAX_CLOCKS]; | |||
138 | */ | 136 | */ |
139 | static int common_nsleep(const clockid_t, int flags, struct timespec *t, | 137 | static int common_nsleep(const clockid_t, int flags, struct timespec *t, |
140 | struct timespec __user *rmtp); | 138 | struct timespec __user *rmtp); |
139 | static int common_timer_create(struct k_itimer *new_timer); | ||
141 | static void common_timer_get(struct k_itimer *, struct itimerspec *); | 140 | static void common_timer_get(struct k_itimer *, struct itimerspec *); |
142 | static int common_timer_set(struct k_itimer *, int, | 141 | static int common_timer_set(struct k_itimer *, int, |
143 | struct itimerspec *, struct itimerspec *); | 142 | struct itimerspec *, struct itimerspec *); |
@@ -158,76 +157,24 @@ static inline void unlock_timer(struct k_itimer *timr, unsigned long flags) | |||
158 | spin_unlock_irqrestore(&timr->it_lock, flags); | 157 | spin_unlock_irqrestore(&timr->it_lock, flags); |
159 | } | 158 | } |
160 | 159 | ||
161 | /* | 160 | /* Get clock_realtime */ |
162 | * Call the k_clock hook function if non-null, or the default function. | 161 | static int posix_clock_realtime_get(clockid_t which_clock, struct timespec *tp) |
163 | */ | ||
164 | #define CLOCK_DISPATCH(clock, call, arglist) \ | ||
165 | ((clock) < 0 ? posix_cpu_##call arglist : \ | ||
166 | (posix_clocks[clock].call != NULL \ | ||
167 | ? (*posix_clocks[clock].call) arglist : common_##call arglist)) | ||
168 | |||
169 | /* | ||
170 | * Default clock hook functions when the struct k_clock passed | ||
171 | * to register_posix_clock leaves a function pointer null. | ||
172 | * | ||
173 | * The function common_CALL is the default implementation for | ||
174 | * the function pointer CALL in struct k_clock. | ||
175 | */ | ||
176 | |||
177 | static inline int common_clock_getres(const clockid_t which_clock, | ||
178 | struct timespec *tp) | ||
179 | { | ||
180 | tp->tv_sec = 0; | ||
181 | tp->tv_nsec = posix_clocks[which_clock].res; | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * Get real time for posix timers | ||
187 | */ | ||
188 | static int common_clock_get(clockid_t which_clock, struct timespec *tp) | ||
189 | { | 162 | { |
190 | ktime_get_real_ts(tp); | 163 | ktime_get_real_ts(tp); |
191 | return 0; | 164 | return 0; |
192 | } | 165 | } |
193 | 166 | ||
194 | static inline int common_clock_set(const clockid_t which_clock, | 167 | /* Set clock_realtime */ |
195 | struct timespec *tp) | 168 | static int posix_clock_realtime_set(const clockid_t which_clock, |
169 | const struct timespec *tp) | ||
196 | { | 170 | { |
197 | return do_sys_settimeofday(tp, NULL); | 171 | return do_sys_settimeofday(tp, NULL); |
198 | } | 172 | } |
199 | 173 | ||
200 | static int common_timer_create(struct k_itimer *new_timer) | 174 | static int posix_clock_realtime_adj(const clockid_t which_clock, |
201 | { | 175 | struct timex *t) |
202 | hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int no_timer_create(struct k_itimer *new_timer) | ||
207 | { | ||
208 | return -EOPNOTSUPP; | ||
209 | } | ||
210 | |||
211 | static int no_nsleep(const clockid_t which_clock, int flags, | ||
212 | struct timespec *tsave, struct timespec __user *rmtp) | ||
213 | { | ||
214 | return -EOPNOTSUPP; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Return nonzero if we know a priori this clockid_t value is bogus. | ||
219 | */ | ||
220 | static inline int invalid_clockid(const clockid_t which_clock) | ||
221 | { | 176 | { |
222 | if (which_clock < 0) /* CPU clock, posix_cpu_* will check it */ | 177 | return do_adjtimex(t); |
223 | return 0; | ||
224 | if ((unsigned) which_clock >= MAX_CLOCKS) | ||
225 | return 1; | ||
226 | if (posix_clocks[which_clock].clock_getres != NULL) | ||
227 | return 0; | ||
228 | if (posix_clocks[which_clock].res != 0) | ||
229 | return 0; | ||
230 | return 1; | ||
231 | } | 178 | } |
232 | 179 | ||
233 | /* | 180 | /* |
@@ -240,7 +187,7 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp) | |||
240 | } | 187 | } |
241 | 188 | ||
242 | /* | 189 | /* |
243 | * Get monotonic time for posix timers | 190 | * Get monotonic-raw time for posix timers |
244 | */ | 191 | */ |
245 | static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp) | 192 | static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp) |
246 | { | 193 | { |
@@ -267,46 +214,70 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp | |||
267 | *tp = ktime_to_timespec(KTIME_LOW_RES); | 214 | *tp = ktime_to_timespec(KTIME_LOW_RES); |
268 | return 0; | 215 | return 0; |
269 | } | 216 | } |
217 | |||
218 | static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp) | ||
219 | { | ||
220 | get_monotonic_boottime(tp); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | |||
270 | /* | 225 | /* |
271 | * Initialize everything, well, just everything in Posix clocks/timers ;) | 226 | * Initialize everything, well, just everything in Posix clocks/timers ;) |
272 | */ | 227 | */ |
273 | static __init int init_posix_timers(void) | 228 | static __init int init_posix_timers(void) |
274 | { | 229 | { |
275 | struct k_clock clock_realtime = { | 230 | struct k_clock clock_realtime = { |
276 | .clock_getres = hrtimer_get_res, | 231 | .clock_getres = hrtimer_get_res, |
232 | .clock_get = posix_clock_realtime_get, | ||
233 | .clock_set = posix_clock_realtime_set, | ||
234 | .clock_adj = posix_clock_realtime_adj, | ||
235 | .nsleep = common_nsleep, | ||
236 | .nsleep_restart = hrtimer_nanosleep_restart, | ||
237 | .timer_create = common_timer_create, | ||
238 | .timer_set = common_timer_set, | ||
239 | .timer_get = common_timer_get, | ||
240 | .timer_del = common_timer_del, | ||
277 | }; | 241 | }; |
278 | struct k_clock clock_monotonic = { | 242 | struct k_clock clock_monotonic = { |
279 | .clock_getres = hrtimer_get_res, | 243 | .clock_getres = hrtimer_get_res, |
280 | .clock_get = posix_ktime_get_ts, | 244 | .clock_get = posix_ktime_get_ts, |
281 | .clock_set = do_posix_clock_nosettime, | 245 | .nsleep = common_nsleep, |
246 | .nsleep_restart = hrtimer_nanosleep_restart, | ||
247 | .timer_create = common_timer_create, | ||
248 | .timer_set = common_timer_set, | ||
249 | .timer_get = common_timer_get, | ||
250 | .timer_del = common_timer_del, | ||
282 | }; | 251 | }; |
283 | struct k_clock clock_monotonic_raw = { | 252 | struct k_clock clock_monotonic_raw = { |
284 | .clock_getres = hrtimer_get_res, | 253 | .clock_getres = hrtimer_get_res, |
285 | .clock_get = posix_get_monotonic_raw, | 254 | .clock_get = posix_get_monotonic_raw, |
286 | .clock_set = do_posix_clock_nosettime, | ||
287 | .timer_create = no_timer_create, | ||
288 | .nsleep = no_nsleep, | ||
289 | }; | 255 | }; |
290 | struct k_clock clock_realtime_coarse = { | 256 | struct k_clock clock_realtime_coarse = { |
291 | .clock_getres = posix_get_coarse_res, | 257 | .clock_getres = posix_get_coarse_res, |
292 | .clock_get = posix_get_realtime_coarse, | 258 | .clock_get = posix_get_realtime_coarse, |
293 | .clock_set = do_posix_clock_nosettime, | ||
294 | .timer_create = no_timer_create, | ||
295 | .nsleep = no_nsleep, | ||
296 | }; | 259 | }; |
297 | struct k_clock clock_monotonic_coarse = { | 260 | struct k_clock clock_monotonic_coarse = { |
298 | .clock_getres = posix_get_coarse_res, | 261 | .clock_getres = posix_get_coarse_res, |
299 | .clock_get = posix_get_monotonic_coarse, | 262 | .clock_get = posix_get_monotonic_coarse, |
300 | .clock_set = do_posix_clock_nosettime, | 263 | }; |
301 | .timer_create = no_timer_create, | 264 | struct k_clock clock_boottime = { |
302 | .nsleep = no_nsleep, | 265 | .clock_getres = hrtimer_get_res, |
266 | .clock_get = posix_get_boottime, | ||
267 | .nsleep = common_nsleep, | ||
268 | .nsleep_restart = hrtimer_nanosleep_restart, | ||
269 | .timer_create = common_timer_create, | ||
270 | .timer_set = common_timer_set, | ||
271 | .timer_get = common_timer_get, | ||
272 | .timer_del = common_timer_del, | ||
303 | }; | 273 | }; |
304 | 274 | ||
305 | register_posix_clock(CLOCK_REALTIME, &clock_realtime); | 275 | posix_timers_register_clock(CLOCK_REALTIME, &clock_realtime); |
306 | register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic); | 276 | posix_timers_register_clock(CLOCK_MONOTONIC, &clock_monotonic); |
307 | register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw); | 277 | posix_timers_register_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw); |
308 | register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse); | 278 | posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse); |
309 | register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse); | 279 | posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse); |
280 | posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime); | ||
310 | 281 | ||
311 | posix_timers_cache = kmem_cache_create("posix_timers_cache", | 282 | posix_timers_cache = kmem_cache_create("posix_timers_cache", |
312 | sizeof (struct k_itimer), 0, SLAB_PANIC, | 283 | sizeof (struct k_itimer), 0, SLAB_PANIC, |
@@ -482,17 +453,29 @@ static struct pid *good_sigevent(sigevent_t * event) | |||
482 | return task_pid(rtn); | 453 | return task_pid(rtn); |
483 | } | 454 | } |
484 | 455 | ||
485 | void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock) | 456 | void posix_timers_register_clock(const clockid_t clock_id, |
457 | struct k_clock *new_clock) | ||
486 | { | 458 | { |
487 | if ((unsigned) clock_id >= MAX_CLOCKS) { | 459 | if ((unsigned) clock_id >= MAX_CLOCKS) { |
488 | printk("POSIX clock register failed for clock_id %d\n", | 460 | printk(KERN_WARNING "POSIX clock register failed for clock_id %d\n", |
461 | clock_id); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | if (!new_clock->clock_get) { | ||
466 | printk(KERN_WARNING "POSIX clock id %d lacks clock_get()\n", | ||
467 | clock_id); | ||
468 | return; | ||
469 | } | ||
470 | if (!new_clock->clock_getres) { | ||
471 | printk(KERN_WARNING "POSIX clock id %d lacks clock_getres()\n", | ||
489 | clock_id); | 472 | clock_id); |
490 | return; | 473 | return; |
491 | } | 474 | } |
492 | 475 | ||
493 | posix_clocks[clock_id] = *new_clock; | 476 | posix_clocks[clock_id] = *new_clock; |
494 | } | 477 | } |
495 | EXPORT_SYMBOL_GPL(register_posix_clock); | 478 | EXPORT_SYMBOL_GPL(posix_timers_register_clock); |
496 | 479 | ||
497 | static struct k_itimer * alloc_posix_timer(void) | 480 | static struct k_itimer * alloc_posix_timer(void) |
498 | { | 481 | { |
@@ -523,19 +506,39 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) | |||
523 | kmem_cache_free(posix_timers_cache, tmr); | 506 | kmem_cache_free(posix_timers_cache, tmr); |
524 | } | 507 | } |
525 | 508 | ||
509 | static struct k_clock *clockid_to_kclock(const clockid_t id) | ||
510 | { | ||
511 | if (id < 0) | ||
512 | return (id & CLOCKFD_MASK) == CLOCKFD ? | ||
513 | &clock_posix_dynamic : &clock_posix_cpu; | ||
514 | |||
515 | if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres) | ||
516 | return NULL; | ||
517 | return &posix_clocks[id]; | ||
518 | } | ||
519 | |||
520 | static int common_timer_create(struct k_itimer *new_timer) | ||
521 | { | ||
522 | hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /* Create a POSIX.1b interval timer. */ | 526 | /* Create a POSIX.1b interval timer. */ |
527 | 527 | ||
528 | SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | 528 | SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, |
529 | struct sigevent __user *, timer_event_spec, | 529 | struct sigevent __user *, timer_event_spec, |
530 | timer_t __user *, created_timer_id) | 530 | timer_t __user *, created_timer_id) |
531 | { | 531 | { |
532 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
532 | struct k_itimer *new_timer; | 533 | struct k_itimer *new_timer; |
533 | int error, new_timer_id; | 534 | int error, new_timer_id; |
534 | sigevent_t event; | 535 | sigevent_t event; |
535 | int it_id_set = IT_ID_NOT_SET; | 536 | int it_id_set = IT_ID_NOT_SET; |
536 | 537 | ||
537 | if (invalid_clockid(which_clock)) | 538 | if (!kc) |
538 | return -EINVAL; | 539 | return -EINVAL; |
540 | if (!kc->timer_create) | ||
541 | return -EOPNOTSUPP; | ||
539 | 542 | ||
540 | new_timer = alloc_posix_timer(); | 543 | new_timer = alloc_posix_timer(); |
541 | if (unlikely(!new_timer)) | 544 | if (unlikely(!new_timer)) |
@@ -597,7 +600,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
597 | goto out; | 600 | goto out; |
598 | } | 601 | } |
599 | 602 | ||
600 | error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer)); | 603 | error = kc->timer_create(new_timer); |
601 | if (error) | 604 | if (error) |
602 | goto out; | 605 | goto out; |
603 | 606 | ||
@@ -607,7 +610,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
607 | spin_unlock_irq(¤t->sighand->siglock); | 610 | spin_unlock_irq(¤t->sighand->siglock); |
608 | 611 | ||
609 | return 0; | 612 | return 0; |
610 | /* | 613 | /* |
611 | * In the case of the timer belonging to another task, after | 614 | * In the case of the timer belonging to another task, after |
612 | * the task is unlocked, the timer is owned by the other task | 615 | * the task is unlocked, the timer is owned by the other task |
613 | * and may cease to exist at any time. Don't use or modify | 616 | * and may cease to exist at any time. Don't use or modify |
@@ -709,22 +712,28 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) | |||
709 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | 712 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, |
710 | struct itimerspec __user *, setting) | 713 | struct itimerspec __user *, setting) |
711 | { | 714 | { |
712 | struct k_itimer *timr; | ||
713 | struct itimerspec cur_setting; | 715 | struct itimerspec cur_setting; |
716 | struct k_itimer *timr; | ||
717 | struct k_clock *kc; | ||
714 | unsigned long flags; | 718 | unsigned long flags; |
719 | int ret = 0; | ||
715 | 720 | ||
716 | timr = lock_timer(timer_id, &flags); | 721 | timr = lock_timer(timer_id, &flags); |
717 | if (!timr) | 722 | if (!timr) |
718 | return -EINVAL; | 723 | return -EINVAL; |
719 | 724 | ||
720 | CLOCK_DISPATCH(timr->it_clock, timer_get, (timr, &cur_setting)); | 725 | kc = clockid_to_kclock(timr->it_clock); |
726 | if (WARN_ON_ONCE(!kc || !kc->timer_get)) | ||
727 | ret = -EINVAL; | ||
728 | else | ||
729 | kc->timer_get(timr, &cur_setting); | ||
721 | 730 | ||
722 | unlock_timer(timr, flags); | 731 | unlock_timer(timr, flags); |
723 | 732 | ||
724 | if (copy_to_user(setting, &cur_setting, sizeof (cur_setting))) | 733 | if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting))) |
725 | return -EFAULT; | 734 | return -EFAULT; |
726 | 735 | ||
727 | return 0; | 736 | return ret; |
728 | } | 737 | } |
729 | 738 | ||
730 | /* | 739 | /* |
@@ -813,6 +822,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, | |||
813 | int error = 0; | 822 | int error = 0; |
814 | unsigned long flag; | 823 | unsigned long flag; |
815 | struct itimerspec *rtn = old_setting ? &old_spec : NULL; | 824 | struct itimerspec *rtn = old_setting ? &old_spec : NULL; |
825 | struct k_clock *kc; | ||
816 | 826 | ||
817 | if (!new_setting) | 827 | if (!new_setting) |
818 | return -EINVAL; | 828 | return -EINVAL; |
@@ -828,8 +838,11 @@ retry: | |||
828 | if (!timr) | 838 | if (!timr) |
829 | return -EINVAL; | 839 | return -EINVAL; |
830 | 840 | ||
831 | error = CLOCK_DISPATCH(timr->it_clock, timer_set, | 841 | kc = clockid_to_kclock(timr->it_clock); |
832 | (timr, flags, &new_spec, rtn)); | 842 | if (WARN_ON_ONCE(!kc || !kc->timer_set)) |
843 | error = -EINVAL; | ||
844 | else | ||
845 | error = kc->timer_set(timr, flags, &new_spec, rtn); | ||
833 | 846 | ||
834 | unlock_timer(timr, flag); | 847 | unlock_timer(timr, flag); |
835 | if (error == TIMER_RETRY) { | 848 | if (error == TIMER_RETRY) { |
@@ -844,7 +857,7 @@ retry: | |||
844 | return error; | 857 | return error; |
845 | } | 858 | } |
846 | 859 | ||
847 | static inline int common_timer_del(struct k_itimer *timer) | 860 | static int common_timer_del(struct k_itimer *timer) |
848 | { | 861 | { |
849 | timer->it.real.interval.tv64 = 0; | 862 | timer->it.real.interval.tv64 = 0; |
850 | 863 | ||
@@ -855,7 +868,11 @@ static inline int common_timer_del(struct k_itimer *timer) | |||
855 | 868 | ||
856 | static inline int timer_delete_hook(struct k_itimer *timer) | 869 | static inline int timer_delete_hook(struct k_itimer *timer) |
857 | { | 870 | { |
858 | return CLOCK_DISPATCH(timer->it_clock, timer_del, (timer)); | 871 | struct k_clock *kc = clockid_to_kclock(timer->it_clock); |
872 | |||
873 | if (WARN_ON_ONCE(!kc || !kc->timer_del)) | ||
874 | return -EINVAL; | ||
875 | return kc->timer_del(timer); | ||
859 | } | 876 | } |
860 | 877 | ||
861 | /* Delete a POSIX.1b interval timer. */ | 878 | /* Delete a POSIX.1b interval timer. */ |
@@ -927,69 +944,76 @@ void exit_itimers(struct signal_struct *sig) | |||
927 | } | 944 | } |
928 | } | 945 | } |
929 | 946 | ||
930 | /* Not available / possible... functions */ | ||
931 | int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp) | ||
932 | { | ||
933 | return -EINVAL; | ||
934 | } | ||
935 | EXPORT_SYMBOL_GPL(do_posix_clock_nosettime); | ||
936 | |||
937 | int do_posix_clock_nonanosleep(const clockid_t clock, int flags, | ||
938 | struct timespec *t, struct timespec __user *r) | ||
939 | { | ||
940 | #ifndef ENOTSUP | ||
941 | return -EOPNOTSUPP; /* aka ENOTSUP in userland for POSIX */ | ||
942 | #else /* parisc does define it separately. */ | ||
943 | return -ENOTSUP; | ||
944 | #endif | ||
945 | } | ||
946 | EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep); | ||
947 | |||
948 | SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, | 947 | SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, |
949 | const struct timespec __user *, tp) | 948 | const struct timespec __user *, tp) |
950 | { | 949 | { |
950 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
951 | struct timespec new_tp; | 951 | struct timespec new_tp; |
952 | 952 | ||
953 | if (invalid_clockid(which_clock)) | 953 | if (!kc || !kc->clock_set) |
954 | return -EINVAL; | 954 | return -EINVAL; |
955 | |||
955 | if (copy_from_user(&new_tp, tp, sizeof (*tp))) | 956 | if (copy_from_user(&new_tp, tp, sizeof (*tp))) |
956 | return -EFAULT; | 957 | return -EFAULT; |
957 | 958 | ||
958 | return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp)); | 959 | return kc->clock_set(which_clock, &new_tp); |
959 | } | 960 | } |
960 | 961 | ||
961 | SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | 962 | SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, |
962 | struct timespec __user *,tp) | 963 | struct timespec __user *,tp) |
963 | { | 964 | { |
965 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
964 | struct timespec kernel_tp; | 966 | struct timespec kernel_tp; |
965 | int error; | 967 | int error; |
966 | 968 | ||
967 | if (invalid_clockid(which_clock)) | 969 | if (!kc) |
968 | return -EINVAL; | 970 | return -EINVAL; |
969 | error = CLOCK_DISPATCH(which_clock, clock_get, | 971 | |
970 | (which_clock, &kernel_tp)); | 972 | error = kc->clock_get(which_clock, &kernel_tp); |
973 | |||
971 | if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) | 974 | if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) |
972 | error = -EFAULT; | 975 | error = -EFAULT; |
973 | 976 | ||
974 | return error; | 977 | return error; |
978 | } | ||
979 | |||
980 | SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock, | ||
981 | struct timex __user *, utx) | ||
982 | { | ||
983 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
984 | struct timex ktx; | ||
985 | int err; | ||
986 | |||
987 | if (!kc) | ||
988 | return -EINVAL; | ||
989 | if (!kc->clock_adj) | ||
990 | return -EOPNOTSUPP; | ||
991 | |||
992 | if (copy_from_user(&ktx, utx, sizeof(ktx))) | ||
993 | return -EFAULT; | ||
994 | |||
995 | err = kc->clock_adj(which_clock, &ktx); | ||
996 | |||
997 | if (!err && copy_to_user(utx, &ktx, sizeof(ktx))) | ||
998 | return -EFAULT; | ||
975 | 999 | ||
1000 | return err; | ||
976 | } | 1001 | } |
977 | 1002 | ||
978 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, | 1003 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, |
979 | struct timespec __user *, tp) | 1004 | struct timespec __user *, tp) |
980 | { | 1005 | { |
1006 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
981 | struct timespec rtn_tp; | 1007 | struct timespec rtn_tp; |
982 | int error; | 1008 | int error; |
983 | 1009 | ||
984 | if (invalid_clockid(which_clock)) | 1010 | if (!kc) |
985 | return -EINVAL; | 1011 | return -EINVAL; |
986 | 1012 | ||
987 | error = CLOCK_DISPATCH(which_clock, clock_getres, | 1013 | error = kc->clock_getres(which_clock, &rtn_tp); |
988 | (which_clock, &rtn_tp)); | ||
989 | 1014 | ||
990 | if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) { | 1015 | if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) |
991 | error = -EFAULT; | 1016 | error = -EFAULT; |
992 | } | ||
993 | 1017 | ||
994 | return error; | 1018 | return error; |
995 | } | 1019 | } |
@@ -1009,10 +1033,13 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
1009 | const struct timespec __user *, rqtp, | 1033 | const struct timespec __user *, rqtp, |
1010 | struct timespec __user *, rmtp) | 1034 | struct timespec __user *, rmtp) |
1011 | { | 1035 | { |
1036 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
1012 | struct timespec t; | 1037 | struct timespec t; |
1013 | 1038 | ||
1014 | if (invalid_clockid(which_clock)) | 1039 | if (!kc) |
1015 | return -EINVAL; | 1040 | return -EINVAL; |
1041 | if (!kc->nsleep) | ||
1042 | return -ENANOSLEEP_NOTSUP; | ||
1016 | 1043 | ||
1017 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) | 1044 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) |
1018 | return -EFAULT; | 1045 | return -EFAULT; |
@@ -1020,27 +1047,20 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
1020 | if (!timespec_valid(&t)) | 1047 | if (!timespec_valid(&t)) |
1021 | return -EINVAL; | 1048 | return -EINVAL; |
1022 | 1049 | ||
1023 | return CLOCK_DISPATCH(which_clock, nsleep, | 1050 | return kc->nsleep(which_clock, flags, &t, rmtp); |
1024 | (which_clock, flags, &t, rmtp)); | ||
1025 | } | ||
1026 | |||
1027 | /* | ||
1028 | * nanosleep_restart for monotonic and realtime clocks | ||
1029 | */ | ||
1030 | static int common_nsleep_restart(struct restart_block *restart_block) | ||
1031 | { | ||
1032 | return hrtimer_nanosleep_restart(restart_block); | ||
1033 | } | 1051 | } |
1034 | 1052 | ||
1035 | /* | 1053 | /* |
1036 | * This will restart clock_nanosleep. This is required only by | 1054 | * This will restart clock_nanosleep. This is required only by |
1037 | * compat_clock_nanosleep_restart for now. | 1055 | * compat_clock_nanosleep_restart for now. |
1038 | */ | 1056 | */ |
1039 | long | 1057 | long clock_nanosleep_restart(struct restart_block *restart_block) |
1040 | clock_nanosleep_restart(struct restart_block *restart_block) | ||
1041 | { | 1058 | { |
1042 | clockid_t which_clock = restart_block->arg0; | 1059 | clockid_t which_clock = restart_block->nanosleep.index; |
1060 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
1061 | |||
1062 | if (WARN_ON_ONCE(!kc || !kc->nsleep_restart)) | ||
1063 | return -EINVAL; | ||
1043 | 1064 | ||
1044 | return CLOCK_DISPATCH(which_clock, nsleep_restart, | 1065 | return kc->nsleep_restart(restart_block); |
1045 | (restart_block)); | ||
1046 | } | 1066 | } |
diff --git a/kernel/time.c b/kernel/time.c index 55337a816b2..8e8dc6d705c 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -150,7 +150,7 @@ static inline void warp_clock(void) | |||
150 | * various programs will get confused when the clock gets warped. | 150 | * various programs will get confused when the clock gets warped. |
151 | */ | 151 | */ |
152 | 152 | ||
153 | int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) | 153 | int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz) |
154 | { | 154 | { |
155 | static int firsttime = 1; | 155 | static int firsttime = 1; |
156 | int error = 0; | 156 | int error = 0; |
@@ -674,7 +674,6 @@ u64 nsecs_to_jiffies64(u64 n) | |||
674 | #endif | 674 | #endif |
675 | } | 675 | } |
676 | 676 | ||
677 | |||
678 | /** | 677 | /** |
679 | * nsecs_to_jiffies - Convert nsecs in u64 to jiffies | 678 | * nsecs_to_jiffies - Convert nsecs in u64 to jiffies |
680 | * | 679 | * |
@@ -693,23 +692,6 @@ unsigned long nsecs_to_jiffies(u64 n) | |||
693 | return (unsigned long)nsecs_to_jiffies64(n); | 692 | return (unsigned long)nsecs_to_jiffies64(n); |
694 | } | 693 | } |
695 | 694 | ||
696 | #if (BITS_PER_LONG < 64) | ||
697 | u64 get_jiffies_64(void) | ||
698 | { | ||
699 | unsigned long seq; | ||
700 | u64 ret; | ||
701 | |||
702 | do { | ||
703 | seq = read_seqbegin(&xtime_lock); | ||
704 | ret = jiffies_64; | ||
705 | } while (read_seqretry(&xtime_lock, seq)); | ||
706 | return ret; | ||
707 | } | ||
708 | EXPORT_SYMBOL(get_jiffies_64); | ||
709 | #endif | ||
710 | |||
711 | EXPORT_SYMBOL(jiffies); | ||
712 | |||
713 | /* | 695 | /* |
714 | * Add two timespec values and do a safety check for overflow. | 696 | * Add two timespec values and do a safety check for overflow. |
715 | * It's assumed that both values are valid (>= 0) | 697 | * It's assumed that both values are valid (>= 0) |
diff --git a/kernel/time/Makefile b/kernel/time/Makefile index ee266620b06..b0425991e9a 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o timeconv.o | 1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o |
2 | obj-y += timeconv.o posix-clock.o | ||
2 | 3 | ||
3 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o | 4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o |
4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o | 5 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index d7395fdfb9f..0d74b9ba90c 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/notifier.h> | 18 | #include <linux/notifier.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/sysdev.h> | 20 | #include <linux/sysdev.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include "tick-internal.h" | 22 | #include "tick-internal.h" |
24 | 23 | ||
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index 5404a845690..b2fa506667c 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c | |||
@@ -22,8 +22,11 @@ | |||
22 | ************************************************************************/ | 22 | ************************************************************************/ |
23 | #include <linux/clocksource.h> | 23 | #include <linux/clocksource.h> |
24 | #include <linux/jiffies.h> | 24 | #include <linux/jiffies.h> |
25 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | 27 | ||
28 | #include "tick-internal.h" | ||
29 | |||
27 | /* The Jiffies based clocksource is the lowest common | 30 | /* The Jiffies based clocksource is the lowest common |
28 | * denominator clock source which should function on | 31 | * denominator clock source which should function on |
29 | * all systems. It has the same coarse resolution as | 32 | * all systems. It has the same coarse resolution as |
@@ -64,6 +67,23 @@ struct clocksource clocksource_jiffies = { | |||
64 | .shift = JIFFIES_SHIFT, | 67 | .shift = JIFFIES_SHIFT, |
65 | }; | 68 | }; |
66 | 69 | ||
70 | #if (BITS_PER_LONG < 64) | ||
71 | u64 get_jiffies_64(void) | ||
72 | { | ||
73 | unsigned long seq; | ||
74 | u64 ret; | ||
75 | |||
76 | do { | ||
77 | seq = read_seqbegin(&xtime_lock); | ||
78 | ret = jiffies_64; | ||
79 | } while (read_seqretry(&xtime_lock, seq)); | ||
80 | return ret; | ||
81 | } | ||
82 | EXPORT_SYMBOL(get_jiffies_64); | ||
83 | #endif | ||
84 | |||
85 | EXPORT_SYMBOL(jiffies); | ||
86 | |||
67 | static int __init init_jiffies_clocksource(void) | 87 | static int __init init_jiffies_clocksource(void) |
68 | { | 88 | { |
69 | return clocksource_register(&clocksource_jiffies); | 89 | return clocksource_register(&clocksource_jiffies); |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 5c00242fa92..5f1bb8e2008 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include "tick-internal.h" | ||
20 | |||
19 | /* | 21 | /* |
20 | * NTP timekeeping variables: | 22 | * NTP timekeeping variables: |
21 | */ | 23 | */ |
@@ -646,6 +648,17 @@ int do_adjtimex(struct timex *txc) | |||
646 | hrtimer_cancel(&leap_timer); | 648 | hrtimer_cancel(&leap_timer); |
647 | } | 649 | } |
648 | 650 | ||
651 | if (txc->modes & ADJ_SETOFFSET) { | ||
652 | struct timespec delta; | ||
653 | delta.tv_sec = txc->time.tv_sec; | ||
654 | delta.tv_nsec = txc->time.tv_usec; | ||
655 | if (!(txc->modes & ADJ_NANO)) | ||
656 | delta.tv_nsec *= 1000; | ||
657 | result = timekeeping_inject_offset(&delta); | ||
658 | if (result) | ||
659 | return result; | ||
660 | } | ||
661 | |||
649 | getnstimeofday(&ts); | 662 | getnstimeofday(&ts); |
650 | 663 | ||
651 | write_seqlock_irq(&xtime_lock); | 664 | write_seqlock_irq(&xtime_lock); |
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c new file mode 100644 index 00000000000..25028dd4fa1 --- /dev/null +++ b/kernel/time/posix-clock.c | |||
@@ -0,0 +1,451 @@ | |||
1 | /* | ||
2 | * posix-clock.c - support for dynamic clock devices | ||
3 | * | ||
4 | * Copyright (C) 2010 OMICRON electronics GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/posix-clock.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/syscalls.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | |||
28 | static void delete_clock(struct kref *kref); | ||
29 | |||
30 | /* | ||
31 | * Returns NULL if the posix_clock instance attached to 'fp' is old and stale. | ||
32 | */ | ||
33 | static struct posix_clock *get_posix_clock(struct file *fp) | ||
34 | { | ||
35 | struct posix_clock *clk = fp->private_data; | ||
36 | |||
37 | mutex_lock(&clk->mutex); | ||
38 | |||
39 | if (!clk->zombie) | ||
40 | return clk; | ||
41 | |||
42 | mutex_unlock(&clk->mutex); | ||
43 | |||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | static void put_posix_clock(struct posix_clock *clk) | ||
48 | { | ||
49 | mutex_unlock(&clk->mutex); | ||
50 | } | ||
51 | |||
52 | static ssize_t posix_clock_read(struct file *fp, char __user *buf, | ||
53 | size_t count, loff_t *ppos) | ||
54 | { | ||
55 | struct posix_clock *clk = get_posix_clock(fp); | ||
56 | int err = -EINVAL; | ||
57 | |||
58 | if (!clk) | ||
59 | return -ENODEV; | ||
60 | |||
61 | if (clk->ops.read) | ||
62 | err = clk->ops.read(clk, fp->f_flags, buf, count); | ||
63 | |||
64 | put_posix_clock(clk); | ||
65 | |||
66 | return err; | ||
67 | } | ||
68 | |||
69 | static unsigned int posix_clock_poll(struct file *fp, poll_table *wait) | ||
70 | { | ||
71 | struct posix_clock *clk = get_posix_clock(fp); | ||
72 | int result = 0; | ||
73 | |||
74 | if (!clk) | ||
75 | return -ENODEV; | ||
76 | |||
77 | if (clk->ops.poll) | ||
78 | result = clk->ops.poll(clk, fp, wait); | ||
79 | |||
80 | put_posix_clock(clk); | ||
81 | |||
82 | return result; | ||
83 | } | ||
84 | |||
85 | static int posix_clock_fasync(int fd, struct file *fp, int on) | ||
86 | { | ||
87 | struct posix_clock *clk = get_posix_clock(fp); | ||
88 | int err = 0; | ||
89 | |||
90 | if (!clk) | ||
91 | return -ENODEV; | ||
92 | |||
93 | if (clk->ops.fasync) | ||
94 | err = clk->ops.fasync(clk, fd, fp, on); | ||
95 | |||
96 | put_posix_clock(clk); | ||
97 | |||
98 | return err; | ||
99 | } | ||
100 | |||
101 | static int posix_clock_mmap(struct file *fp, struct vm_area_struct *vma) | ||
102 | { | ||
103 | struct posix_clock *clk = get_posix_clock(fp); | ||
104 | int err = -ENODEV; | ||
105 | |||
106 | if (!clk) | ||
107 | return -ENODEV; | ||
108 | |||
109 | if (clk->ops.mmap) | ||
110 | err = clk->ops.mmap(clk, vma); | ||
111 | |||
112 | put_posix_clock(clk); | ||
113 | |||
114 | return err; | ||
115 | } | ||
116 | |||
117 | static long posix_clock_ioctl(struct file *fp, | ||
118 | unsigned int cmd, unsigned long arg) | ||
119 | { | ||
120 | struct posix_clock *clk = get_posix_clock(fp); | ||
121 | int err = -ENOTTY; | ||
122 | |||
123 | if (!clk) | ||
124 | return -ENODEV; | ||
125 | |||
126 | if (clk->ops.ioctl) | ||
127 | err = clk->ops.ioctl(clk, cmd, arg); | ||
128 | |||
129 | put_posix_clock(clk); | ||
130 | |||
131 | return err; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_COMPAT | ||
135 | static long posix_clock_compat_ioctl(struct file *fp, | ||
136 | unsigned int cmd, unsigned long arg) | ||
137 | { | ||
138 | struct posix_clock *clk = get_posix_clock(fp); | ||
139 | int err = -ENOTTY; | ||
140 | |||
141 | if (!clk) | ||
142 | return -ENODEV; | ||
143 | |||
144 | if (clk->ops.ioctl) | ||
145 | err = clk->ops.ioctl(clk, cmd, arg); | ||
146 | |||
147 | put_posix_clock(clk); | ||
148 | |||
149 | return err; | ||
150 | } | ||
151 | #endif | ||
152 | |||
153 | static int posix_clock_open(struct inode *inode, struct file *fp) | ||
154 | { | ||
155 | int err; | ||
156 | struct posix_clock *clk = | ||
157 | container_of(inode->i_cdev, struct posix_clock, cdev); | ||
158 | |||
159 | mutex_lock(&clk->mutex); | ||
160 | |||
161 | if (clk->zombie) { | ||
162 | err = -ENODEV; | ||
163 | goto out; | ||
164 | } | ||
165 | if (clk->ops.open) | ||
166 | err = clk->ops.open(clk, fp->f_mode); | ||
167 | else | ||
168 | err = 0; | ||
169 | |||
170 | if (!err) { | ||
171 | kref_get(&clk->kref); | ||
172 | fp->private_data = clk; | ||
173 | } | ||
174 | out: | ||
175 | mutex_unlock(&clk->mutex); | ||
176 | return err; | ||
177 | } | ||
178 | |||
179 | static int posix_clock_release(struct inode *inode, struct file *fp) | ||
180 | { | ||
181 | struct posix_clock *clk = fp->private_data; | ||
182 | int err = 0; | ||
183 | |||
184 | if (clk->ops.release) | ||
185 | err = clk->ops.release(clk); | ||
186 | |||
187 | kref_put(&clk->kref, delete_clock); | ||
188 | |||
189 | fp->private_data = NULL; | ||
190 | |||
191 | return err; | ||
192 | } | ||
193 | |||
194 | static const struct file_operations posix_clock_file_operations = { | ||
195 | .owner = THIS_MODULE, | ||
196 | .llseek = no_llseek, | ||
197 | .read = posix_clock_read, | ||
198 | .poll = posix_clock_poll, | ||
199 | .unlocked_ioctl = posix_clock_ioctl, | ||
200 | .open = posix_clock_open, | ||
201 | .release = posix_clock_release, | ||
202 | .fasync = posix_clock_fasync, | ||
203 | .mmap = posix_clock_mmap, | ||
204 | #ifdef CONFIG_COMPAT | ||
205 | .compat_ioctl = posix_clock_compat_ioctl, | ||
206 | #endif | ||
207 | }; | ||
208 | |||
209 | int posix_clock_register(struct posix_clock *clk, dev_t devid) | ||
210 | { | ||
211 | int err; | ||
212 | |||
213 | kref_init(&clk->kref); | ||
214 | mutex_init(&clk->mutex); | ||
215 | |||
216 | cdev_init(&clk->cdev, &posix_clock_file_operations); | ||
217 | clk->cdev.owner = clk->ops.owner; | ||
218 | err = cdev_add(&clk->cdev, devid, 1); | ||
219 | if (err) | ||
220 | goto no_cdev; | ||
221 | |||
222 | return err; | ||
223 | no_cdev: | ||
224 | mutex_destroy(&clk->mutex); | ||
225 | return err; | ||
226 | } | ||
227 | EXPORT_SYMBOL_GPL(posix_clock_register); | ||
228 | |||
229 | static void delete_clock(struct kref *kref) | ||
230 | { | ||
231 | struct posix_clock *clk = container_of(kref, struct posix_clock, kref); | ||
232 | mutex_destroy(&clk->mutex); | ||
233 | if (clk->release) | ||
234 | clk->release(clk); | ||
235 | } | ||
236 | |||
237 | void posix_clock_unregister(struct posix_clock *clk) | ||
238 | { | ||
239 | cdev_del(&clk->cdev); | ||
240 | |||
241 | mutex_lock(&clk->mutex); | ||
242 | clk->zombie = true; | ||
243 | mutex_unlock(&clk->mutex); | ||
244 | |||
245 | kref_put(&clk->kref, delete_clock); | ||
246 | } | ||
247 | EXPORT_SYMBOL_GPL(posix_clock_unregister); | ||
248 | |||
249 | struct posix_clock_desc { | ||
250 | struct file *fp; | ||
251 | struct posix_clock *clk; | ||
252 | }; | ||
253 | |||
254 | static int get_clock_desc(const clockid_t id, struct posix_clock_desc *cd) | ||
255 | { | ||
256 | struct file *fp = fget(CLOCKID_TO_FD(id)); | ||
257 | int err = -EINVAL; | ||
258 | |||
259 | if (!fp) | ||
260 | return err; | ||
261 | |||
262 | if (fp->f_op->open != posix_clock_open || !fp->private_data) | ||
263 | goto out; | ||
264 | |||
265 | cd->fp = fp; | ||
266 | cd->clk = get_posix_clock(fp); | ||
267 | |||
268 | err = cd->clk ? 0 : -ENODEV; | ||
269 | out: | ||
270 | if (err) | ||
271 | fput(fp); | ||
272 | return err; | ||
273 | } | ||
274 | |||
275 | static void put_clock_desc(struct posix_clock_desc *cd) | ||
276 | { | ||
277 | put_posix_clock(cd->clk); | ||
278 | fput(cd->fp); | ||
279 | } | ||
280 | |||
281 | static int pc_clock_adjtime(clockid_t id, struct timex *tx) | ||
282 | { | ||
283 | struct posix_clock_desc cd; | ||
284 | int err; | ||
285 | |||
286 | err = get_clock_desc(id, &cd); | ||
287 | if (err) | ||
288 | return err; | ||
289 | |||
290 | if ((cd.fp->f_mode & FMODE_WRITE) == 0) { | ||
291 | err = -EACCES; | ||
292 | goto out; | ||
293 | } | ||
294 | |||
295 | if (cd.clk->ops.clock_adjtime) | ||
296 | err = cd.clk->ops.clock_adjtime(cd.clk, tx); | ||
297 | else | ||
298 | err = -EOPNOTSUPP; | ||
299 | out: | ||
300 | put_clock_desc(&cd); | ||
301 | |||
302 | return err; | ||
303 | } | ||
304 | |||
305 | static int pc_clock_gettime(clockid_t id, struct timespec *ts) | ||
306 | { | ||
307 | struct posix_clock_desc cd; | ||
308 | int err; | ||
309 | |||
310 | err = get_clock_desc(id, &cd); | ||
311 | if (err) | ||
312 | return err; | ||
313 | |||
314 | if (cd.clk->ops.clock_gettime) | ||
315 | err = cd.clk->ops.clock_gettime(cd.clk, ts); | ||
316 | else | ||
317 | err = -EOPNOTSUPP; | ||
318 | |||
319 | put_clock_desc(&cd); | ||
320 | |||
321 | return err; | ||
322 | } | ||
323 | |||
324 | static int pc_clock_getres(clockid_t id, struct timespec *ts) | ||
325 | { | ||
326 | struct posix_clock_desc cd; | ||
327 | int err; | ||
328 | |||
329 | err = get_clock_desc(id, &cd); | ||
330 | if (err) | ||
331 | return err; | ||
332 | |||
333 | if (cd.clk->ops.clock_getres) | ||
334 | err = cd.clk->ops.clock_getres(cd.clk, ts); | ||
335 | else | ||
336 | err = -EOPNOTSUPP; | ||
337 | |||
338 | put_clock_desc(&cd); | ||
339 | |||
340 | return err; | ||
341 | } | ||
342 | |||
343 | static int pc_clock_settime(clockid_t id, const struct timespec *ts) | ||
344 | { | ||
345 | struct posix_clock_desc cd; | ||
346 | int err; | ||
347 | |||
348 | err = get_clock_desc(id, &cd); | ||
349 | if (err) | ||
350 | return err; | ||
351 | |||
352 | if ((cd.fp->f_mode & FMODE_WRITE) == 0) { | ||
353 | err = -EACCES; | ||
354 | goto out; | ||
355 | } | ||
356 | |||
357 | if (cd.clk->ops.clock_settime) | ||
358 | err = cd.clk->ops.clock_settime(cd.clk, ts); | ||
359 | else | ||
360 | err = -EOPNOTSUPP; | ||
361 | out: | ||
362 | put_clock_desc(&cd); | ||
363 | |||
364 | return err; | ||
365 | } | ||
366 | |||
367 | static int pc_timer_create(struct k_itimer *kit) | ||
368 | { | ||
369 | clockid_t id = kit->it_clock; | ||
370 | struct posix_clock_desc cd; | ||
371 | int err; | ||
372 | |||
373 | err = get_clock_desc(id, &cd); | ||
374 | if (err) | ||
375 | return err; | ||
376 | |||
377 | if (cd.clk->ops.timer_create) | ||
378 | err = cd.clk->ops.timer_create(cd.clk, kit); | ||
379 | else | ||
380 | err = -EOPNOTSUPP; | ||
381 | |||
382 | put_clock_desc(&cd); | ||
383 | |||
384 | return err; | ||
385 | } | ||
386 | |||
387 | static int pc_timer_delete(struct k_itimer *kit) | ||
388 | { | ||
389 | clockid_t id = kit->it_clock; | ||
390 | struct posix_clock_desc cd; | ||
391 | int err; | ||
392 | |||
393 | err = get_clock_desc(id, &cd); | ||
394 | if (err) | ||
395 | return err; | ||
396 | |||
397 | if (cd.clk->ops.timer_delete) | ||
398 | err = cd.clk->ops.timer_delete(cd.clk, kit); | ||
399 | else | ||
400 | err = -EOPNOTSUPP; | ||
401 | |||
402 | put_clock_desc(&cd); | ||
403 | |||
404 | return err; | ||
405 | } | ||
406 | |||
407 | static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec *ts) | ||
408 | { | ||
409 | clockid_t id = kit->it_clock; | ||
410 | struct posix_clock_desc cd; | ||
411 | |||
412 | if (get_clock_desc(id, &cd)) | ||
413 | return; | ||
414 | |||
415 | if (cd.clk->ops.timer_gettime) | ||
416 | cd.clk->ops.timer_gettime(cd.clk, kit, ts); | ||
417 | |||
418 | put_clock_desc(&cd); | ||
419 | } | ||
420 | |||
421 | static int pc_timer_settime(struct k_itimer *kit, int flags, | ||
422 | struct itimerspec *ts, struct itimerspec *old) | ||
423 | { | ||
424 | clockid_t id = kit->it_clock; | ||
425 | struct posix_clock_desc cd; | ||
426 | int err; | ||
427 | |||
428 | err = get_clock_desc(id, &cd); | ||
429 | if (err) | ||
430 | return err; | ||
431 | |||
432 | if (cd.clk->ops.timer_settime) | ||
433 | err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old); | ||
434 | else | ||
435 | err = -EOPNOTSUPP; | ||
436 | |||
437 | put_clock_desc(&cd); | ||
438 | |||
439 | return err; | ||
440 | } | ||
441 | |||
442 | struct k_clock clock_posix_dynamic = { | ||
443 | .clock_getres = pc_clock_getres, | ||
444 | .clock_set = pc_clock_settime, | ||
445 | .clock_get = pc_clock_gettime, | ||
446 | .clock_adj = pc_clock_adjtime, | ||
447 | .timer_create = pc_timer_create, | ||
448 | .timer_set = pc_timer_settime, | ||
449 | .timer_del = pc_timer_delete, | ||
450 | .timer_get = pc_timer_gettime, | ||
451 | }; | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index a3b5aff6260..da800ffa810 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
19 | #include <linux/profile.h> | 19 | #include <linux/profile.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include "tick-internal.h" | 22 | #include "tick-internal.h" |
24 | 23 | ||
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index ed228ef6f6b..119528de823 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
19 | #include <linux/profile.h> | 19 | #include <linux/profile.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include <asm/irq_regs.h> | 22 | #include <asm/irq_regs.h> |
24 | 23 | ||
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index f65d3a723a6..1009b06d6f8 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -1,6 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * tick internal variable and functions used by low/high res code | 2 | * tick internal variable and functions used by low/high res code |
3 | */ | 3 | */ |
4 | #include <linux/hrtimer.h> | ||
5 | #include <linux/tick.h> | ||
6 | |||
7 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD | ||
4 | 8 | ||
5 | #define TICK_DO_TIMER_NONE -1 | 9 | #define TICK_DO_TIMER_NONE -1 |
6 | #define TICK_DO_TIMER_BOOT -2 | 10 | #define TICK_DO_TIMER_BOOT -2 |
@@ -135,3 +139,8 @@ static inline int tick_device_is_functional(struct clock_event_device *dev) | |||
135 | { | 139 | { |
136 | return !(dev->features & CLOCK_EVT_FEAT_DUMMY); | 140 | return !(dev->features & CLOCK_EVT_FEAT_DUMMY); |
137 | } | 141 | } |
142 | |||
143 | #endif | ||
144 | |||
145 | extern void do_timer(unsigned long ticks); | ||
146 | extern seqlock_t xtime_lock; | ||
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 5cbc101f908..2d04411a5f0 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
19 | #include <linux/profile.h> | 19 | #include <linux/profile.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include "tick-internal.h" | 22 | #include "tick-internal.h" |
24 | 23 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index c55ea243347..d5097c44b40 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/percpu.h> | 19 | #include <linux/percpu.h> |
20 | #include <linux/profile.h> | 20 | #include <linux/profile.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/tick.h> | ||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | 23 | ||
25 | #include <asm/irq_regs.h> | 24 | #include <asm/irq_regs.h> |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d27c7562902..3bd7e3d5c63 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -353,7 +353,7 @@ EXPORT_SYMBOL(do_gettimeofday); | |||
353 | * | 353 | * |
354 | * Sets the time of day to the new time and update NTP and notify hrtimers | 354 | * Sets the time of day to the new time and update NTP and notify hrtimers |
355 | */ | 355 | */ |
356 | int do_settimeofday(struct timespec *tv) | 356 | int do_settimeofday(const struct timespec *tv) |
357 | { | 357 | { |
358 | struct timespec ts_delta; | 358 | struct timespec ts_delta; |
359 | unsigned long flags; | 359 | unsigned long flags; |
@@ -387,6 +387,42 @@ int do_settimeofday(struct timespec *tv) | |||
387 | 387 | ||
388 | EXPORT_SYMBOL(do_settimeofday); | 388 | EXPORT_SYMBOL(do_settimeofday); |
389 | 389 | ||
390 | |||
391 | /** | ||
392 | * timekeeping_inject_offset - Adds or subtracts from the current time. | ||
393 | * @tv: pointer to the timespec variable containing the offset | ||
394 | * | ||
395 | * Adds or subtracts an offset value from the current time. | ||
396 | */ | ||
397 | int timekeeping_inject_offset(struct timespec *ts) | ||
398 | { | ||
399 | unsigned long flags; | ||
400 | |||
401 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | ||
402 | return -EINVAL; | ||
403 | |||
404 | write_seqlock_irqsave(&xtime_lock, flags); | ||
405 | |||
406 | timekeeping_forward_now(); | ||
407 | |||
408 | xtime = timespec_add(xtime, *ts); | ||
409 | wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts); | ||
410 | |||
411 | timekeeper.ntp_error = 0; | ||
412 | ntp_clear(); | ||
413 | |||
414 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | ||
415 | timekeeper.mult); | ||
416 | |||
417 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
418 | |||
419 | /* signal hrtimers about time change */ | ||
420 | clock_was_set(); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | EXPORT_SYMBOL(timekeeping_inject_offset); | ||
425 | |||
390 | /** | 426 | /** |
391 | * change_clocksource - Swaps clocksources if a new one is available | 427 | * change_clocksource - Swaps clocksources if a new one is available |
392 | * | 428 | * |
@@ -779,7 +815,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
779 | * | 815 | * |
780 | * Called from the timer interrupt, must hold a write on xtime_lock. | 816 | * Called from the timer interrupt, must hold a write on xtime_lock. |
781 | */ | 817 | */ |
782 | void update_wall_time(void) | 818 | static void update_wall_time(void) |
783 | { | 819 | { |
784 | struct clocksource *clock; | 820 | struct clocksource *clock; |
785 | cycle_t offset; | 821 | cycle_t offset; |
@@ -871,7 +907,7 @@ void update_wall_time(void) | |||
871 | * getboottime - Return the real time of system boot. | 907 | * getboottime - Return the real time of system boot. |
872 | * @ts: pointer to the timespec to be set | 908 | * @ts: pointer to the timespec to be set |
873 | * | 909 | * |
874 | * Returns the time of day in a timespec. | 910 | * Returns the wall-time of boot in a timespec. |
875 | * | 911 | * |
876 | * This is based on the wall_to_monotonic offset and the total suspend | 912 | * This is based on the wall_to_monotonic offset and the total suspend |
877 | * time. Calls to settimeofday will affect the value returned (which | 913 | * time. Calls to settimeofday will affect the value returned (which |
@@ -889,6 +925,55 @@ void getboottime(struct timespec *ts) | |||
889 | } | 925 | } |
890 | EXPORT_SYMBOL_GPL(getboottime); | 926 | EXPORT_SYMBOL_GPL(getboottime); |
891 | 927 | ||
928 | |||
929 | /** | ||
930 | * get_monotonic_boottime - Returns monotonic time since boot | ||
931 | * @ts: pointer to the timespec to be set | ||
932 | * | ||
933 | * Returns the monotonic time since boot in a timespec. | ||
934 | * | ||
935 | * This is similar to CLOCK_MONTONIC/ktime_get_ts, but also | ||
936 | * includes the time spent in suspend. | ||
937 | */ | ||
938 | void get_monotonic_boottime(struct timespec *ts) | ||
939 | { | ||
940 | struct timespec tomono, sleep; | ||
941 | unsigned int seq; | ||
942 | s64 nsecs; | ||
943 | |||
944 | WARN_ON(timekeeping_suspended); | ||
945 | |||
946 | do { | ||
947 | seq = read_seqbegin(&xtime_lock); | ||
948 | *ts = xtime; | ||
949 | tomono = wall_to_monotonic; | ||
950 | sleep = total_sleep_time; | ||
951 | nsecs = timekeeping_get_ns(); | ||
952 | |||
953 | } while (read_seqretry(&xtime_lock, seq)); | ||
954 | |||
955 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec, | ||
956 | ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec + nsecs); | ||
957 | } | ||
958 | EXPORT_SYMBOL_GPL(get_monotonic_boottime); | ||
959 | |||
960 | /** | ||
961 | * ktime_get_boottime - Returns monotonic time since boot in a ktime | ||
962 | * | ||
963 | * Returns the monotonic time since boot in a ktime | ||
964 | * | ||
965 | * This is similar to CLOCK_MONTONIC/ktime_get, but also | ||
966 | * includes the time spent in suspend. | ||
967 | */ | ||
968 | ktime_t ktime_get_boottime(void) | ||
969 | { | ||
970 | struct timespec ts; | ||
971 | |||
972 | get_monotonic_boottime(&ts); | ||
973 | return timespec_to_ktime(ts); | ||
974 | } | ||
975 | EXPORT_SYMBOL_GPL(ktime_get_boottime); | ||
976 | |||
892 | /** | 977 | /** |
893 | * monotonic_to_bootbased - Convert the monotonic time to boot based. | 978 | * monotonic_to_bootbased - Convert the monotonic time to boot based. |
894 | * @ts: pointer to the timespec to be converted | 979 | * @ts: pointer to the timespec to be converted |
@@ -910,11 +995,6 @@ struct timespec __current_kernel_time(void) | |||
910 | return xtime; | 995 | return xtime; |
911 | } | 996 | } |
912 | 997 | ||
913 | struct timespec __get_wall_to_monotonic(void) | ||
914 | { | ||
915 | return wall_to_monotonic; | ||
916 | } | ||
917 | |||
918 | struct timespec current_kernel_time(void) | 998 | struct timespec current_kernel_time(void) |
919 | { | 999 | { |
920 | struct timespec now; | 1000 | struct timespec now; |
@@ -946,3 +1026,48 @@ struct timespec get_monotonic_coarse(void) | |||
946 | now.tv_nsec + mono.tv_nsec); | 1026 | now.tv_nsec + mono.tv_nsec); |
947 | return now; | 1027 | return now; |
948 | } | 1028 | } |
1029 | |||
1030 | /* | ||
1031 | * The 64-bit jiffies value is not atomic - you MUST NOT read it | ||
1032 | * without sampling the sequence number in xtime_lock. | ||
1033 | * jiffies is defined in the linker script... | ||
1034 | */ | ||
1035 | void do_timer(unsigned long ticks) | ||
1036 | { | ||
1037 | jiffies_64 += ticks; | ||
1038 | update_wall_time(); | ||
1039 | calc_global_load(ticks); | ||
1040 | } | ||
1041 | |||
1042 | /** | ||
1043 | * get_xtime_and_monotonic_and_sleep_offset() - get xtime, wall_to_monotonic, | ||
1044 | * and sleep offsets. | ||
1045 | * @xtim: pointer to timespec to be set with xtime | ||
1046 | * @wtom: pointer to timespec to be set with wall_to_monotonic | ||
1047 | * @sleep: pointer to timespec to be set with time in suspend | ||
1048 | */ | ||
1049 | void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | ||
1050 | struct timespec *wtom, struct timespec *sleep) | ||
1051 | { | ||
1052 | unsigned long seq; | ||
1053 | |||
1054 | do { | ||
1055 | seq = read_seqbegin(&xtime_lock); | ||
1056 | *xtim = xtime; | ||
1057 | *wtom = wall_to_monotonic; | ||
1058 | *sleep = total_sleep_time; | ||
1059 | } while (read_seqretry(&xtime_lock, seq)); | ||
1060 | } | ||
1061 | |||
1062 | /** | ||
1063 | * xtime_update() - advances the timekeeping infrastructure | ||
1064 | * @ticks: number of ticks, that have elapsed since the last call. | ||
1065 | * | ||
1066 | * Must be called with interrupts disabled. | ||
1067 | */ | ||
1068 | void xtime_update(unsigned long ticks) | ||
1069 | { | ||
1070 | write_seqlock(&xtime_lock); | ||
1071 | do_timer(ticks); | ||
1072 | write_sequnlock(&xtime_lock); | ||
1073 | } | ||
diff --git a/kernel/timer.c b/kernel/timer.c index 3503c17ac1d..fd6198692b5 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1324,19 +1324,6 @@ void run_local_timers(void) | |||
1324 | raise_softirq(TIMER_SOFTIRQ); | 1324 | raise_softirq(TIMER_SOFTIRQ); |
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | /* | ||
1328 | * The 64-bit jiffies value is not atomic - you MUST NOT read it | ||
1329 | * without sampling the sequence number in xtime_lock. | ||
1330 | * jiffies is defined in the linker script... | ||
1331 | */ | ||
1332 | |||
1333 | void do_timer(unsigned long ticks) | ||
1334 | { | ||
1335 | jiffies_64 += ticks; | ||
1336 | update_wall_time(); | ||
1337 | calc_global_load(ticks); | ||
1338 | } | ||
1339 | |||
1340 | #ifdef __ARCH_WANT_SYS_ALARM | 1327 | #ifdef __ARCH_WANT_SYS_ALARM |
1341 | 1328 | ||
1342 | /* | 1329 | /* |