diff options
56 files changed, 1276 insertions, 508 deletions
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index c1f3e7cb82a4..a58e84f1a63b 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -159,7 +159,7 @@ void read_persistent_clock(struct timespec *ts) | |||
159 | 159 | ||
160 | /* | 160 | /* |
161 | * timer_interrupt() needs to keep up the real-time clock, | 161 | * timer_interrupt() needs to keep up the real-time clock, |
162 | * as well as call the "do_timer()" routine every clocktick | 162 | * as well as call the "xtime_update()" routine every clocktick |
163 | */ | 163 | */ |
164 | irqreturn_t timer_interrupt(int irq, void *dev) | 164 | irqreturn_t timer_interrupt(int irq, void *dev) |
165 | { | 165 | { |
@@ -172,8 +172,6 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
172 | profile_tick(CPU_PROFILING); | 172 | profile_tick(CPU_PROFILING); |
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | write_seqlock(&xtime_lock); | ||
176 | |||
177 | /* | 175 | /* |
178 | * Calculate how many ticks have passed since the last update, | 176 | * Calculate how many ticks have passed since the last update, |
179 | * including any previous partial leftover. Save any resulting | 177 | * including any previous partial leftover. Save any resulting |
@@ -187,9 +185,7 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
187 | nticks = delta >> FIX_SHIFT; | 185 | nticks = delta >> FIX_SHIFT; |
188 | 186 | ||
189 | if (nticks) | 187 | if (nticks) |
190 | do_timer(nticks); | 188 | xtime_update(nticks); |
191 | |||
192 | write_sequnlock(&xtime_lock); | ||
193 | 189 | ||
194 | if (test_irq_work_pending()) { | 190 | if (test_irq_work_pending()) { |
195 | clear_irq_work_pending(); | 191 | clear_irq_work_pending(); |
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 3d76bf233734..1ff46cabc7ef 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -107,9 +107,7 @@ void timer_tick(void) | |||
107 | { | 107 | { |
108 | profile_tick(CPU_PROFILING); | 108 | profile_tick(CPU_PROFILING); |
109 | do_leds(); | 109 | do_leds(); |
110 | write_seqlock(&xtime_lock); | 110 | xtime_update(1); |
111 | do_timer(1); | ||
112 | write_sequnlock(&xtime_lock); | ||
113 | #ifndef CONFIG_SMP | 111 | #ifndef CONFIG_SMP |
114 | update_process_times(user_mode(get_irq_regs())); | 112 | update_process_times(user_mode(get_irq_regs())); |
115 | #endif | 113 | #endif |
diff --git a/arch/arm/mach-clps711x/include/mach/time.h b/arch/arm/mach-clps711x/include/mach/time.h index 8fe283ccd1f3..61fef9129c6a 100644 --- a/arch/arm/mach-clps711x/include/mach/time.h +++ b/arch/arm/mach-clps711x/include/mach/time.h | |||
@@ -30,7 +30,7 @@ p720t_timer_interrupt(int irq, void *dev_id) | |||
30 | { | 30 | { |
31 | struct pt_regs *regs = get_irq_regs(); | 31 | struct pt_regs *regs = get_irq_regs(); |
32 | do_leds(); | 32 | do_leds(); |
33 | do_timer(1); | 33 | xtime_update(1); |
34 | #ifndef CONFIG_SMP | 34 | #ifndef CONFIG_SMP |
35 | update_process_times(user_mode(regs)); | 35 | update_process_times(user_mode(regs)); |
36 | #endif | 36 | #endif |
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index c9113619029f..8d73724c0092 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c | |||
@@ -114,16 +114,14 @@ u32 arch_gettimeoffset(void) | |||
114 | 114 | ||
115 | /* | 115 | /* |
116 | * timer_interrupt() needs to keep up the real-time clock, | 116 | * timer_interrupt() needs to keep up the real-time clock, |
117 | * as well as call the "do_timer()" routine every clocktick | 117 | * as well as call the "xtime_update()" routine every clocktick |
118 | */ | 118 | */ |
119 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 | 119 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 |
120 | __attribute__((l1_text)) | 120 | __attribute__((l1_text)) |
121 | #endif | 121 | #endif |
122 | irqreturn_t timer_interrupt(int irq, void *dummy) | 122 | irqreturn_t timer_interrupt(int irq, void *dummy) |
123 | { | 123 | { |
124 | write_seqlock(&xtime_lock); | 124 | xtime_update(1); |
125 | do_timer(1); | ||
126 | write_sequnlock(&xtime_lock); | ||
127 | 125 | ||
128 | #ifdef CONFIG_IPIPE | 126 | #ifdef CONFIG_IPIPE |
129 | update_root_process_times(get_irq_regs()); | 127 | update_root_process_times(get_irq_regs()); |
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 00eb36f8debf..20c85b5dc7d0 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c | |||
@@ -140,7 +140,7 @@ stop_watchdog(void) | |||
140 | 140 | ||
141 | /* | 141 | /* |
142 | * timer_interrupt() needs to keep up the real-time clock, | 142 | * timer_interrupt() needs to keep up the real-time clock, |
143 | * as well as call the "do_timer()" routine every clocktick | 143 | * as well as call the "xtime_update()" routine every clocktick |
144 | */ | 144 | */ |
145 | 145 | ||
146 | //static unsigned short myjiff; /* used by our debug routine print_timestamp */ | 146 | //static unsigned short myjiff; /* used by our debug routine print_timestamp */ |
@@ -176,7 +176,7 @@ timer_interrupt(int irq, void *dev_id) | |||
176 | 176 | ||
177 | /* call the real timer interrupt handler */ | 177 | /* call the real timer interrupt handler */ |
178 | 178 | ||
179 | do_timer(1); | 179 | xtime_update(1); |
180 | 180 | ||
181 | cris_do_profile(regs); /* Save profiling information */ | 181 | cris_do_profile(regs); /* Save profiling information */ |
182 | return IRQ_HANDLED; | 182 | return IRQ_HANDLED; |
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index a545211e999d..bb978ede8985 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c | |||
@@ -183,7 +183,7 @@ void handle_watchdog_bite(struct pt_regs *regs) | |||
183 | 183 | ||
184 | /* | 184 | /* |
185 | * timer_interrupt() needs to keep up the real-time clock, | 185 | * timer_interrupt() needs to keep up the real-time clock, |
186 | * as well as call the "do_timer()" routine every clocktick. | 186 | * as well as call the "xtime_update()" routine every clocktick. |
187 | */ | 187 | */ |
188 | extern void cris_do_profile(struct pt_regs *regs); | 188 | extern void cris_do_profile(struct pt_regs *regs); |
189 | 189 | ||
@@ -216,9 +216,7 @@ static inline irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
216 | return IRQ_HANDLED; | 216 | return IRQ_HANDLED; |
217 | 217 | ||
218 | /* Call the real timer interrupt handler */ | 218 | /* Call the real timer interrupt handler */ |
219 | write_seqlock(&xtime_lock); | 219 | xtime_update(1); |
220 | do_timer(1); | ||
221 | write_sequnlock(&xtime_lock); | ||
222 | return IRQ_HANDLED; | 220 | return IRQ_HANDLED; |
223 | } | 221 | } |
224 | 222 | ||
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index 0ddbbae83cb2..b457de496b70 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c | |||
@@ -50,21 +50,13 @@ static struct irqaction timer_irq = { | |||
50 | 50 | ||
51 | /* | 51 | /* |
52 | * timer_interrupt() needs to keep up the real-time clock, | 52 | * timer_interrupt() needs to keep up the real-time clock, |
53 | * as well as call the "do_timer()" routine every clocktick | 53 | * as well as call the "xtime_update()" routine every clocktick |
54 | */ | 54 | */ |
55 | static irqreturn_t timer_interrupt(int irq, void *dummy) | 55 | static irqreturn_t timer_interrupt(int irq, void *dummy) |
56 | { | 56 | { |
57 | profile_tick(CPU_PROFILING); | 57 | profile_tick(CPU_PROFILING); |
58 | /* | ||
59 | * Here we are in the timer irq handler. We just have irqs locally | ||
60 | * disabled but we don't know if the timer_bh is running on the other | ||
61 | * CPU. We need to avoid to SMP race with it. NOTE: we don't need | ||
62 | * the irq version of write_lock because as just said we have irq | ||
63 | * locally disabled. -arca | ||
64 | */ | ||
65 | write_seqlock(&xtime_lock); | ||
66 | 58 | ||
67 | do_timer(1); | 59 | xtime_update(1); |
68 | 60 | ||
69 | #ifdef CONFIG_HEARTBEAT | 61 | #ifdef CONFIG_HEARTBEAT |
70 | static unsigned short n; | 62 | static unsigned short n; |
@@ -72,8 +64,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) | |||
72 | __set_LEDS(n); | 64 | __set_LEDS(n); |
73 | #endif /* CONFIG_HEARTBEAT */ | 65 | #endif /* CONFIG_HEARTBEAT */ |
74 | 66 | ||
75 | write_sequnlock(&xtime_lock); | ||
76 | |||
77 | update_process_times(user_mode(get_irq_regs())); | 67 | update_process_times(user_mode(get_irq_regs())); |
78 | 68 | ||
79 | return IRQ_HANDLED; | 69 | return IRQ_HANDLED; |
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c index 165005aff9df..32263a138aa6 100644 --- a/arch/h8300/kernel/time.c +++ b/arch/h8300/kernel/time.c | |||
@@ -35,9 +35,7 @@ void h8300_timer_tick(void) | |||
35 | { | 35 | { |
36 | if (current->pid) | 36 | if (current->pid) |
37 | profile_tick(CPU_PROFILING); | 37 | profile_tick(CPU_PROFILING); |
38 | write_seqlock(&xtime_lock); | 38 | xtime_update(1); |
39 | do_timer(1); | ||
40 | write_sequnlock(&xtime_lock); | ||
41 | update_process_times(user_mode(get_irq_regs())); | 39 | update_process_times(user_mode(get_irq_regs())); |
42 | } | 40 | } |
43 | 41 | ||
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c index 3946c0fa8374..7a1533fad47d 100644 --- a/arch/h8300/kernel/timer/timer8.c +++ b/arch/h8300/kernel/timer/timer8.c | |||
@@ -61,7 +61,7 @@ | |||
61 | 61 | ||
62 | /* | 62 | /* |
63 | * timer_interrupt() needs to keep up the real-time clock, | 63 | * timer_interrupt() needs to keep up the real-time clock, |
64 | * as well as call the "do_timer()" routine every clocktick | 64 | * as well as call the "xtime_update()" routine every clocktick |
65 | */ | 65 | */ |
66 | 66 | ||
67 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | 67 | static irqreturn_t timer_interrupt(int irq, void *dev_id) |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 9702fa92489e..156ad803d5b7 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -190,19 +190,10 @@ timer_interrupt (int irq, void *dev_id) | |||
190 | 190 | ||
191 | new_itm += local_cpu_data->itm_delta; | 191 | new_itm += local_cpu_data->itm_delta; |
192 | 192 | ||
193 | if (smp_processor_id() == time_keeper_id) { | 193 | if (smp_processor_id() == time_keeper_id) |
194 | /* | 194 | xtime_update(1); |
195 | * Here we are in the timer irq handler. We have irqs locally | 195 | |
196 | * disabled, but we don't know if the timer_bh is running on | 196 | local_cpu_data->itm_next = new_itm; |
197 | * another CPU. We need to avoid to SMP race by acquiring the | ||
198 | * xtime_lock. | ||
199 | */ | ||
200 | write_seqlock(&xtime_lock); | ||
201 | do_timer(1); | ||
202 | local_cpu_data->itm_next = new_itm; | ||
203 | write_sequnlock(&xtime_lock); | ||
204 | } else | ||
205 | local_cpu_data->itm_next = new_itm; | ||
206 | 197 | ||
207 | if (time_after(new_itm, ia64_get_itc())) | 198 | if (time_after(new_itm, ia64_get_itc())) |
208 | break; | 199 | break; |
@@ -222,7 +213,7 @@ skip_process_time_accounting: | |||
222 | * comfort, we increase the safety margin by | 213 | * comfort, we increase the safety margin by |
223 | * intentionally dropping the next tick(s). We do NOT | 214 | * intentionally dropping the next tick(s). We do NOT |
224 | * update itm.next because that would force us to call | 215 | * update itm.next because that would force us to call |
225 | * do_timer() which in turn would let our clock run | 216 | * xtime_update() which in turn would let our clock run |
226 | * too fast (with the potentially devastating effect | 217 | * too fast (with the potentially devastating effect |
227 | * of losing monotony of time). | 218 | * of losing monotony of time). |
228 | */ | 219 | */ |
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c index c1c544513e8d..1f8244a78bee 100644 --- a/arch/ia64/xen/time.c +++ b/arch/ia64/xen/time.c | |||
@@ -139,14 +139,11 @@ consider_steal_time(unsigned long new_itm) | |||
139 | run_posix_cpu_timers(p); | 139 | run_posix_cpu_timers(p); |
140 | delta_itm += local_cpu_data->itm_delta * (stolen + blocked); | 140 | delta_itm += local_cpu_data->itm_delta * (stolen + blocked); |
141 | 141 | ||
142 | if (cpu == time_keeper_id) { | 142 | if (cpu == time_keeper_id) |
143 | write_seqlock(&xtime_lock); | 143 | xtime_update(stolen + blocked); |
144 | do_timer(stolen + blocked); | 144 | |
145 | local_cpu_data->itm_next = delta_itm + new_itm; | 145 | local_cpu_data->itm_next = delta_itm + new_itm; |
146 | write_sequnlock(&xtime_lock); | 146 | |
147 | } else { | ||
148 | local_cpu_data->itm_next = delta_itm + new_itm; | ||
149 | } | ||
150 | per_cpu(xen_stolen_time, cpu) += NS_PER_TICK * stolen; | 147 | per_cpu(xen_stolen_time, cpu) += NS_PER_TICK * stolen; |
151 | per_cpu(xen_blocked_time, cpu) += NS_PER_TICK * blocked; | 148 | per_cpu(xen_blocked_time, cpu) += NS_PER_TICK * blocked; |
152 | } | 149 | } |
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index bda86820bffd..84dd04048db9 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c | |||
@@ -107,15 +107,14 @@ u32 arch_gettimeoffset(void) | |||
107 | 107 | ||
108 | /* | 108 | /* |
109 | * timer_interrupt() needs to keep up the real-time clock, | 109 | * timer_interrupt() needs to keep up the real-time clock, |
110 | * as well as call the "do_timer()" routine every clocktick | 110 | * as well as call the "xtime_update()" routine every clocktick |
111 | */ | 111 | */ |
112 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | 112 | static irqreturn_t timer_interrupt(int irq, void *dev_id) |
113 | { | 113 | { |
114 | #ifndef CONFIG_SMP | 114 | #ifndef CONFIG_SMP |
115 | profile_tick(CPU_PROFILING); | 115 | profile_tick(CPU_PROFILING); |
116 | #endif | 116 | #endif |
117 | /* XXX FIXME. Uh, the xtime_lock should be held here, no? */ | 117 | xtime_update(1); |
118 | do_timer(1); | ||
119 | 118 | ||
120 | #ifndef CONFIG_SMP | 119 | #ifndef CONFIG_SMP |
121 | update_process_times(user_mode(get_irq_regs())); | 120 | update_process_times(user_mode(get_irq_regs())); |
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 9fe6fefb5e14..1edd95095cb4 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c | |||
@@ -45,8 +45,8 @@ extern int bvme6000_set_clock_mmss (unsigned long); | |||
45 | extern void bvme6000_reset (void); | 45 | extern void bvme6000_reset (void); |
46 | void bvme6000_set_vectors (void); | 46 | void bvme6000_set_vectors (void); |
47 | 47 | ||
48 | /* Save tick handler routine pointer, will point to do_timer() in | 48 | /* Save tick handler routine pointer, will point to xtime_update() in |
49 | * kernel/sched.c, called via bvme6000_process_int() */ | 49 | * kernel/timer/timekeeping.c, called via bvme6000_process_int() */ |
50 | 50 | ||
51 | static irq_handler_t tick_handler; | 51 | static irq_handler_t tick_handler; |
52 | 52 | ||
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 06438dac08ff..18b34ee5db3b 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c | |||
@@ -37,11 +37,11 @@ static inline int set_rtc_mmss(unsigned long nowtime) | |||
37 | 37 | ||
38 | /* | 38 | /* |
39 | * timer_interrupt() needs to keep up the real-time clock, | 39 | * timer_interrupt() needs to keep up the real-time clock, |
40 | * as well as call the "do_timer()" routine every clocktick | 40 | * as well as call the "xtime_update()" routine every clocktick |
41 | */ | 41 | */ |
42 | static irqreturn_t timer_interrupt(int irq, void *dummy) | 42 | static irqreturn_t timer_interrupt(int irq, void *dummy) |
43 | { | 43 | { |
44 | do_timer(1); | 44 | xtime_update(1); |
45 | update_process_times(user_mode(get_irq_regs())); | 45 | update_process_times(user_mode(get_irq_regs())); |
46 | profile_tick(CPU_PROFILING); | 46 | profile_tick(CPU_PROFILING); |
47 | 47 | ||
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 100baaa692a1..6cb9c3a9b6c9 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c | |||
@@ -46,8 +46,8 @@ extern void mvme147_reset (void); | |||
46 | 46 | ||
47 | static int bcd2int (unsigned char b); | 47 | static int bcd2int (unsigned char b); |
48 | 48 | ||
49 | /* Save tick handler routine pointer, will point to do_timer() in | 49 | /* Save tick handler routine pointer, will point to xtime_update() in |
50 | * kernel/sched.c, called via mvme147_process_int() */ | 50 | * kernel/time/timekeeping.c, called via mvme147_process_int() */ |
51 | 51 | ||
52 | irq_handler_t tick_handler; | 52 | irq_handler_t tick_handler; |
53 | 53 | ||
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 11edf61cc2c4..0b28e2621653 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c | |||
@@ -51,8 +51,8 @@ extern void mvme16x_reset (void); | |||
51 | 51 | ||
52 | int bcd2int (unsigned char b); | 52 | int bcd2int (unsigned char b); |
53 | 53 | ||
54 | /* Save tick handler routine pointer, will point to do_timer() in | 54 | /* Save tick handler routine pointer, will point to xtime_update() in |
55 | * kernel/sched.c, called via mvme16x_process_int() */ | 55 | * kernel/time/timekeeping.c, called via mvme16x_process_int() */ |
56 | 56 | ||
57 | static irq_handler_t tick_handler; | 57 | static irq_handler_t tick_handler; |
58 | 58 | ||
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 2d9e21bd313a..6464ad3ae3e6 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c | |||
@@ -66,7 +66,7 @@ static irqreturn_t sun3_int5(int irq, void *dev_id) | |||
66 | #ifdef CONFIG_SUN3 | 66 | #ifdef CONFIG_SUN3 |
67 | intersil_clear(); | 67 | intersil_clear(); |
68 | #endif | 68 | #endif |
69 | do_timer(1); | 69 | xtime_update(1); |
70 | update_process_times(user_mode(get_irq_regs())); | 70 | update_process_times(user_mode(get_irq_regs())); |
71 | if (!(kstat_cpu(0).irqs[irq] % 20)) | 71 | if (!(kstat_cpu(0).irqs[irq] % 20)) |
72 | sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); | 72 | sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); |
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index d6ac2a43453c..6623909f70e6 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c | |||
@@ -36,7 +36,7 @@ static inline int set_rtc_mmss(unsigned long nowtime) | |||
36 | #ifndef CONFIG_GENERIC_CLOCKEVENTS | 36 | #ifndef CONFIG_GENERIC_CLOCKEVENTS |
37 | /* | 37 | /* |
38 | * timer_interrupt() needs to keep up the real-time clock, | 38 | * timer_interrupt() needs to keep up the real-time clock, |
39 | * as well as call the "do_timer()" routine every clocktick | 39 | * as well as call the "xtime_update()" routine every clocktick |
40 | */ | 40 | */ |
41 | irqreturn_t arch_timer_interrupt(int irq, void *dummy) | 41 | irqreturn_t arch_timer_interrupt(int irq, void *dummy) |
42 | { | 42 | { |
@@ -44,11 +44,7 @@ irqreturn_t arch_timer_interrupt(int irq, void *dummy) | |||
44 | if (current->pid) | 44 | if (current->pid) |
45 | profile_tick(CPU_PROFILING); | 45 | profile_tick(CPU_PROFILING); |
46 | 46 | ||
47 | write_seqlock(&xtime_lock); | 47 | xtime_update(1); |
48 | |||
49 | do_timer(1); | ||
50 | |||
51 | write_sequnlock(&xtime_lock); | ||
52 | 48 | ||
53 | update_process_times(user_mode(get_irq_regs())); | 49 | update_process_times(user_mode(get_irq_regs())); |
54 | 50 | ||
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index 75da468090b9..5b955000626d 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c | |||
@@ -104,8 +104,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
104 | unsigned tsc, elapse; | 104 | unsigned tsc, elapse; |
105 | irqreturn_t ret; | 105 | irqreturn_t ret; |
106 | 106 | ||
107 | write_seqlock(&xtime_lock); | ||
108 | |||
109 | while (tsc = get_cycles(), | 107 | while (tsc = get_cycles(), |
110 | elapse = tsc - mn10300_last_tsc, /* time elapsed since last | 108 | elapse = tsc - mn10300_last_tsc, /* time elapsed since last |
111 | * tick */ | 109 | * tick */ |
@@ -114,11 +112,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
114 | mn10300_last_tsc += MN10300_TSC_PER_HZ; | 112 | mn10300_last_tsc += MN10300_TSC_PER_HZ; |
115 | 113 | ||
116 | /* advance the kernel's time tracking system */ | 114 | /* advance the kernel's time tracking system */ |
117 | do_timer(1); | 115 | xtime_update(1); |
118 | } | 116 | } |
119 | 117 | ||
120 | write_sequnlock(&xtime_lock); | ||
121 | |||
122 | ret = local_timer_interrupt(); | 118 | ret = local_timer_interrupt(); |
123 | #ifdef CONFIG_SMP | 119 | #ifdef CONFIG_SMP |
124 | send_IPI_allbutself(LOCAL_TIMER_IPI); | 120 | send_IPI_allbutself(LOCAL_TIMER_IPI); |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 05511ccb61d2..45b7389d77aa 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
@@ -162,11 +162,8 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) | |||
162 | update_process_times(user_mode(get_irq_regs())); | 162 | update_process_times(user_mode(get_irq_regs())); |
163 | } | 163 | } |
164 | 164 | ||
165 | if (cpu == 0) { | 165 | if (cpu == 0) |
166 | write_seqlock(&xtime_lock); | 166 | xtime_update(ticks_elapsed); |
167 | do_timer(ticks_elapsed); | ||
168 | write_sequnlock(&xtime_lock); | ||
169 | } | ||
170 | 167 | ||
171 | return IRQ_HANDLED; | 168 | return IRQ_HANDLED; |
172 | } | 169 | } |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index aeaa09a3c655..2cdc131b50ac 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -700,10 +700,8 @@ static void pcic_clear_clock_irq(void) | |||
700 | 700 | ||
701 | static irqreturn_t pcic_timer_handler (int irq, void *h) | 701 | static irqreturn_t pcic_timer_handler (int irq, void *h) |
702 | { | 702 | { |
703 | write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ | ||
704 | pcic_clear_clock_irq(); | 703 | pcic_clear_clock_irq(); |
705 | do_timer(1); | 704 | xtime_update(1); |
706 | write_sequnlock(&xtime_lock); | ||
707 | #ifndef CONFIG_SMP | 705 | #ifndef CONFIG_SMP |
708 | update_process_times(user_mode(get_irq_regs())); | 706 | update_process_times(user_mode(get_irq_regs())); |
709 | #endif | 707 | #endif |
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 9c743b1886ff..4211bfc9bcad 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c | |||
@@ -85,7 +85,7 @@ int update_persistent_clock(struct timespec now) | |||
85 | 85 | ||
86 | /* | 86 | /* |
87 | * timer_interrupt() needs to keep up the real-time clock, | 87 | * timer_interrupt() needs to keep up the real-time clock, |
88 | * as well as call the "do_timer()" routine every clocktick | 88 | * as well as call the "xtime_update()" routine every clocktick |
89 | */ | 89 | */ |
90 | 90 | ||
91 | #define TICK_SIZE (tick_nsec / 1000) | 91 | #define TICK_SIZE (tick_nsec / 1000) |
@@ -96,14 +96,9 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id) | |||
96 | profile_tick(CPU_PROFILING); | 96 | profile_tick(CPU_PROFILING); |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | /* Protect counter clear so that do_gettimeoffset works */ | ||
100 | write_seqlock(&xtime_lock); | ||
101 | |||
102 | clear_clock_irq(); | 99 | clear_clock_irq(); |
103 | 100 | ||
104 | do_timer(1); | 101 | xtime_update(1); |
105 | |||
106 | write_sequnlock(&xtime_lock); | ||
107 | 102 | ||
108 | #ifndef CONFIG_SMP | 103 | #ifndef CONFIG_SMP |
109 | update_process_times(user_mode(get_irq_regs())); | 104 | update_process_times(user_mode(get_irq_regs())); |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index f27b709754bf..2f0d7b450150 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -855,4 +855,5 @@ ia32_sys_call_table: | |||
855 | .quad sys_prlimit64 /* 340 */ | 855 | .quad sys_prlimit64 /* 340 */ |
856 | .quad sys_name_to_handle_at | 856 | .quad sys_name_to_handle_at |
857 | .quad compat_sys_open_by_handle_at | 857 | .quad compat_sys_open_by_handle_at |
858 | .quad compat_sys_clock_adjtime | ||
858 | ia32_syscall_end: | 859 | ia32_syscall_end: |
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index f4c4973fc2ac..ffaf183c619a 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h | |||
@@ -348,10 +348,11 @@ | |||
348 | #define __NR_prlimit64 340 | 348 | #define __NR_prlimit64 340 |
349 | #define __NR_name_to_handle_at 341 | 349 | #define __NR_name_to_handle_at 341 |
350 | #define __NR_open_by_handle_at 342 | 350 | #define __NR_open_by_handle_at 342 |
351 | #define __NR_clock_adjtime 343 | ||
351 | 352 | ||
352 | #ifdef __KERNEL__ | 353 | #ifdef __KERNEL__ |
353 | 354 | ||
354 | #define NR_syscalls 343 | 355 | #define NR_syscalls 344 |
355 | 356 | ||
356 | #define __ARCH_WANT_IPC_PARSE_VERSION | 357 | #define __ARCH_WANT_IPC_PARSE_VERSION |
357 | #define __ARCH_WANT_OLD_READDIR | 358 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 81a3d5b70235..5466bea670e7 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h | |||
@@ -673,6 +673,8 @@ __SYSCALL(__NR_prlimit64, sys_prlimit64) | |||
673 | __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) | 673 | __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) |
674 | #define __NR_open_by_handle_at 304 | 674 | #define __NR_open_by_handle_at 304 |
675 | __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) | 675 | __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) |
676 | #define __NR_clock_adjtime 305 | ||
677 | __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) | ||
676 | 678 | ||
677 | #ifndef __NO_STUBS | 679 | #ifndef __NO_STUBS |
678 | #define __ARCH_WANT_OLD_READDIR | 680 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index c314b2199efd..5f181742e8f9 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S | |||
@@ -342,3 +342,4 @@ ENTRY(sys_call_table) | |||
342 | .long sys_prlimit64 /* 340 */ | 342 | .long sys_prlimit64 /* 340 */ |
343 | .long sys_name_to_handle_at | 343 | .long sys_name_to_handle_at |
344 | .long sys_open_by_handle_at | 344 | .long sys_open_by_handle_at |
345 | .long sys_clock_adjtime | ||
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 19df764f6399..f3e5eb43f71c 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -96,16 +96,12 @@ again: | |||
96 | update_process_times(user_mode(get_irq_regs())); | 96 | update_process_times(user_mode(get_irq_regs())); |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | write_seqlock(&xtime_lock); | 99 | xtime_update(1); /* Linux handler in kernel/time/timekeeping */ |
100 | |||
101 | do_timer(1); /* Linux handler in kernel/timer.c */ | ||
102 | 100 | ||
103 | /* Note that writing CCOMPARE clears the interrupt. */ | 101 | /* Note that writing CCOMPARE clears the interrupt. */ |
104 | 102 | ||
105 | next += CCOUNT_PER_JIFFY; | 103 | next += CCOUNT_PER_JIFFY; |
106 | set_linux_timer(next); | 104 | set_linux_timer(next); |
107 | |||
108 | write_sequnlock(&xtime_lock); | ||
109 | } | 105 | } |
110 | 106 | ||
111 | /* Allow platform to do something useful (Wdog). */ | 107 | /* Allow platform to do something useful (Wdog). */ |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index e6d75627c6c8..33dc2298af73 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -53,6 +53,8 @@ MODULE_LICENSE("GPL"); | |||
53 | 53 | ||
54 | #define RTC_BITS 55 /* 55 bits for this implementation */ | 54 | #define RTC_BITS 55 /* 55 bits for this implementation */ |
55 | 55 | ||
56 | static struct k_clock sgi_clock; | ||
57 | |||
56 | extern unsigned long sn_rtc_cycles_per_second; | 58 | extern unsigned long sn_rtc_cycles_per_second; |
57 | 59 | ||
58 | #define RTC_COUNTER_ADDR ((long *)LOCAL_MMR_ADDR(SH_RTC)) | 60 | #define RTC_COUNTER_ADDR ((long *)LOCAL_MMR_ADDR(SH_RTC)) |
@@ -487,7 +489,7 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp) | |||
487 | return 0; | 489 | return 0; |
488 | }; | 490 | }; |
489 | 491 | ||
490 | static int sgi_clock_set(clockid_t clockid, struct timespec *tp) | 492 | static int sgi_clock_set(const clockid_t clockid, const struct timespec *tp) |
491 | { | 493 | { |
492 | 494 | ||
493 | u64 nsec; | 495 | u64 nsec; |
@@ -763,15 +765,21 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, | |||
763 | return err; | 765 | return err; |
764 | } | 766 | } |
765 | 767 | ||
768 | static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) | ||
769 | { | ||
770 | tp->tv_sec = 0; | ||
771 | tp->tv_nsec = sgi_clock_period; | ||
772 | return 0; | ||
773 | } | ||
774 | |||
766 | static struct k_clock sgi_clock = { | 775 | static struct k_clock sgi_clock = { |
767 | .res = 0, | 776 | .clock_set = sgi_clock_set, |
768 | .clock_set = sgi_clock_set, | 777 | .clock_get = sgi_clock_get, |
769 | .clock_get = sgi_clock_get, | 778 | .clock_getres = sgi_clock_getres, |
770 | .timer_create = sgi_timer_create, | 779 | .timer_create = sgi_timer_create, |
771 | .nsleep = do_posix_clock_nonanosleep, | 780 | .timer_set = sgi_timer_set, |
772 | .timer_set = sgi_timer_set, | 781 | .timer_del = sgi_timer_del, |
773 | .timer_del = sgi_timer_del, | 782 | .timer_get = sgi_timer_get |
774 | .timer_get = sgi_timer_get | ||
775 | }; | 783 | }; |
776 | 784 | ||
777 | /** | 785 | /** |
@@ -831,8 +839,8 @@ static int __init mmtimer_init(void) | |||
831 | (unsigned long) node); | 839 | (unsigned long) node); |
832 | } | 840 | } |
833 | 841 | ||
834 | sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; | 842 | sgi_clock_period = NSEC_PER_SEC / sn_rtc_cycles_per_second; |
835 | register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock); | 843 | posix_timers_register_clock(CLOCK_SGI_CYCLE, &sgi_clock); |
836 | 844 | ||
837 | printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION, | 845 | printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION, |
838 | sn_rtc_cycles_per_second/(unsigned long)1E6); | 846 | sn_rtc_cycles_per_second/(unsigned long)1E6); |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index f376ddc64c4d..62f500c724f9 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -54,11 +54,13 @@ enum hrtimer_restart { | |||
54 | * 0x00 inactive | 54 | * 0x00 inactive |
55 | * 0x01 enqueued into rbtree | 55 | * 0x01 enqueued into rbtree |
56 | * 0x02 callback function running | 56 | * 0x02 callback function running |
57 | * 0x04 timer is migrated to another cpu | ||
57 | * | 58 | * |
58 | * Special cases: | 59 | * Special cases: |
59 | * 0x03 callback function running and enqueued | 60 | * 0x03 callback function running and enqueued |
60 | * (was requeued on another CPU) | 61 | * (was requeued on another CPU) |
61 | * 0x09 timer was migrated on CPU hotunplug | 62 | * 0x05 timer was migrated on CPU hotunplug |
63 | * | ||
62 | * The "callback function running and enqueued" status is only possible on | 64 | * The "callback function running and enqueued" status is only possible on |
63 | * SMP. It happens for example when a posix timer expired and the callback | 65 | * SMP. It happens for example when a posix timer expired and the callback |
64 | * queued a signal. Between dropping the lock which protects the posix timer | 66 | * queued a signal. Between dropping the lock which protects the posix timer |
@@ -67,8 +69,11 @@ enum hrtimer_restart { | |||
67 | * as otherwise the timer could be removed before the softirq code finishes the | 69 | * as otherwise the timer could be removed before the softirq code finishes the |
68 | * the handling of the timer. | 70 | * the handling of the timer. |
69 | * | 71 | * |
70 | * The HRTIMER_STATE_ENQUEUED bit is always or'ed to the current state to | 72 | * The HRTIMER_STATE_ENQUEUED bit is always or'ed to the current state |
71 | * preserve the HRTIMER_STATE_CALLBACK bit in the above scenario. | 73 | * to preserve the HRTIMER_STATE_CALLBACK in the above scenario. This |
74 | * also affects HRTIMER_STATE_MIGRATE where the preservation is not | ||
75 | * necessary. HRTIMER_STATE_MIGRATE is cleared after the timer is | ||
76 | * enqueued on the new cpu. | ||
72 | * | 77 | * |
73 | * All state transitions are protected by cpu_base->lock. | 78 | * All state transitions are protected by cpu_base->lock. |
74 | */ | 79 | */ |
@@ -148,7 +153,12 @@ struct hrtimer_clock_base { | |||
148 | #endif | 153 | #endif |
149 | }; | 154 | }; |
150 | 155 | ||
151 | #define HRTIMER_MAX_CLOCK_BASES 2 | 156 | enum hrtimer_base_type { |
157 | HRTIMER_BASE_REALTIME, | ||
158 | HRTIMER_BASE_MONOTONIC, | ||
159 | HRTIMER_BASE_BOOTTIME, | ||
160 | HRTIMER_MAX_CLOCK_BASES, | ||
161 | }; | ||
152 | 162 | ||
153 | /* | 163 | /* |
154 | * struct hrtimer_cpu_base - the per cpu clock bases | 164 | * struct hrtimer_cpu_base - the per cpu clock bases |
@@ -308,6 +318,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) | |||
308 | 318 | ||
309 | extern ktime_t ktime_get(void); | 319 | extern ktime_t ktime_get(void); |
310 | extern ktime_t ktime_get_real(void); | 320 | extern ktime_t ktime_get_real(void); |
321 | extern ktime_t ktime_get_boottime(void); | ||
311 | 322 | ||
312 | 323 | ||
313 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); | 324 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
@@ -370,8 +381,9 @@ extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); | |||
370 | extern ktime_t hrtimer_get_next_event(void); | 381 | extern ktime_t hrtimer_get_next_event(void); |
371 | 382 | ||
372 | /* | 383 | /* |
373 | * A timer is active, when it is enqueued into the rbtree or the callback | 384 | * A timer is active, when it is enqueued into the rbtree or the |
374 | * function is running. | 385 | * callback function is running or it's in the state of being migrated |
386 | * to another cpu. | ||
375 | */ | 387 | */ |
376 | static inline int hrtimer_active(const struct hrtimer *timer) | 388 | static inline int hrtimer_active(const struct hrtimer *timer) |
377 | { | 389 | { |
diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h new file mode 100644 index 000000000000..369e19d3750b --- /dev/null +++ b/include/linux/posix-clock.h | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * posix-clock.h - 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 | #ifndef _LINUX_POSIX_CLOCK_H_ | ||
21 | #define _LINUX_POSIX_CLOCK_H_ | ||
22 | |||
23 | #include <linux/cdev.h> | ||
24 | #include <linux/fs.h> | ||
25 | #include <linux/poll.h> | ||
26 | #include <linux/posix-timers.h> | ||
27 | |||
28 | struct posix_clock; | ||
29 | |||
30 | /** | ||
31 | * struct posix_clock_operations - functional interface to the clock | ||
32 | * | ||
33 | * Every posix clock is represented by a character device. Drivers may | ||
34 | * optionally offer extended capabilities by implementing the | ||
35 | * character device methods. The character device file operations are | ||
36 | * first handled by the clock device layer, then passed on to the | ||
37 | * driver by calling these functions. | ||
38 | * | ||
39 | * @owner: The clock driver should set to THIS_MODULE | ||
40 | * @clock_adjtime: Adjust the clock | ||
41 | * @clock_gettime: Read the current time | ||
42 | * @clock_getres: Get the clock resolution | ||
43 | * @clock_settime: Set the current time value | ||
44 | * @timer_create: Create a new timer | ||
45 | * @timer_delete: Remove a previously created timer | ||
46 | * @timer_gettime: Get remaining time and interval of a timer | ||
47 | * @timer_setttime: Set a timer's initial expiration and interval | ||
48 | * @fasync: Optional character device fasync method | ||
49 | * @mmap: Optional character device mmap method | ||
50 | * @open: Optional character device open method | ||
51 | * @release: Optional character device release method | ||
52 | * @ioctl: Optional character device ioctl method | ||
53 | * @read: Optional character device read method | ||
54 | * @poll: Optional character device poll method | ||
55 | */ | ||
56 | struct posix_clock_operations { | ||
57 | struct module *owner; | ||
58 | |||
59 | int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx); | ||
60 | |||
61 | int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts); | ||
62 | |||
63 | int (*clock_getres) (struct posix_clock *pc, struct timespec *ts); | ||
64 | |||
65 | int (*clock_settime)(struct posix_clock *pc, | ||
66 | const struct timespec *ts); | ||
67 | |||
68 | int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit); | ||
69 | |||
70 | int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit); | ||
71 | |||
72 | void (*timer_gettime)(struct posix_clock *pc, | ||
73 | struct k_itimer *kit, struct itimerspec *tsp); | ||
74 | |||
75 | int (*timer_settime)(struct posix_clock *pc, | ||
76 | struct k_itimer *kit, int flags, | ||
77 | struct itimerspec *tsp, struct itimerspec *old); | ||
78 | /* | ||
79 | * Optional character device methods: | ||
80 | */ | ||
81 | int (*fasync) (struct posix_clock *pc, | ||
82 | int fd, struct file *file, int on); | ||
83 | |||
84 | long (*ioctl) (struct posix_clock *pc, | ||
85 | unsigned int cmd, unsigned long arg); | ||
86 | |||
87 | int (*mmap) (struct posix_clock *pc, | ||
88 | struct vm_area_struct *vma); | ||
89 | |||
90 | int (*open) (struct posix_clock *pc, fmode_t f_mode); | ||
91 | |||
92 | uint (*poll) (struct posix_clock *pc, | ||
93 | struct file *file, poll_table *wait); | ||
94 | |||
95 | int (*release) (struct posix_clock *pc); | ||
96 | |||
97 | ssize_t (*read) (struct posix_clock *pc, | ||
98 | uint flags, char __user *buf, size_t cnt); | ||
99 | }; | ||
100 | |||
101 | /** | ||
102 | * struct posix_clock - represents a dynamic posix clock | ||
103 | * | ||
104 | * @ops: Functional interface to the clock | ||
105 | * @cdev: Character device instance for this clock | ||
106 | * @kref: Reference count. | ||
107 | * @mutex: Protects the 'zombie' field from concurrent access. | ||
108 | * @zombie: If 'zombie' is true, then the hardware has disappeared. | ||
109 | * @release: A function to free the structure when the reference count reaches | ||
110 | * zero. May be NULL if structure is statically allocated. | ||
111 | * | ||
112 | * Drivers should embed their struct posix_clock within a private | ||
113 | * structure, obtaining a reference to it during callbacks using | ||
114 | * container_of(). | ||
115 | */ | ||
116 | struct posix_clock { | ||
117 | struct posix_clock_operations ops; | ||
118 | struct cdev cdev; | ||
119 | struct kref kref; | ||
120 | struct mutex mutex; | ||
121 | bool zombie; | ||
122 | void (*release)(struct posix_clock *clk); | ||
123 | }; | ||
124 | |||
125 | /** | ||
126 | * posix_clock_register() - register a new clock | ||
127 | * @clk: Pointer to the clock. Caller must provide 'ops' and 'release' | ||
128 | * @devid: Allocated device id | ||
129 | * | ||
130 | * A clock driver calls this function to register itself with the | ||
131 | * clock device subsystem. If 'clk' points to dynamically allocated | ||
132 | * memory, then the caller must provide a 'release' function to free | ||
133 | * that memory. | ||
134 | * | ||
135 | * Returns zero on success, non-zero otherwise. | ||
136 | */ | ||
137 | int posix_clock_register(struct posix_clock *clk, dev_t devid); | ||
138 | |||
139 | /** | ||
140 | * posix_clock_unregister() - unregister a clock | ||
141 | * @clk: Clock instance previously registered via posix_clock_register() | ||
142 | * | ||
143 | * A clock driver calls this function to remove itself from the clock | ||
144 | * device subsystem. The posix_clock itself will remain (in an | ||
145 | * inactive state) until its reference count drops to zero, at which | ||
146 | * point it will be deallocated with its 'release' method. | ||
147 | */ | ||
148 | void posix_clock_unregister(struct posix_clock *clk); | ||
149 | |||
150 | #endif | ||
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 3e23844a6990..d51243ae0726 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/timex.h> | ||
7 | 8 | ||
8 | union cpu_time_count { | 9 | union cpu_time_count { |
9 | cputime_t cpu; | 10 | cputime_t cpu; |
@@ -17,10 +18,21 @@ struct cpu_timer_list { | |||
17 | int firing; | 18 | int firing; |
18 | }; | 19 | }; |
19 | 20 | ||
21 | /* | ||
22 | * Bit fields within a clockid: | ||
23 | * | ||
24 | * The most significant 29 bits hold either a pid or a file descriptor. | ||
25 | * | ||
26 | * Bit 2 indicates whether a cpu clock refers to a thread or a process. | ||
27 | * | ||
28 | * Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3. | ||
29 | * | ||
30 | * A clockid is invalid if bits 2, 1, and 0 are all set. | ||
31 | */ | ||
20 | #define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3)) | 32 | #define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3)) |
21 | #define CPUCLOCK_PERTHREAD(clock) \ | 33 | #define CPUCLOCK_PERTHREAD(clock) \ |
22 | (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0) | 34 | (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0) |
23 | #define CPUCLOCK_PID_MASK 7 | 35 | |
24 | #define CPUCLOCK_PERTHREAD_MASK 4 | 36 | #define CPUCLOCK_PERTHREAD_MASK 4 |
25 | #define CPUCLOCK_WHICH(clock) ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK) | 37 | #define CPUCLOCK_WHICH(clock) ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK) |
26 | #define CPUCLOCK_CLOCK_MASK 3 | 38 | #define CPUCLOCK_CLOCK_MASK 3 |
@@ -28,12 +40,17 @@ struct cpu_timer_list { | |||
28 | #define CPUCLOCK_VIRT 1 | 40 | #define CPUCLOCK_VIRT 1 |
29 | #define CPUCLOCK_SCHED 2 | 41 | #define CPUCLOCK_SCHED 2 |
30 | #define CPUCLOCK_MAX 3 | 42 | #define CPUCLOCK_MAX 3 |
43 | #define CLOCKFD CPUCLOCK_MAX | ||
44 | #define CLOCKFD_MASK (CPUCLOCK_PERTHREAD_MASK|CPUCLOCK_CLOCK_MASK) | ||
31 | 45 | ||
32 | #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ | 46 | #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ |
33 | ((~(clockid_t) (pid) << 3) | (clockid_t) (clock)) | 47 | ((~(clockid_t) (pid) << 3) | (clockid_t) (clock)) |
34 | #define MAKE_THREAD_CPUCLOCK(tid, clock) \ | 48 | #define MAKE_THREAD_CPUCLOCK(tid, clock) \ |
35 | MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK) | 49 | MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK) |
36 | 50 | ||
51 | #define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD) | ||
52 | #define CLOCKID_TO_FD(clk) ((unsigned int) ~((clk) >> 3)) | ||
53 | |||
37 | /* POSIX.1b interval timer structure. */ | 54 | /* POSIX.1b interval timer structure. */ |
38 | struct k_itimer { | 55 | struct k_itimer { |
39 | struct list_head list; /* free/ allocate list */ | 56 | struct list_head list; /* free/ allocate list */ |
@@ -67,10 +84,11 @@ struct k_itimer { | |||
67 | }; | 84 | }; |
68 | 85 | ||
69 | struct k_clock { | 86 | struct k_clock { |
70 | int res; /* in nanoseconds */ | ||
71 | int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); | 87 | int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); |
72 | int (*clock_set) (const clockid_t which_clock, struct timespec * tp); | 88 | int (*clock_set) (const clockid_t which_clock, |
89 | const struct timespec *tp); | ||
73 | int (*clock_get) (const clockid_t which_clock, struct timespec * tp); | 90 | int (*clock_get) (const clockid_t which_clock, struct timespec * tp); |
91 | int (*clock_adj) (const clockid_t which_clock, struct timex *tx); | ||
74 | int (*timer_create) (struct k_itimer *timer); | 92 | int (*timer_create) (struct k_itimer *timer); |
75 | int (*nsleep) (const clockid_t which_clock, int flags, | 93 | int (*nsleep) (const clockid_t which_clock, int flags, |
76 | struct timespec *, struct timespec __user *); | 94 | struct timespec *, struct timespec __user *); |
@@ -84,28 +102,14 @@ struct k_clock { | |||
84 | struct itimerspec * cur_setting); | 102 | struct itimerspec * cur_setting); |
85 | }; | 103 | }; |
86 | 104 | ||
87 | void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock); | 105 | extern struct k_clock clock_posix_cpu; |
106 | extern struct k_clock clock_posix_dynamic; | ||
88 | 107 | ||
89 | /* error handlers for timer_create, nanosleep and settime */ | 108 | void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock); |
90 | int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *, | ||
91 | struct timespec __user *); | ||
92 | int do_posix_clock_nosettime(const clockid_t, struct timespec *tp); | ||
93 | 109 | ||
94 | /* function to call to trigger timer event */ | 110 | /* function to call to trigger timer event */ |
95 | int posix_timer_event(struct k_itimer *timr, int si_private); | 111 | int posix_timer_event(struct k_itimer *timr, int si_private); |
96 | 112 | ||
97 | int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *ts); | ||
98 | int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *ts); | ||
99 | int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts); | ||
100 | int posix_cpu_timer_create(struct k_itimer *timer); | ||
101 | int posix_cpu_nsleep(const clockid_t which_clock, int flags, | ||
102 | struct timespec *rqtp, struct timespec __user *rmtp); | ||
103 | long posix_cpu_nsleep_restart(struct restart_block *restart_block); | ||
104 | int posix_cpu_timer_set(struct k_itimer *timer, int flags, | ||
105 | struct itimerspec *new, struct itimerspec *old); | ||
106 | int posix_cpu_timer_del(struct k_itimer *timer); | ||
107 | void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp); | ||
108 | |||
109 | void posix_cpu_timer_schedule(struct k_itimer *timer); | 113 | void posix_cpu_timer_schedule(struct k_itimer *timer); |
110 | 114 | ||
111 | void run_posix_cpu_timers(struct task_struct *task); | 115 | void run_posix_cpu_timers(struct task_struct *task); |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 214af2ed11b5..c15936fe998b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2046,7 +2046,7 @@ extern void release_uids(struct user_namespace *ns); | |||
2046 | 2046 | ||
2047 | #include <asm/current.h> | 2047 | #include <asm/current.h> |
2048 | 2048 | ||
2049 | extern void do_timer(unsigned long ticks); | 2049 | extern void xtime_update(unsigned long ticks); |
2050 | 2050 | ||
2051 | extern int wake_up_state(struct task_struct *tsk, unsigned int state); | 2051 | extern int wake_up_state(struct task_struct *tsk, unsigned int state); |
2052 | extern int wake_up_process(struct task_struct *tsk); | 2052 | extern int wake_up_process(struct task_struct *tsk); |
diff --git a/include/linux/security.h b/include/linux/security.h index b2b7f9749f5e..debbd97db7ab 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -53,7 +53,7 @@ struct audit_krule; | |||
53 | */ | 53 | */ |
54 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, | 54 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, |
55 | int cap, int audit); | 55 | int cap, int audit); |
56 | extern int cap_settime(struct timespec *ts, struct timezone *tz); | 56 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); |
57 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); | 57 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); |
58 | extern int cap_ptrace_traceme(struct task_struct *parent); | 58 | extern int cap_ptrace_traceme(struct task_struct *parent); |
59 | extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); | 59 | extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); |
@@ -1387,7 +1387,7 @@ struct security_operations { | |||
1387 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); | 1387 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); |
1388 | int (*quota_on) (struct dentry *dentry); | 1388 | int (*quota_on) (struct dentry *dentry); |
1389 | int (*syslog) (int type); | 1389 | int (*syslog) (int type); |
1390 | int (*settime) (struct timespec *ts, struct timezone *tz); | 1390 | int (*settime) (const struct timespec *ts, const struct timezone *tz); |
1391 | int (*vm_enough_memory) (struct mm_struct *mm, long pages); | 1391 | int (*vm_enough_memory) (struct mm_struct *mm, long pages); |
1392 | 1392 | ||
1393 | int (*bprm_set_creds) (struct linux_binprm *bprm); | 1393 | int (*bprm_set_creds) (struct linux_binprm *bprm); |
@@ -1669,7 +1669,7 @@ int security_sysctl(struct ctl_table *table, int op); | |||
1669 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); | 1669 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); |
1670 | int security_quota_on(struct dentry *dentry); | 1670 | int security_quota_on(struct dentry *dentry); |
1671 | int security_syslog(int type); | 1671 | int security_syslog(int type); |
1672 | int security_settime(struct timespec *ts, struct timezone *tz); | 1672 | int security_settime(const struct timespec *ts, const struct timezone *tz); |
1673 | int security_vm_enough_memory(long pages); | 1673 | int security_vm_enough_memory(long pages); |
1674 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); | 1674 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); |
1675 | int security_vm_enough_memory_kern(long pages); | 1675 | int security_vm_enough_memory_kern(long pages); |
@@ -1904,7 +1904,8 @@ static inline int security_syslog(int type) | |||
1904 | return 0; | 1904 | return 0; |
1905 | } | 1905 | } |
1906 | 1906 | ||
1907 | static inline int security_settime(struct timespec *ts, struct timezone *tz) | 1907 | static inline int security_settime(const struct timespec *ts, |
1908 | const struct timezone *tz) | ||
1908 | { | 1909 | { |
1909 | return cap_settime(ts, tz); | 1910 | return cap_settime(ts, tz); |
1910 | } | 1911 | } |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 4acc6b6088b0..1f5c18e6f4f1 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -316,6 +316,8 @@ asmlinkage long sys_clock_settime(clockid_t which_clock, | |||
316 | const struct timespec __user *tp); | 316 | const struct timespec __user *tp); |
317 | asmlinkage long sys_clock_gettime(clockid_t which_clock, | 317 | asmlinkage long sys_clock_gettime(clockid_t which_clock, |
318 | struct timespec __user *tp); | 318 | struct timespec __user *tp); |
319 | asmlinkage long sys_clock_adjtime(clockid_t which_clock, | ||
320 | struct timex __user *tx); | ||
319 | asmlinkage long sys_clock_getres(clockid_t which_clock, | 321 | asmlinkage long sys_clock_getres(clockid_t which_clock, |
320 | struct timespec __user *tp); | 322 | struct timespec __user *tp); |
321 | asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, | 323 | asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, |
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index c90696544176..20fc303947d3 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h | |||
@@ -18,9 +18,6 @@ struct compat_timespec; | |||
18 | struct restart_block { | 18 | struct restart_block { |
19 | long (*fn)(struct restart_block *); | 19 | long (*fn)(struct restart_block *); |
20 | union { | 20 | union { |
21 | struct { | ||
22 | unsigned long arg0, arg1, arg2, arg3; | ||
23 | }; | ||
24 | /* For futex_wait and futex_wait_requeue_pi */ | 21 | /* For futex_wait and futex_wait_requeue_pi */ |
25 | struct { | 22 | struct { |
26 | u32 __user *uaddr; | 23 | u32 __user *uaddr; |
diff --git a/include/linux/time.h b/include/linux/time.h index 1e6d3b59238d..454a26205787 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -113,8 +113,6 @@ static inline struct timespec timespec_sub(struct timespec lhs, | |||
113 | #define timespec_valid(ts) \ | 113 | #define timespec_valid(ts) \ |
114 | (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) | 114 | (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) |
115 | 115 | ||
116 | extern seqlock_t xtime_lock; | ||
117 | |||
118 | extern void read_persistent_clock(struct timespec *ts); | 116 | extern void read_persistent_clock(struct timespec *ts); |
119 | extern void read_boot_clock(struct timespec *ts); | 117 | extern void read_boot_clock(struct timespec *ts); |
120 | extern int update_persistent_clock(struct timespec now); | 118 | extern int update_persistent_clock(struct timespec now); |
@@ -125,8 +123,9 @@ extern int timekeeping_suspended; | |||
125 | unsigned long get_seconds(void); | 123 | unsigned long get_seconds(void); |
126 | struct timespec current_kernel_time(void); | 124 | struct timespec current_kernel_time(void); |
127 | struct timespec __current_kernel_time(void); /* does not take xtime_lock */ | 125 | struct timespec __current_kernel_time(void); /* does not take xtime_lock */ |
128 | struct timespec __get_wall_to_monotonic(void); /* does not take xtime_lock */ | ||
129 | struct timespec get_monotonic_coarse(void); | 126 | struct timespec get_monotonic_coarse(void); |
127 | void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | ||
128 | struct timespec *wtom, struct timespec *sleep); | ||
130 | 129 | ||
131 | #define CURRENT_TIME (current_kernel_time()) | 130 | #define CURRENT_TIME (current_kernel_time()) |
132 | #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) | 131 | #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) |
@@ -147,8 +146,9 @@ static inline u32 arch_gettimeoffset(void) { return 0; } | |||
147 | #endif | 146 | #endif |
148 | 147 | ||
149 | extern void do_gettimeofday(struct timeval *tv); | 148 | extern void do_gettimeofday(struct timeval *tv); |
150 | extern int do_settimeofday(struct timespec *tv); | 149 | extern int do_settimeofday(const struct timespec *tv); |
151 | extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz); | 150 | extern int do_sys_settimeofday(const struct timespec *tv, |
151 | const struct timezone *tz); | ||
152 | #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) | 152 | #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) |
153 | extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); | 153 | extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); |
154 | struct itimerval; | 154 | struct itimerval; |
@@ -162,12 +162,13 @@ extern void getnstime_raw_and_real(struct timespec *ts_raw, | |||
162 | struct timespec *ts_real); | 162 | struct timespec *ts_real); |
163 | extern void getboottime(struct timespec *ts); | 163 | extern void getboottime(struct timespec *ts); |
164 | extern void monotonic_to_bootbased(struct timespec *ts); | 164 | extern void monotonic_to_bootbased(struct timespec *ts); |
165 | extern void get_monotonic_boottime(struct timespec *ts); | ||
165 | 166 | ||
166 | extern struct timespec timespec_trunc(struct timespec t, unsigned gran); | 167 | extern struct timespec timespec_trunc(struct timespec t, unsigned gran); |
167 | extern int timekeeping_valid_for_hres(void); | 168 | extern int timekeeping_valid_for_hres(void); |
168 | extern u64 timekeeping_max_deferment(void); | 169 | extern u64 timekeeping_max_deferment(void); |
169 | extern void update_wall_time(void); | ||
170 | extern void timekeeping_leap_insert(int leapsecond); | 170 | extern void timekeeping_leap_insert(int leapsecond); |
171 | extern int timekeeping_inject_offset(struct timespec *ts); | ||
171 | 172 | ||
172 | struct tms; | 173 | struct tms; |
173 | extern void do_sys_times(struct tms *); | 174 | extern void do_sys_times(struct tms *); |
@@ -292,6 +293,7 @@ struct itimerval { | |||
292 | #define CLOCK_MONOTONIC_RAW 4 | 293 | #define CLOCK_MONOTONIC_RAW 4 |
293 | #define CLOCK_REALTIME_COARSE 5 | 294 | #define CLOCK_REALTIME_COARSE 5 |
294 | #define CLOCK_MONOTONIC_COARSE 6 | 295 | #define CLOCK_MONOTONIC_COARSE 6 |
296 | #define CLOCK_BOOTTIME 7 | ||
295 | 297 | ||
296 | /* | 298 | /* |
297 | * The IDs of various hardware clocks: | 299 | * The IDs of various hardware clocks: |
diff --git a/include/linux/timex.h b/include/linux/timex.h index d23999f9499d..aa60fe7b6ed6 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -73,7 +73,7 @@ struct timex { | |||
73 | long tolerance; /* clock frequency tolerance (ppm) | 73 | long tolerance; /* clock frequency tolerance (ppm) |
74 | * (read only) | 74 | * (read only) |
75 | */ | 75 | */ |
76 | struct timeval time; /* (read only) */ | 76 | struct timeval time; /* (read only, except for ADJ_SETOFFSET) */ |
77 | long tick; /* (modified) usecs between clock ticks */ | 77 | long tick; /* (modified) usecs between clock ticks */ |
78 | 78 | ||
79 | long ppsfreq; /* pps frequency (scaled ppm) (ro) */ | 79 | long ppsfreq; /* pps frequency (scaled ppm) (ro) */ |
@@ -102,6 +102,7 @@ struct timex { | |||
102 | #define ADJ_STATUS 0x0010 /* clock status */ | 102 | #define ADJ_STATUS 0x0010 /* clock status */ |
103 | #define ADJ_TIMECONST 0x0020 /* pll time constant */ | 103 | #define ADJ_TIMECONST 0x0020 /* pll time constant */ |
104 | #define ADJ_TAI 0x0080 /* set TAI offset */ | 104 | #define ADJ_TAI 0x0080 /* set TAI offset */ |
105 | #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */ | ||
105 | #define ADJ_MICRO 0x1000 /* select microsecond resolution */ | 106 | #define ADJ_MICRO 0x1000 /* select microsecond resolution */ |
106 | #define ADJ_NANO 0x2000 /* select nanosecond resolution */ | 107 | #define ADJ_NANO 0x2000 /* select nanosecond resolution */ |
107 | #define ADJ_TICK 0x4000 /* tick value */ | 108 | #define ADJ_TICK 0x4000 /* tick value */ |
diff --git a/kernel/compat.c b/kernel/compat.c index c9e2ec0b34a8..38b1d2c1cbe8 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 e38f5a073d01..9017478c5d4c 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 05bb7173850e..67fea9d25d55 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 93bd2eb2bc53..4c0124919f9a 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 55337a816b20..8e8dc6d705c9 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 ee266620b06c..b0425991e9ac 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 d7395fdfb9f3..0d74b9ba90c8 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 5404a8456909..b2fa506667c0 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 5c00242fa921..5f1bb8e2008f 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 000000000000..25028dd4fa18 --- /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 a3b5aff62606..da800ffa810c 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 ed228ef6f6b8..119528de8235 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 f65d3a723a64..1009b06d6f89 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 5cbc101f908b..2d04411a5f05 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 c55ea2433471..d5097c44b407 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 d27c7562902c..3bd7e3d5c632 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 3503c17ac1d3..fd6198692b57 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 | /* |
diff --git a/security/commoncap.c b/security/commoncap.c index 64c2ed9c9015..dbfdaed4cc66 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -93,7 +93,7 @@ int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, | |||
93 | * Determine whether the current process may set the system clock and timezone | 93 | * Determine whether the current process may set the system clock and timezone |
94 | * information, returning 0 if permission granted, -ve if denied. | 94 | * information, returning 0 if permission granted, -ve if denied. |
95 | */ | 95 | */ |
96 | int cap_settime(struct timespec *ts, struct timezone *tz) | 96 | int cap_settime(const struct timespec *ts, const struct timezone *tz) |
97 | { | 97 | { |
98 | if (!capable(CAP_SYS_TIME)) | 98 | if (!capable(CAP_SYS_TIME)) |
99 | return -EPERM; | 99 | return -EPERM; |
diff --git a/security/security.c b/security/security.c index 7b7308ace8c5..bb33ecadcf95 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -201,7 +201,7 @@ int security_syslog(int type) | |||
201 | return security_ops->syslog(type); | 201 | return security_ops->syslog(type); |
202 | } | 202 | } |
203 | 203 | ||
204 | int security_settime(struct timespec *ts, struct timezone *tz) | 204 | int security_settime(const struct timespec *ts, const struct timezone *tz) |
205 | { | 205 | { |
206 | return security_ops->settime(ts, tz); | 206 | return security_ops->settime(ts, tz); |
207 | } | 207 | } |