Blame view

kernel/posix-timers.c 29.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
f30c22695   Uwe Zeisberger   fix file specific...
2
   * linux/kernel/posix-timers.c
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   *
   *
   * 2002-10-15  Posix Clocks & timers
   *                           by George Anzinger george@mvista.com
   *
   *			     Copyright (C) 2002 2003 by MontaVista Software.
   *
   * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
   *			     Copyright (C) 2004 Boris Hu
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or (at
   * your option) any later version.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
  
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   * MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA
   */
  
  /* These are all the functions necessary to implement
   * POSIX clocks & timers
   */
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
  #include <linux/interrupt.h>
  #include <linux/slab.h>
  #include <linux/time.h>
97d1f15b7   Arjan van de Ven   [PATCH] sem2mutex...
37
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
  
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
  #include <linux/list.h>
  #include <linux/init.h>
  #include <linux/compiler.h>
  #include <linux/idr.h>
0606f422b   Richard Cochran   posix clocks: Int...
44
  #include <linux/posix-clock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
48
49
  #include <linux/posix-timers.h>
  #include <linux/syscalls.h>
  #include <linux/wait.h>
  #include <linux/workqueue.h>
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /*
   * Management arrays for POSIX timers.	 Timers are kept in slab memory
   * Timer ids are allocated by an external routine that keeps track of the
   * id and the timer.  The external interface is:
   *
   * void *idr_find(struct idr *idp, int id);           to find timer_id <id>
   * int idr_get_new(struct idr *idp, void *ptr);       to get a new id and
   *                                                    related it to <ptr>
   * void idr_remove(struct idr *idp, int id);          to release <id>
   * void idr_init(struct idr *idp);                    to initialize <idp>
   *                                                    which we supply.
   * The idr_get_new *may* call slab for more memory so it must not be
   * called under a spin lock.  Likewise idr_remore may release memory
   * (but it may be ok to do this under a lock...).
   * idr_find is just a memory look up and is quite fast.  A -1 return
   * indicates that the requested id does not exist.
   */
  
  /*
   * Lets keep our timers in a slab cache :-)
   */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
71
  static struct kmem_cache *posix_timers_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
  static struct idr posix_timers_id;
  static DEFINE_SPINLOCK(idr_lock);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
81
82
   * we assume that the new SIGEV_THREAD_ID shares no bits with the other
   * SIGEV values.  Here we put out an error if this assumption fails.
   */
  #if SIGEV_THREAD_ID != (SIGEV_THREAD_ID & \
                         ~(SIGEV_SIGNAL | SIGEV_NONE | SIGEV_THREAD))
  #error "SIGEV_THREAD_ID must not share bit with other SIGEV values!"
  #endif
65da528d7   Thomas Gleixner   posix-timers: Def...
83
84
85
86
87
88
89
90
  /*
   * parisc wants ENOTSUP instead of EOPNOTSUPP
   */
  #ifndef ENOTSUP
  # define ENANOSLEEP_NOTSUP EOPNOTSUPP
  #else
  # define ENANOSLEEP_NOTSUP ENOTSUP
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
95
96
97
98
99
100
101
102
103
  
  /*
   * The timer ID is turned into a timer address by idr_find().
   * Verifying a valid ID consists of:
   *
   * a) checking that idr_find() returns other than -1.
   * b) checking that the timer id matches the one in the timer itself.
   * c) that the timer owner is in the callers thread group.
   */
  
  /*
   * CLOCKs: The POSIX standard calls for a couple of clocks and allows us
   *	    to implement others.  This structure defines the various
0061748dd   Richard Cochran   posix-timer: Upda...
104
   *	    clocks.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
108
109
110
111
112
113
   *
   * RESOLUTION: Clock resolution is used to round up timer and interval
   *	    times, NOT to report clock times, which are reported with as
   *	    much resolution as the system can muster.  In some cases this
   *	    resolution may depend on the underlying clock hardware and
   *	    may not be quantifiable until run time, and only then is the
   *	    necessary code is written.	The standard says we should say
   *	    something about this issue in the documentation...
   *
0061748dd   Richard Cochran   posix-timer: Upda...
114
115
   * FUNCTIONS: The CLOCKs structure defines possible functions to
   *	    handle various clock functions.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
   *
0061748dd   Richard Cochran   posix-timer: Upda...
117
118
119
120
   *	    The standard POSIX timer management code assumes the
   *	    following: 1.) The k_itimer struct (sched.h) is used for
   *	    the timer.  2.) The list, it_lock, it_clock, it_id and
   *	    it_pid fields are not modified by timer code.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
123
124
125
126
127
128
129
130
   *
   * Permissions: It is assumed that the clock_settime() function defined
   *	    for each clock will take care of permission checks.	 Some
   *	    clocks may be set able by any user (i.e. local process
   *	    clocks) others not.	 Currently the only set able clock we
   *	    have is CLOCK_REALTIME and its high res counter part, both of
   *	    which we beg off on and pass to do_sys_settimeofday().
   */
  
  static struct k_clock posix_clocks[MAX_CLOCKS];
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
131

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  /*
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
133
   * These ones are defined below.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
   */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
135
136
  static int common_nsleep(const clockid_t, int flags, struct timespec *t,
  			 struct timespec __user *rmtp);
838394fbf   Thomas Gleixner   posix-timers: Con...
137
  static int common_timer_create(struct k_itimer *new_timer);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
138
139
140
141
  static void common_timer_get(struct k_itimer *, struct itimerspec *);
  static int common_timer_set(struct k_itimer *, int,
  			    struct itimerspec *, struct itimerspec *);
  static int common_timer_del(struct k_itimer *timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
143
  static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144

20f33a03f   Namhyung Kim   posix-timers: Ann...
145
146
147
148
149
150
151
  static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags);
  
  #define lock_timer(tid, flags)						   \
  ({	struct k_itimer *__timr;					   \
  	__cond_lock(&__timr->it_lock, __timr = __lock_timer(tid, flags));  \
  	__timr;								   \
  })
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
  
  static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
  {
  	spin_unlock_irqrestore(&timr->it_lock, flags);
  }
422857776   Thomas Gleixner   posix-timers: Con...
157
158
159
160
161
162
  /* Get clock_realtime */
  static int posix_clock_realtime_get(clockid_t which_clock, struct timespec *tp)
  {
  	ktime_get_real_ts(tp);
  	return 0;
  }
26f9a4796   Thomas Gleixner   posix-timers: Con...
163
164
165
166
167
168
  /* Set clock_realtime */
  static int posix_clock_realtime_set(const clockid_t which_clock,
  				    const struct timespec *tp)
  {
  	return do_sys_settimeofday(tp, NULL);
  }
f1f1d5ebd   Richard Cochran   posix-timers: Int...
169
170
171
172
173
  static int posix_clock_realtime_adj(const clockid_t which_clock,
  				    struct timex *t)
  {
  	return do_adjtimex(t);
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
174
175
176
177
178
179
180
181
  /*
   * Get monotonic time for posix timers
   */
  static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
  {
  	ktime_get_ts(tp);
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
  
  /*
7fdd7f890   John Stultz   timers: Export CL...
184
   * Get monotonic-raw time for posix timers
2d42244ae   John Stultz   clocksource: intr...
185
186
187
188
189
190
   */
  static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
  {
  	getrawmonotonic(tp);
  	return 0;
  }
da15cfdae   John Stultz   time: Introduce C...
191
192
193
194
195
196
197
198
199
200
201
202
203
  
  static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
  {
  	*tp = current_kernel_time();
  	return 0;
  }
  
  static int posix_get_monotonic_coarse(clockid_t which_clock,
  						struct timespec *tp)
  {
  	*tp = get_monotonic_coarse();
  	return 0;
  }
6622e670b   H Hartley Sweeten   posix-timers.c: D...
204
  static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
da15cfdae   John Stultz   time: Introduce C...
205
206
207
208
  {
  	*tp = ktime_to_timespec(KTIME_LOW_RES);
  	return 0;
  }
7fdd7f890   John Stultz   timers: Export CL...
209
210
211
212
213
214
  
  static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp)
  {
  	get_monotonic_boottime(tp);
  	return 0;
  }
2d42244ae   John Stultz   clocksource: intr...
215
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
218
219
   * Initialize everything, well, just everything in Posix clocks/timers ;)
   */
  static __init int init_posix_timers(void)
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
220
  	struct k_clock clock_realtime = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
221
  		.clock_getres	= hrtimer_get_res,
422857776   Thomas Gleixner   posix-timers: Con...
222
  		.clock_get	= posix_clock_realtime_get,
26f9a4796   Thomas Gleixner   posix-timers: Con...
223
  		.clock_set	= posix_clock_realtime_set,
f1f1d5ebd   Richard Cochran   posix-timers: Int...
224
  		.clock_adj	= posix_clock_realtime_adj,
a5cd28801   Thomas Gleixner   posix-timers: Con...
225
  		.nsleep		= common_nsleep,
59bd5bc24   Thomas Gleixner   posix-timers: Con...
226
  		.nsleep_restart	= hrtimer_nanosleep_restart,
838394fbf   Thomas Gleixner   posix-timers: Con...
227
  		.timer_create	= common_timer_create,
27722df16   Thomas Gleixner   posix-timers: Con...
228
  		.timer_set	= common_timer_set,
a7319fa25   Thomas Gleixner   posix-timers: Con...
229
  		.timer_get	= common_timer_get,
6761c6702   Thomas Gleixner   posix-timers: Con...
230
  		.timer_del	= common_timer_del,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  	};
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
232
  	struct k_clock clock_monotonic = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
233
234
  		.clock_getres	= hrtimer_get_res,
  		.clock_get	= posix_ktime_get_ts,
a5cd28801   Thomas Gleixner   posix-timers: Con...
235
  		.nsleep		= common_nsleep,
59bd5bc24   Thomas Gleixner   posix-timers: Con...
236
  		.nsleep_restart	= hrtimer_nanosleep_restart,
838394fbf   Thomas Gleixner   posix-timers: Con...
237
  		.timer_create	= common_timer_create,
27722df16   Thomas Gleixner   posix-timers: Con...
238
  		.timer_set	= common_timer_set,
a7319fa25   Thomas Gleixner   posix-timers: Con...
239
  		.timer_get	= common_timer_get,
6761c6702   Thomas Gleixner   posix-timers: Con...
240
  		.timer_del	= common_timer_del,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  	};
2d42244ae   John Stultz   clocksource: intr...
242
  	struct k_clock clock_monotonic_raw = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
243
244
  		.clock_getres	= hrtimer_get_res,
  		.clock_get	= posix_get_monotonic_raw,
2d42244ae   John Stultz   clocksource: intr...
245
  	};
da15cfdae   John Stultz   time: Introduce C...
246
  	struct k_clock clock_realtime_coarse = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
247
248
  		.clock_getres	= posix_get_coarse_res,
  		.clock_get	= posix_get_realtime_coarse,
da15cfdae   John Stultz   time: Introduce C...
249
250
  	};
  	struct k_clock clock_monotonic_coarse = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
251
252
  		.clock_getres	= posix_get_coarse_res,
  		.clock_get	= posix_get_monotonic_coarse,
da15cfdae   John Stultz   time: Introduce C...
253
  	};
7fdd7f890   John Stultz   timers: Export CL...
254
255
256
257
258
259
260
261
262
263
  	struct k_clock clock_boottime = {
  		.clock_getres	= hrtimer_get_res,
  		.clock_get	= posix_get_boottime,
  		.nsleep		= common_nsleep,
  		.nsleep_restart	= hrtimer_nanosleep_restart,
  		.timer_create	= common_timer_create,
  		.timer_set	= common_timer_set,
  		.timer_get	= common_timer_get,
  		.timer_del	= common_timer_del,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264

527087374   Thomas Gleixner   posix-timers: Cle...
265
266
267
268
269
  	posix_timers_register_clock(CLOCK_REALTIME, &clock_realtime);
  	posix_timers_register_clock(CLOCK_MONOTONIC, &clock_monotonic);
  	posix_timers_register_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
  	posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
  	posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
7fdd7f890   John Stultz   timers: Export CL...
270
  	posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
  
  	posix_timers_cache = kmem_cache_create("posix_timers_cache",
040b5c6f9   Alexey Dobriyan   SLAB_PANIC more (...
273
274
  					sizeof (struct k_itimer), 0, SLAB_PANIC,
  					NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
  	idr_init(&posix_timers_id);
  	return 0;
  }
  
  __initcall(init_posix_timers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
  static void schedule_next_timer(struct k_itimer *timr)
  {
44f214755   Roman Zippel   [PATCH] hrtimers:...
282
  	struct hrtimer *timer = &timr->it.real.timer;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
283
  	if (timr->it.real.interval.tv64 == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  		return;
4d672e7ac   Davide Libenzi   timerfd: new time...
285
286
287
  	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
  						timer->base->get_time(),
  						timr->it.real.interval);
44f214755   Roman Zippel   [PATCH] hrtimers:...
288

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
291
  	timr->it_overrun_last = timr->it_overrun;
  	timr->it_overrun = -1;
  	++timr->it_requeue_pending;
44f214755   Roman Zippel   [PATCH] hrtimers:...
292
  	hrtimer_restart(timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
  }
  
  /*
   * This function is exported for use by the signal deliver code.  It is
   * called just prior to the info block being released and passes that
   * block to us.  It's function is to update the overrun entry AND to
   * restart the timer.  It should only be called if the timer is to be
   * restarted (i.e. we have flagged this in the sys_private entry of the
   * info block).
   *
   * To protect aginst the timer going away while the interrupt is queued,
   * we require that the it_requeue_pending flag be set.
   */
  void do_schedule_next_timer(struct siginfo *info)
  {
  	struct k_itimer *timr;
  	unsigned long flags;
  
  	timr = lock_timer(info->si_tid, &flags);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
312
313
314
315
316
  	if (timr && timr->it_requeue_pending == info->si_sys_private) {
  		if (timr->it_clock < 0)
  			posix_cpu_timer_schedule(timr);
  		else
  			schedule_next_timer(timr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317

54da11749   Oleg Nesterov   posix-timers: do_...
318
  		info->si_overrun += timr->it_overrun_last;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
319
  	}
b6557fbca   Thomas Gleixner   [PATCH] hrtimers:...
320
321
  	if (timr)
  		unlock_timer(timr, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  }
ba661292a   Oleg Nesterov   posix-timers: fix...
323
  int posix_timer_event(struct k_itimer *timr, int si_private)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  {
27af4245b   Oleg Nesterov   posix-timers: use...
325
326
  	struct task_struct *task;
  	int shared, ret = -1;
ba661292a   Oleg Nesterov   posix-timers: fix...
327
328
329
330
331
332
333
334
335
336
337
  	/*
  	 * FIXME: if ->sigq is queued we can race with
  	 * dequeue_signal()->do_schedule_next_timer().
  	 *
  	 * If dequeue_signal() sees the "right" value of
  	 * si_sys_private it calls do_schedule_next_timer().
  	 * We re-queue ->sigq and drop ->it_lock().
  	 * do_schedule_next_timer() locks the timer
  	 * and re-schedules it while ->sigq is pending.
  	 * Not really bad, but not that we want.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  	timr->sigq->info.si_sys_private = si_private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339

27af4245b   Oleg Nesterov   posix-timers: use...
340
341
342
343
344
345
346
  	rcu_read_lock();
  	task = pid_task(timr->it_pid, PIDTYPE_PID);
  	if (task) {
  		shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
  		ret = send_sigqueue(timr->sigq, task, shared);
  	}
  	rcu_read_unlock();
4aa736117   Oleg Nesterov   posix-timers: don...
347
348
  	/* If we failed to send the signal the timer stops. */
  	return ret > 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
356
357
358
  }
  EXPORT_SYMBOL_GPL(posix_timer_event);
  
  /*
   * This function gets called when a POSIX.1b interval timer expires.  It
   * is used as a callback from the kernel internal timer.  The
   * run_timer_list code ALWAYS calls with interrupts on.
  
   * This code is for CLOCK_REALTIME* and CLOCK_MONOTONIC* timers.
   */
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
359
  static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  {
05cfb614d   Roman Zippel   [PATCH] hrtimers:...
361
  	struct k_itimer *timr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  	unsigned long flags;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
363
  	int si_private = 0;
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
364
  	enum hrtimer_restart ret = HRTIMER_NORESTART;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365

05cfb614d   Roman Zippel   [PATCH] hrtimers:...
366
  	timr = container_of(timer, struct k_itimer, it.real.timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  	spin_lock_irqsave(&timr->it_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
369
370
  	if (timr->it.real.interval.tv64 != 0)
  		si_private = ++timr->it_requeue_pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
372
373
374
375
376
377
378
  	if (posix_timer_event(timr, si_private)) {
  		/*
  		 * signal was not sent because of sig_ignor
  		 * we will not get a call back to restart it AND
  		 * it should be restarted.
  		 */
  		if (timr->it.real.interval.tv64 != 0) {
58229a189   Thomas Gleixner   posix-timers: Pre...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  			ktime_t now = hrtimer_cb_get_time(timer);
  
  			/*
  			 * FIXME: What we really want, is to stop this
  			 * timer completely and restart it in case the
  			 * SIG_IGN is removed. This is a non trivial
  			 * change which involves sighand locking
  			 * (sigh !), which we don't want to do late in
  			 * the release cycle.
  			 *
  			 * For now we just let timers with an interval
  			 * less than a jiffie expire every jiffie to
  			 * avoid softirq starvation in case of SIG_IGN
  			 * and a very small interval, which would put
  			 * the timer right back on the softirq pending
  			 * list. By moving now ahead of time we trick
  			 * hrtimer_forward() to expire the timer
  			 * later, while we still maintain the overrun
  			 * accuracy, but have some inconsistency in
  			 * the timer_gettime() case. This is at least
  			 * better than a starved softirq. A more
  			 * complex fix which solves also another related
  			 * inconsistency is already in the pipeline.
  			 */
  #ifdef CONFIG_HIGH_RES_TIMERS
  			{
  				ktime_t kj = ktime_set(0, NSEC_PER_SEC / HZ);
  
  				if (timr->it.real.interval.tv64 < kj.tv64)
  					now = ktime_add(now, kj);
  			}
  #endif
4d672e7ac   Davide Libenzi   timerfd: new time...
411
  			timr->it_overrun += (unsigned int)
58229a189   Thomas Gleixner   posix-timers: Pre...
412
  				hrtimer_forward(timer, now,
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
413
414
  						timr->it.real.interval);
  			ret = HRTIMER_RESTART;
a0a0c28c1   Roman Zippel   [PATCH] posix-tim...
415
  			++timr->it_requeue_pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
419
420
421
  	unlock_timer(timr, flags);
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422

27af4245b   Oleg Nesterov   posix-timers: use...
423
  static struct pid *good_sigevent(sigevent_t * event)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
426
427
  {
  	struct task_struct *rtn = current->group_leader;
  
  	if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
8dc86af00   Pavel Emelyanov   Use find_task_by_...
428
  		(!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
bac0abd61   Pavel Emelyanov   Isolate some expl...
429
  		 !same_thread_group(rtn, current) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
432
433
434
435
  		 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
  		return NULL;
  
  	if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) &&
  	    ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
  		return NULL;
27af4245b   Oleg Nesterov   posix-timers: use...
436
  	return task_pid(rtn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
  }
527087374   Thomas Gleixner   posix-timers: Cle...
438
439
  void posix_timers_register_clock(const clockid_t clock_id,
  				 struct k_clock *new_clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
  {
  	if ((unsigned) clock_id >= MAX_CLOCKS) {
4359ac0ac   Thomas Gleixner   posix-timers: Mak...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  		printk(KERN_WARNING "POSIX clock register failed for clock_id %d
  ",
  		       clock_id);
  		return;
  	}
  
  	if (!new_clock->clock_get) {
  		printk(KERN_WARNING "POSIX clock id %d lacks clock_get()
  ",
  		       clock_id);
  		return;
  	}
  	if (!new_clock->clock_getres) {
  		printk(KERN_WARNING "POSIX clock id %d lacks clock_getres()
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
459
460
461
462
  		       clock_id);
  		return;
  	}
  
  	posix_clocks[clock_id] = *new_clock;
  }
527087374   Thomas Gleixner   posix-timers: Cle...
463
  EXPORT_SYMBOL_GPL(posix_timers_register_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
467
  
  static struct k_itimer * alloc_posix_timer(void)
  {
  	struct k_itimer *tmr;
c37622296   Robert P. J. Day   [PATCH] Transform...
468
  	tmr = kmem_cache_zalloc(posix_timers_cache, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
  	if (!tmr)
  		return tmr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
  	if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
  		kmem_cache_free(posix_timers_cache, tmr);
aa94fbd5c   Dan Carpenter   fix error-path NU...
473
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
  	}
ba661292a   Oleg Nesterov   posix-timers: fix...
475
  	memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
478
479
480
481
482
483
484
485
486
487
488
  	return tmr;
  }
  
  #define IT_ID_SET	1
  #define IT_ID_NOT_SET	0
  static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
  {
  	if (it_id_set) {
  		unsigned long flags;
  		spin_lock_irqsave(&idr_lock, flags);
  		idr_remove(&posix_timers_id, tmr->it_id);
  		spin_unlock_irqrestore(&idr_lock, flags);
  	}
899921025   Oleg Nesterov   posix-timers: che...
489
  	put_pid(tmr->it_pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
  	sigqueue_free(tmr->sigq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
  	kmem_cache_free(posix_timers_cache, tmr);
  }
cc785ac22   Thomas Gleixner   posix-timers: Int...
493
494
495
  static struct k_clock *clockid_to_kclock(const clockid_t id)
  {
  	if (id < 0)
0606f422b   Richard Cochran   posix clocks: Int...
496
497
  		return (id & CLOCKFD_MASK) == CLOCKFD ?
  			&clock_posix_dynamic : &clock_posix_cpu;
cc785ac22   Thomas Gleixner   posix-timers: Int...
498
499
500
501
502
  
  	if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres)
  		return NULL;
  	return &posix_clocks[id];
  }
838394fbf   Thomas Gleixner   posix-timers: Con...
503
504
505
506
507
  static int common_timer_create(struct k_itimer *new_timer)
  {
  	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
  /* Create a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
509
510
511
  SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
  		struct sigevent __user *, timer_event_spec,
  		timer_t __user *, created_timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  {
838394fbf   Thomas Gleixner   posix-timers: Con...
513
  	struct k_clock *kc = clockid_to_kclock(which_clock);
2cd499e38   Oleg Nesterov   posix-timers: sys...
514
  	struct k_itimer *new_timer;
ef864c958   Oleg Nesterov   posix-timers: sys...
515
  	int error, new_timer_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
  	sigevent_t event;
  	int it_id_set = IT_ID_NOT_SET;
838394fbf   Thomas Gleixner   posix-timers: Con...
518
  	if (!kc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
  		return -EINVAL;
838394fbf   Thomas Gleixner   posix-timers: Con...
520
521
  	if (!kc->timer_create)
  		return -EOPNOTSUPP;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
524
525
526
527
528
529
530
531
532
533
  
  	new_timer = alloc_posix_timer();
  	if (unlikely(!new_timer))
  		return -EAGAIN;
  
  	spin_lock_init(&new_timer->it_lock);
   retry:
  	if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
  		error = -EAGAIN;
  		goto out;
  	}
  	spin_lock_irq(&idr_lock);
5a51b713c   Oleg Nesterov   posix-timers: loc...
534
  	error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  	spin_unlock_irq(&idr_lock);
ef864c958   Oleg Nesterov   posix-timers: sys...
536
537
538
  	if (error) {
  		if (error == -EAGAIN)
  			goto retry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  		/*
0b0a3e7b1   Joe Perches   kernel/: Spelling...
540
  		 * Weird looking, but we return EAGAIN if the IDR is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
542
543
544
545
546
547
548
549
550
  		 * full (proper POSIX return value for this)
  		 */
  		error = -EAGAIN;
  		goto out;
  	}
  
  	it_id_set = IT_ID_SET;
  	new_timer->it_id = (timer_t) new_timer_id;
  	new_timer->it_clock = which_clock;
  	new_timer->it_overrun = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
555
556
  	if (timer_event_spec) {
  		if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
  			error = -EFAULT;
  			goto out;
  		}
36b2f0460   Oleg Nesterov   posix-timers: sys...
557
  		rcu_read_lock();
899921025   Oleg Nesterov   posix-timers: che...
558
  		new_timer->it_pid = get_pid(good_sigevent(&event));
36b2f0460   Oleg Nesterov   posix-timers: sys...
559
  		rcu_read_unlock();
899921025   Oleg Nesterov   posix-timers: che...
560
  		if (!new_timer->it_pid) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
562
563
564
  			error = -EINVAL;
  			goto out;
  		}
  	} else {
5a9fa7307   Oleg Nesterov   posix-timers: kil...
565
566
567
  		event.sigev_notify = SIGEV_SIGNAL;
  		event.sigev_signo = SIGALRM;
  		event.sigev_value.sival_int = new_timer->it_id;
899921025   Oleg Nesterov   posix-timers: che...
568
  		new_timer->it_pid = get_pid(task_tgid(current));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  	}
5a9fa7307   Oleg Nesterov   posix-timers: kil...
570
571
572
  	new_timer->it_sigev_notify     = event.sigev_notify;
  	new_timer->sigq->info.si_signo = event.sigev_signo;
  	new_timer->sigq->info.si_value = event.sigev_value;
717835d94   Oleg Nesterov   posix-timers: mov...
573
  	new_timer->sigq->info.si_tid   = new_timer->it_id;
5a9fa7307   Oleg Nesterov   posix-timers: kil...
574
  	new_timer->sigq->info.si_code  = SI_TIMER;
717835d94   Oleg Nesterov   posix-timers: mov...
575

2b08de007   Andrey Vagin   posix_timer: Move...
576
577
578
579
580
  	if (copy_to_user(created_timer_id,
  			 &new_timer_id, sizeof (new_timer_id))) {
  		error = -EFAULT;
  		goto out;
  	}
838394fbf   Thomas Gleixner   posix-timers: Con...
581
  	error = kc->timer_create(new_timer);
45e0fffc8   Andrey Vagin   posix_timer: Fix ...
582
583
  	if (error)
  		goto out;
36b2f0460   Oleg Nesterov   posix-timers: sys...
584
  	spin_lock_irq(&current->sighand->siglock);
27af4245b   Oleg Nesterov   posix-timers: use...
585
  	new_timer->it_signal = current->signal;
36b2f0460   Oleg Nesterov   posix-timers: sys...
586
587
  	list_add(&new_timer->list, &current->signal->posix_timers);
  	spin_unlock_irq(&current->sighand->siglock);
ef864c958   Oleg Nesterov   posix-timers: sys...
588
589
  
  	return 0;
838394fbf   Thomas Gleixner   posix-timers: Con...
590
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
594
595
  	 * In the case of the timer belonging to another task, after
  	 * the task is unlocked, the timer is owned by the other task
  	 * and may cease to exist at any time.  Don't use or modify
  	 * new_timer after the unlock call.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
  out:
ef864c958   Oleg Nesterov   posix-timers: sys...
597
  	release_posix_timer(new_timer, it_id_set);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
600
601
  	return error;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
603
604
605
606
607
   * Locking issues: We need to protect the result of the id look up until
   * we get the timer locked down so it is not deleted under us.  The
   * removal is done under the idr spinlock so we use that here to bridge
   * the find to the timer lock.  To avoid a dead lock, the timer id MUST
   * be release with out holding the timer lock.
   */
20f33a03f   Namhyung Kim   posix-timers: Ann...
608
  static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
611
612
613
614
615
  {
  	struct k_itimer *timr;
  	/*
  	 * Watch out here.  We do a irqsave on the idr_lock and pass the
  	 * flags part over to the timer lock.  Must not let interrupts in
  	 * while we are moving the lock.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
  	spin_lock_irqsave(&idr_lock, *flags);
31d928456   Oleg Nesterov   posix-timers: loc...
617
  	timr = idr_find(&posix_timers_id, (int)timer_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
619
  	if (timr) {
  		spin_lock(&timr->it_lock);
899921025   Oleg Nesterov   posix-timers: che...
620
  		if (timr->it_signal == current->signal) {
179394af7   Thomas Gleixner   posix-timers: fix...
621
  			spin_unlock(&idr_lock);
31d928456   Oleg Nesterov   posix-timers: loc...
622
623
624
625
626
  			return timr;
  		}
  		spin_unlock(&timr->it_lock);
  	}
  	spin_unlock_irqrestore(&idr_lock, *flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627

31d928456   Oleg Nesterov   posix-timers: loc...
628
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  }
  
  /*
   * Get the time remaining on a POSIX.1b interval timer.  This function
   * is ALWAYS called with spin_lock_irq on the timer, thus it must not
   * mess with irq.
   *
   * We have a couple of messes to clean up here.  First there is the case
   * of a timer that has a requeue pending.  These timers should appear to
   * be in the timer list with an expiry as if we were to requeue them
   * now.
   *
   * The second issue is the SIGEV_NONE timer which may be active but is
   * not really ever put in the timer list (to save system resources).
   * This timer may be expired, and if so, we will do it here.  Otherwise
   * it is the same as a requeue pending timer WRT to what we should
   * report.
   */
  static void
  common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
  {
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
650
  	ktime_t now, remaining, iv;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
651
  	struct hrtimer *timer = &timr->it.real.timer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
653
  	memset(cur_setting, 0, sizeof(struct itimerspec));
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
654

3b98a5328   Roman Zippel   [PATCH] hrtimers:...
655
  	iv = timr->it.real.interval;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
656
  	/* interval timer ? */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
657
658
659
660
  	if (iv.tv64)
  		cur_setting->it_interval = ktime_to_timespec(iv);
  	else if (!hrtimer_active(timer) &&
  		 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
661
  		return;
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
662
663
  
  	now = timer->base->get_time();
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
664
  	/*
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
665
666
667
  	 * When a requeue is pending or this is a SIGEV_NONE
  	 * timer move the expiry time forward by intervals, so
  	 * expiry is > now.
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
668
  	 */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
669
670
  	if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
  	    (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
4d672e7ac   Davide Libenzi   timerfd: new time...
671
  		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
672

cc584b213   Arjan van de Ven   hrtimer: convert ...
673
  	remaining = ktime_sub(hrtimer_get_expires(timer), now);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
674
  	/* Return 0 only, when the timer is expired and not pending */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
675
676
677
678
679
680
681
682
  	if (remaining.tv64 <= 0) {
  		/*
  		 * A single shot SIGEV_NONE timer must return 0, when
  		 * it is expired !
  		 */
  		if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
  			cur_setting->it_value.tv_nsec = 1;
  	} else
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
683
  		cur_setting->it_value = ktime_to_timespec(remaining);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
685
686
  }
  
  /* Get the time remaining on a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
687
688
  SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
  		struct itimerspec __user *, setting)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  	struct itimerspec cur_setting;
a7319fa25   Thomas Gleixner   posix-timers: Con...
691
692
  	struct k_itimer *timr;
  	struct k_clock *kc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
  	unsigned long flags;
a7319fa25   Thomas Gleixner   posix-timers: Con...
694
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
695
696
697
698
  
  	timr = lock_timer(timer_id, &flags);
  	if (!timr)
  		return -EINVAL;
a7319fa25   Thomas Gleixner   posix-timers: Con...
699
700
701
702
703
  	kc = clockid_to_kclock(timr->it_clock);
  	if (WARN_ON_ONCE(!kc || !kc->timer_get))
  		ret = -EINVAL;
  	else
  		kc->timer_get(timr, &cur_setting);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
  
  	unlock_timer(timr, flags);
a7319fa25   Thomas Gleixner   posix-timers: Con...
706
  	if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
  		return -EFAULT;
a7319fa25   Thomas Gleixner   posix-timers: Con...
708
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
710

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
712
713
714
715
716
717
718
719
  /*
   * Get the number of overruns of a POSIX.1b interval timer.  This is to
   * be the overrun of the timer last delivered.  At the same time we are
   * accumulating overruns on the next timer.  The overrun is frozen when
   * the signal is delivered, either at the notify time (if the info block
   * is not queued) or at the actual delivery time (as we are informed by
   * the call back to do_schedule_next_timer().  So all we need to do is
   * to pick up the frozen overrun.
   */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
720
  SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
722
723
  {
  	struct k_itimer *timr;
  	int overrun;
5ba253313   Al Viro   more low-hanging ...
724
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
725
726
727
728
729
730
731
732
733
734
  
  	timr = lock_timer(timer_id, &flags);
  	if (!timr)
  		return -EINVAL;
  
  	overrun = timr->it_overrun_last;
  	unlock_timer(timr, flags);
  
  	return overrun;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
736
737
  
  /* Set a POSIX.1b interval timer. */
  /* timr->it_lock is taken. */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
738
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
740
741
  common_timer_set(struct k_itimer *timr, int flags,
  		 struct itimerspec *new_setting, struct itimerspec *old_setting)
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
742
  	struct hrtimer *timer = &timr->it.real.timer;
7978672c4   George Anzinger   [PATCH] hrtimers:...
743
  	enum hrtimer_mode mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
746
747
748
  
  	if (old_setting)
  		common_timer_get(timr, old_setting);
  
  	/* disable the timer */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
749
  	timr->it.real.interval.tv64 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
753
  	/*
  	 * careful here.  If smp we could be in the "fire" routine which will
  	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
  	 */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
754
  	if (hrtimer_try_to_cancel(timer) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
  		return TIMER_RETRY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
757
758
759
  
  	timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
  		~REQUEUE_PENDING;
  	timr->it_overrun_last = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
761
762
763
  	/* switch off the timer when it_value is zero */
  	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
765
  	mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
7978672c4   George Anzinger   [PATCH] hrtimers:...
766
  	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
7978672c4   George Anzinger   [PATCH] hrtimers:...
767
  	timr->it.real.timer.function = posix_timer_fn;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
768

cc584b213   Arjan van de Ven   hrtimer: convert ...
769
  	hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value));
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
770
771
772
773
774
  
  	/* Convert interval */
  	timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
  
  	/* SIGEV_NONE timers are not queued ! See common_timer_get */
952bbc87f   Thomas Gleixner   [PATCH] hrtimers:...
775
776
  	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
  		/* Setup correct expiry time for relative timers */
5a7780e72   Thomas Gleixner   hrtimer: check re...
777
  		if (mode == HRTIMER_MODE_REL) {
cc584b213   Arjan van de Ven   hrtimer: convert ...
778
  			hrtimer_add_expires(timer, timer->base->get_time());
5a7780e72   Thomas Gleixner   hrtimer: check re...
779
  		}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
780
  		return 0;
952bbc87f   Thomas Gleixner   [PATCH] hrtimers:...
781
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
782

cc584b213   Arjan van de Ven   hrtimer: convert ...
783
  	hrtimer_start_expires(timer, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
785
786
787
  	return 0;
  }
  
  /* Set a POSIX.1b interval timer */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
788
789
790
  SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
  		const struct itimerspec __user *, new_setting,
  		struct itimerspec __user *, old_setting)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
792
793
794
  {
  	struct k_itimer *timr;
  	struct itimerspec new_spec, old_spec;
  	int error = 0;
5ba253313   Al Viro   more low-hanging ...
795
  	unsigned long flag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  	struct itimerspec *rtn = old_setting ? &old_spec : NULL;
27722df16   Thomas Gleixner   posix-timers: Con...
797
  	struct k_clock *kc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
799
800
801
802
803
  
  	if (!new_setting)
  		return -EINVAL;
  
  	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
  		return -EFAULT;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
804
805
  	if (!timespec_valid(&new_spec.it_interval) ||
  	    !timespec_valid(&new_spec.it_value))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
807
808
809
810
  		return -EINVAL;
  retry:
  	timr = lock_timer(timer_id, &flag);
  	if (!timr)
  		return -EINVAL;
27722df16   Thomas Gleixner   posix-timers: Con...
811
812
813
814
815
  	kc = clockid_to_kclock(timr->it_clock);
  	if (WARN_ON_ONCE(!kc || !kc->timer_set))
  		error = -EINVAL;
  	else
  		error = kc->timer_set(timr, flags, &new_spec, rtn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
816
817
818
819
820
821
  
  	unlock_timer(timr, flag);
  	if (error == TIMER_RETRY) {
  		rtn = NULL;	// We already got the old time...
  		goto retry;
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
822
823
  	if (old_setting && !error &&
  	    copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
825
826
827
  		error = -EFAULT;
  
  	return error;
  }
6761c6702   Thomas Gleixner   posix-timers: Con...
828
  static int common_timer_del(struct k_itimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
830
  	timer->it.real.interval.tv64 = 0;
f972be33c   Oleg Nesterov   [PATCH] posix-tim...
831

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
832
  	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  		return TIMER_RETRY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
835
836
837
838
  	return 0;
  }
  
  static inline int timer_delete_hook(struct k_itimer *timer)
  {
6761c6702   Thomas Gleixner   posix-timers: Con...
839
840
841
842
843
  	struct k_clock *kc = clockid_to_kclock(timer->it_clock);
  
  	if (WARN_ON_ONCE(!kc || !kc->timer_del))
  		return -EINVAL;
  	return kc->timer_del(timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
846
  }
  
  /* Delete a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
847
  SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
849
  {
  	struct k_itimer *timer;
5ba253313   Al Viro   more low-hanging ...
850
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
  retry_delete:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
855
  	timer = lock_timer(timer_id, &flags);
  	if (!timer)
  		return -EINVAL;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
856
  	if (timer_delete_hook(timer) == TIMER_RETRY) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
858
859
  		unlock_timer(timer, flags);
  		goto retry_delete;
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
860

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
862
863
864
865
866
867
  	spin_lock(&current->sighand->siglock);
  	list_del(&timer->list);
  	spin_unlock(&current->sighand->siglock);
  	/*
  	 * This keeps any tasks waiting on the spin lock from thinking
  	 * they got something (see the lock code above).
  	 */
899921025   Oleg Nesterov   posix-timers: che...
868
  	timer->it_signal = NULL;
4b7a13042   Oleg Nesterov   posix timers: tim...
869

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
871
872
873
  	unlock_timer(timer, flags);
  	release_posix_timer(timer, IT_ID_SET);
  	return 0;
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
874

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
876
877
  /*
   * return timer owned by the process, used by exit_itimers
   */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
878
  static void itimer_delete(struct k_itimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
  {
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
  retry_delete:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  	spin_lock_irqsave(&timer->it_lock, flags);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
883
  	if (timer_delete_hook(timer) == TIMER_RETRY) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884
885
886
  		unlock_timer(timer, flags);
  		goto retry_delete;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
888
889
890
891
  	list_del(&timer->list);
  	/*
  	 * This keeps any tasks waiting on the spin lock from thinking
  	 * they got something (see the lock code above).
  	 */
899921025   Oleg Nesterov   posix-timers: che...
892
  	timer->it_signal = NULL;
4b7a13042   Oleg Nesterov   posix timers: tim...
893

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
895
896
897
898
  	unlock_timer(timer, flags);
  	release_posix_timer(timer, IT_ID_SET);
  }
  
  /*
25f407f0b   Roland McGrath   [PATCH] Call exit...
899
   * This is called by do_exit or de_thread, only when there are no more
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
901
902
903
904
905
906
907
908
909
910
   * references to the shared signal_struct.
   */
  void exit_itimers(struct signal_struct *sig)
  {
  	struct k_itimer *tmr;
  
  	while (!list_empty(&sig->posix_timers)) {
  		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
  		itimer_delete(tmr);
  	}
  }
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
911
912
  SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
  		const struct timespec __user *, tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  {
26f9a4796   Thomas Gleixner   posix-timers: Con...
914
  	struct k_clock *kc = clockid_to_kclock(which_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
  	struct timespec new_tp;
26f9a4796   Thomas Gleixner   posix-timers: Con...
916
  	if (!kc || !kc->clock_set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
  		return -EINVAL;
26f9a4796   Thomas Gleixner   posix-timers: Con...
918

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
920
  	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
  		return -EFAULT;
26f9a4796   Thomas Gleixner   posix-timers: Con...
921
  	return kc->clock_set(which_clock, &new_tp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
  }
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
923
924
  SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
  		struct timespec __user *,tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
  {
422857776   Thomas Gleixner   posix-timers: Con...
926
  	struct k_clock *kc = clockid_to_kclock(which_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
928
  	struct timespec kernel_tp;
  	int error;
422857776   Thomas Gleixner   posix-timers: Con...
929
  	if (!kc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
930
  		return -EINVAL;
422857776   Thomas Gleixner   posix-timers: Con...
931
932
  
  	error = kc->clock_get(which_clock, &kernel_tp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
933
934
935
936
  	if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
  		error = -EFAULT;
  
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  }
f1f1d5ebd   Richard Cochran   posix-timers: Int...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
  SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
  		struct timex __user *, utx)
  {
  	struct k_clock *kc = clockid_to_kclock(which_clock);
  	struct timex ktx;
  	int err;
  
  	if (!kc)
  		return -EINVAL;
  	if (!kc->clock_adj)
  		return -EOPNOTSUPP;
  
  	if (copy_from_user(&ktx, utx, sizeof(ktx)))
  		return -EFAULT;
  
  	err = kc->clock_adj(which_clock, &ktx);
  
  	if (!err && copy_to_user(utx, &ktx, sizeof(ktx)))
  		return -EFAULT;
  
  	return err;
  }
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
960
961
  SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
  		struct timespec __user *, tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
  {
e5e542eea   Thomas Gleixner   posix-timers: Con...
963
  	struct k_clock *kc = clockid_to_kclock(which_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
964
965
  	struct timespec rtn_tp;
  	int error;
e5e542eea   Thomas Gleixner   posix-timers: Con...
966
  	if (!kc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
  		return -EINVAL;
e5e542eea   Thomas Gleixner   posix-timers: Con...
968
  	error = kc->clock_getres(which_clock, &rtn_tp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969

e5e542eea   Thomas Gleixner   posix-timers: Con...
970
  	if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
  		error = -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
973
974
  
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  /*
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
976
977
978
979
980
   * nanosleep for monotonic and realtime clocks
   */
  static int common_nsleep(const clockid_t which_clock, int flags,
  			 struct timespec *tsave, struct timespec __user *rmtp)
  {
080344b98   Oleg Nesterov   hrtimer: fix *rmt...
981
982
983
  	return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
  				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
  				 which_clock);
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
984
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985

362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
986
987
988
  SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
  		const struct timespec __user *, rqtp,
  		struct timespec __user *, rmtp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
  {
a5cd28801   Thomas Gleixner   posix-timers: Con...
990
  	struct k_clock *kc = clockid_to_kclock(which_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991
  	struct timespec t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992

a5cd28801   Thomas Gleixner   posix-timers: Con...
993
  	if (!kc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
994
  		return -EINVAL;
a5cd28801   Thomas Gleixner   posix-timers: Con...
995
996
  	if (!kc->nsleep)
  		return -ENANOSLEEP_NOTSUP;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
999
  
  	if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
  		return -EFAULT;
5f82b2b77   Thomas Gleixner   [PATCH] hrtimer: ...
1000
  	if (!timespec_valid(&t))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1001
  		return -EINVAL;
a5cd28801   Thomas Gleixner   posix-timers: Con...
1002
  	return kc->nsleep(which_clock, flags, &t, rmtp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
  }
1711ef386   Toyo Abe   [PATCH] posix-tim...
1004
1005
  
  /*
1711ef386   Toyo Abe   [PATCH] posix-tim...
1006
1007
1008
   * This will restart clock_nanosleep. This is required only by
   * compat_clock_nanosleep_restart for now.
   */
59bd5bc24   Thomas Gleixner   posix-timers: Con...
1009
  long clock_nanosleep_restart(struct restart_block *restart_block)
1711ef386   Toyo Abe   [PATCH] posix-tim...
1010
  {
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1011
  	clockid_t which_clock = restart_block->nanosleep.index;
59bd5bc24   Thomas Gleixner   posix-timers: Con...
1012
1013
1014
1015
  	struct k_clock *kc = clockid_to_kclock(which_clock);
  
  	if (WARN_ON_ONCE(!kc || !kc->nsleep_restart))
  		return -EINVAL;
1711ef386   Toyo Abe   [PATCH] posix-tim...
1016

59bd5bc24   Thomas Gleixner   posix-timers: Con...
1017
  	return kc->nsleep_restart(restart_block);
1711ef386   Toyo Abe   [PATCH] posix-tim...
1018
  }