Blame view

kernel/posix-cpu-timers.c 42.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   * Implement CPU time clocks for the POSIX clock interface.
   */
  
  #include <linux/sched.h>
  #include <linux/posix-timers.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
  #include <linux/errno.h>
f8bd2258e   Roman Zippel   remove div_long_l...
8
9
  #include <linux/math64.h>
  #include <asm/uaccess.h>
bb34d92f6   Frank Mayhar   timers: fix itime...
10
  #include <linux/kernel_stat.h>
3f0a525eb   Xiao Guangrong   itimers: Add trac...
11
  #include <trace/events/timer.h>
613370549   Nick Kossifidis   random: Mix cputi...
12
  #include <linux/random.h>
a85721601   Frederic Weisbecker   posix_timers: Kic...
13
14
  #include <linux/tick.h>
  #include <linux/workqueue.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15

f06febc96   Frank Mayhar   timers: fix itime...
16
  /*
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
17
18
19
20
   * Called after updating RLIMIT_CPU to run cpu timer and update
   * tsk->signal->cputime_expires expiration cache if necessary. Needs
   * siglock protection since other code may update expiration cache as
   * well.
f06febc96   Frank Mayhar   timers: fix itime...
21
   */
5ab46b345   Jiri Slaby   rlimits: add task...
22
  void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new)
f06febc96   Frank Mayhar   timers: fix itime...
23
  {
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
24
  	cputime_t cputime = secs_to_cputime(rlim_new);
f06febc96   Frank Mayhar   timers: fix itime...
25

5ab46b345   Jiri Slaby   rlimits: add task...
26
27
28
  	spin_lock_irq(&task->sighand->siglock);
  	set_process_cpu_timer(task, CPUCLOCK_PROF, &cputime, NULL);
  	spin_unlock_irq(&task->sighand->siglock);
f06febc96   Frank Mayhar   timers: fix itime...
29
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
30
  static int check_clock(const clockid_t which_clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
39
40
  {
  	int error = 0;
  	struct task_struct *p;
  	const pid_t pid = CPUCLOCK_PID(which_clock);
  
  	if (CPUCLOCK_WHICH(which_clock) >= CPUCLOCK_MAX)
  		return -EINVAL;
  
  	if (pid == 0)
  		return 0;
c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
41
  	rcu_read_lock();
8dc86af00   Pavel Emelyanov   Use find_task_by_...
42
  	p = find_task_by_vpid(pid);
bac0abd61   Pavel Emelyanov   Isolate some expl...
43
  	if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
44
  		   same_thread_group(p, current) : has_group_leader_pid(p))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
  		error = -EINVAL;
  	}
c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
47
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
51
52
  
  	return error;
  }
  
  static inline union cpu_time_count
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
53
  timespec_to_sample(const clockid_t which_clock, const struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
  {
  	union cpu_time_count ret;
  	ret.sched = 0;		/* high half always zero when .cpu used */
  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
ee500f274   Oleg Nesterov   [PATCH] fix 32bit...
58
  		ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
  	} else {
  		ret.cpu = timespec_to_cputime(tp);
  	}
  	return ret;
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
64
  static void sample_to_timespec(const clockid_t which_clock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  			       union cpu_time_count cpu,
  			       struct timespec *tp)
  {
f8bd2258e   Roman Zippel   remove div_long_l...
68
69
70
  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED)
  		*tp = ns_to_timespec(cpu.sched);
  	else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  		cputime_to_timespec(cpu.cpu, tp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
73
  static inline int cpu_time_before(const clockid_t which_clock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
  				  union cpu_time_count now,
  				  union cpu_time_count then)
  {
  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
  		return now.sched < then.sched;
  	}  else {
648616343   Martin Schwidefsky   [S390] cputime: a...
80
  		return now.cpu < then.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
  	}
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
83
  static inline void cpu_time_add(const clockid_t which_clock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
89
  				union cpu_time_count *acc,
  			        union cpu_time_count val)
  {
  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
  		acc->sched += val.sched;
  	}  else {
648616343   Martin Schwidefsky   [S390] cputime: a...
90
  		acc->cpu += val.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
  	}
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
93
  static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
99
  						union cpu_time_count a,
  						union cpu_time_count b)
  {
  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
  		a.sched -= b.sched;
  	}  else {
648616343   Martin Schwidefsky   [S390] cputime: a...
100
  		a.cpu -= b.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
107
108
  	}
  	return a;
  }
  
  /*
   * Update expiry time from increment, and increase overrun count,
   * given the current clock sample.
   */
7a4ed937a   Oleg Nesterov   [PATCH] Fix cpu t...
109
  static void bump_cpu_timer(struct k_itimer *timer,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  				  union cpu_time_count now)
  {
  	int i;
  
  	if (timer->it.cpu.incr.sched == 0)
  		return;
  
  	if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {
  		unsigned long long delta, incr;
  
  		if (now.sched < timer->it.cpu.expires.sched)
  			return;
  		incr = timer->it.cpu.incr.sched;
  		delta = now.sched + incr - timer->it.cpu.expires.sched;
  		/* Don't use (incr*2 < delta), incr*2 might overflow. */
  		for (i = 0; incr < delta - incr; i++)
  			incr = incr << 1;
  		for (; i >= 0; incr >>= 1, i--) {
7a4ed937a   Oleg Nesterov   [PATCH] Fix cpu t...
128
  			if (delta < incr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
  				continue;
  			timer->it.cpu.expires.sched += incr;
  			timer->it_overrun += 1 << i;
  			delta -= incr;
  		}
  	} else {
  		cputime_t delta, incr;
648616343   Martin Schwidefsky   [S390] cputime: a...
136
  		if (now.cpu < timer->it.cpu.expires.cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
  			return;
  		incr = timer->it.cpu.incr.cpu;
648616343   Martin Schwidefsky   [S390] cputime: a...
139
  		delta = now.cpu + incr - timer->it.cpu.expires.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  		/* Don't use (incr*2 < delta), incr*2 might overflow. */
648616343   Martin Schwidefsky   [S390] cputime: a...
141
142
143
144
  		for (i = 0; incr < delta - incr; i++)
  			     incr += incr;
  		for (; i >= 0; incr = incr >> 1, i--) {
  			if (delta < incr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  				continue;
648616343   Martin Schwidefsky   [S390] cputime: a...
146
  			timer->it.cpu.expires.cpu += incr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  			timer->it_overrun += 1 << i;
648616343   Martin Schwidefsky   [S390] cputime: a...
148
  			delta -= incr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
  		}
  	}
  }
555347f6c   Frederic Weisbecker   posix_timers: New...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  /**
   * task_cputime_zero - Check a task_cputime struct for all zero fields.
   *
   * @cputime:	The struct to compare.
   *
   * Checks @cputime to see if all fields are zero.  Returns true if all fields
   * are zero, false if any field is nonzero.
   */
  static inline int task_cputime_zero(const struct task_cputime *cputime)
  {
  	if (!cputime->utime && !cputime->stime && !cputime->sum_exec_runtime)
  		return 1;
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
  static inline cputime_t prof_ticks(struct task_struct *p)
  {
6fac4829c   Frederic Weisbecker   cputime: Use acce...
168
169
170
171
172
  	cputime_t utime, stime;
  
  	task_cputime(p, &utime, &stime);
  
  	return utime + stime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
175
  }
  static inline cputime_t virt_ticks(struct task_struct *p)
  {
6fac4829c   Frederic Weisbecker   cputime: Use acce...
176
177
178
179
180
  	cputime_t utime;
  
  	task_cputime(p, &utime, NULL);
  
  	return utime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182

bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
183
184
  static int
  posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  {
  	int error = check_clock(which_clock);
  	if (!error) {
  		tp->tv_sec = 0;
  		tp->tv_nsec = ((NSEC_PER_SEC + HZ - 1) / HZ);
  		if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
  			/*
  			 * If sched_clock is using a cycle counter, we
  			 * don't have any idea of its true resolution
  			 * exported, but it is much more than 1s/HZ.
  			 */
  			tp->tv_nsec = 1;
  		}
  	}
  	return error;
  }
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
201
202
  static int
  posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  {
  	/*
  	 * You can never reset a CPU clock, but we check for other errors
  	 * in the call before failing with EPERM.
  	 */
  	int error = check_clock(which_clock);
  	if (error == 0) {
  		error = -EPERM;
  	}
  	return error;
  }
  
  
  /*
   * Sample a per-thread clock for the given task.
   */
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
219
  static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
222
223
224
225
226
227
228
229
230
231
  			    union cpu_time_count *cpu)
  {
  	switch (CPUCLOCK_WHICH(which_clock)) {
  	default:
  		return -EINVAL;
  	case CPUCLOCK_PROF:
  		cpu->cpu = prof_ticks(p);
  		break;
  	case CPUCLOCK_VIRT:
  		cpu->cpu = virt_ticks(p);
  		break;
  	case CPUCLOCK_SCHED:
c5f8d9958   Hidetoshi Seto   posixtimers, sche...
232
  		cpu->sched = task_sched_runtime(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
  		break;
  	}
  	return 0;
  }
4da94d49b   Peter Zijlstra   timers: fix TIMER...
237
238
  static void update_gt_cputime(struct task_cputime *a, struct task_cputime *b)
  {
648616343   Martin Schwidefsky   [S390] cputime: a...
239
  	if (b->utime > a->utime)
4da94d49b   Peter Zijlstra   timers: fix TIMER...
240
  		a->utime = b->utime;
648616343   Martin Schwidefsky   [S390] cputime: a...
241
  	if (b->stime > a->stime)
4da94d49b   Peter Zijlstra   timers: fix TIMER...
242
243
244
245
246
247
248
249
250
251
252
  		a->stime = b->stime;
  
  	if (b->sum_exec_runtime > a->sum_exec_runtime)
  		a->sum_exec_runtime = b->sum_exec_runtime;
  }
  
  void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
  {
  	struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
  	struct task_cputime sum;
  	unsigned long flags;
4da94d49b   Peter Zijlstra   timers: fix TIMER...
253
  	if (!cputimer->running) {
4da94d49b   Peter Zijlstra   timers: fix TIMER...
254
255
256
257
258
259
260
  		/*
  		 * The POSIX timer interface allows for absolute time expiry
  		 * values through the TIMER_ABSTIME flag, therefore we have
  		 * to synchronize the timer to the clock every time we start
  		 * it.
  		 */
  		thread_group_cputime(tsk, &sum);
3cfef9524   Linus Torvalds   Merge branch 'cor...
261
  		raw_spin_lock_irqsave(&cputimer->lock, flags);
bcd5cff72   Peter Zijlstra   cputimer: Cure lo...
262
  		cputimer->running = 1;
4da94d49b   Peter Zijlstra   timers: fix TIMER...
263
  		update_gt_cputime(&cputimer->cputime, &sum);
bcd5cff72   Peter Zijlstra   cputimer: Cure lo...
264
  	} else
3cfef9524   Linus Torvalds   Merge branch 'cor...
265
  		raw_spin_lock_irqsave(&cputimer->lock, flags);
4da94d49b   Peter Zijlstra   timers: fix TIMER...
266
  	*times = cputimer->cputime;
ee30a7b2f   Thomas Gleixner   locking, sched: A...
267
  	raw_spin_unlock_irqrestore(&cputimer->lock, flags);
4da94d49b   Peter Zijlstra   timers: fix TIMER...
268
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
271
  /*
   * Sample a process (thread group) clock for the given group_leader task.
   * Must be called with tasklist_lock held for reading.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
   */
bb34d92f6   Frank Mayhar   timers: fix itime...
273
274
275
  static int cpu_clock_sample_group(const clockid_t which_clock,
  				  struct task_struct *p,
  				  union cpu_time_count *cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  {
f06febc96   Frank Mayhar   timers: fix itime...
277
  	struct task_cputime cputime;
eccdaeafa   Petr Tesarik   posix-cpu-timers:...
278
  	switch (CPUCLOCK_WHICH(which_clock)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
281
  	default:
  		return -EINVAL;
  	case CPUCLOCK_PROF:
c5f8d9958   Hidetoshi Seto   posixtimers, sche...
282
  		thread_group_cputime(p, &cputime);
648616343   Martin Schwidefsky   [S390] cputime: a...
283
  		cpu->cpu = cputime.utime + cputime.stime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
  		break;
  	case CPUCLOCK_VIRT:
c5f8d9958   Hidetoshi Seto   posixtimers, sche...
286
  		thread_group_cputime(p, &cputime);
f06febc96   Frank Mayhar   timers: fix itime...
287
  		cpu->cpu = cputime.utime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
  		break;
  	case CPUCLOCK_SCHED:
d670ec131   Peter Zijlstra   posix-cpu-timers:...
290
291
  		thread_group_cputime(p, &cputime);
  		cpu->sched = cputime.sum_exec_runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
  		break;
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296

bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
297
  static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  {
  	const pid_t pid = CPUCLOCK_PID(which_clock);
  	int error = -EINVAL;
  	union cpu_time_count rtn;
  
  	if (pid == 0) {
  		/*
  		 * Special case constant value for our own clocks.
  		 * We don't have to do any lookup to find ourselves.
  		 */
  		if (CPUCLOCK_PERTHREAD(which_clock)) {
  			/*
  			 * Sampling just ourselves we can do with no locking.
  			 */
  			error = cpu_clock_sample(which_clock,
  						 current, &rtn);
  		} else {
  			read_lock(&tasklist_lock);
  			error = cpu_clock_sample_group(which_clock,
  						       current, &rtn);
  			read_unlock(&tasklist_lock);
  		}
  	} else {
  		/*
  		 * Find the given PID, and validate that the caller
  		 * should be able to see it.
  		 */
  		struct task_struct *p;
1f2ea0837   Paul E. McKenney   [PATCH] posix tim...
326
  		rcu_read_lock();
8dc86af00   Pavel Emelyanov   Use find_task_by_...
327
  		p = find_task_by_vpid(pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
  		if (p) {
  			if (CPUCLOCK_PERTHREAD(which_clock)) {
bac0abd61   Pavel Emelyanov   Isolate some expl...
330
  				if (same_thread_group(p, current)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
  					error = cpu_clock_sample(which_clock,
  								 p, &rtn);
  				}
1f2ea0837   Paul E. McKenney   [PATCH] posix tim...
334
335
  			} else {
  				read_lock(&tasklist_lock);
d30fda355   Oleg Nesterov   posix-cpu-timers:...
336
  				if (thread_group_leader(p) && p->sighand) {
1f2ea0837   Paul E. McKenney   [PATCH] posix tim...
337
338
339
340
341
  					error =
  					    cpu_clock_sample_group(which_clock,
  							           p, &rtn);
  				}
  				read_unlock(&tasklist_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
  			}
  		}
1f2ea0837   Paul E. McKenney   [PATCH] posix tim...
344
  		rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
347
348
349
350
351
352
353
354
355
  	}
  
  	if (error)
  		return error;
  	sample_to_timespec(which_clock, rtn, tp);
  	return 0;
  }
  
  
  /*
   * Validate the clockid_t for a new CPU-clock timer, and initialize the timer.
ba5ea951d   Stanislaw Gruszka   posix-cpu-timers:...
356
357
   * This is called from sys_timer_create() and do_cpu_nanosleep() with the
   * new timer already all-zeros initialized.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
   */
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
359
  static int posix_cpu_timer_create(struct k_itimer *new_timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
365
366
367
368
  {
  	int ret = 0;
  	const pid_t pid = CPUCLOCK_PID(new_timer->it_clock);
  	struct task_struct *p;
  
  	if (CPUCLOCK_WHICH(new_timer->it_clock) >= CPUCLOCK_MAX)
  		return -EINVAL;
  
  	INIT_LIST_HEAD(&new_timer->it.cpu.entry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369

c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
370
  	rcu_read_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
372
373
374
  	if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {
  		if (pid == 0) {
  			p = current;
  		} else {
8dc86af00   Pavel Emelyanov   Use find_task_by_...
375
  			p = find_task_by_vpid(pid);
bac0abd61   Pavel Emelyanov   Isolate some expl...
376
  			if (p && !same_thread_group(p, current))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
380
381
382
  				p = NULL;
  		}
  	} else {
  		if (pid == 0) {
  			p = current->group_leader;
  		} else {
8dc86af00   Pavel Emelyanov   Use find_task_by_...
383
  			p = find_task_by_vpid(pid);
c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
384
  			if (p && !has_group_leader_pid(p))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
386
387
388
389
390
391
392
393
  				p = NULL;
  		}
  	}
  	new_timer->it.cpu.task = p;
  	if (p) {
  		get_task_struct(p);
  	} else {
  		ret = -EINVAL;
  	}
c0deae8c9   Sergey Senozhatsky   posix-cpu-timers:...
394
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
401
402
403
404
  
  	return ret;
  }
  
  /*
   * Clean up a CPU-clock timer that is about to be destroyed.
   * This is called from timer deletion with the timer already locked.
   * If we return TIMER_RETRY, it's necessary to release the timer's lock
   * and try again.  (This happens when the timer is in the middle of firing.)
   */
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
405
  static int posix_cpu_timer_del(struct k_itimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
  {
  	struct task_struct *p = timer->it.cpu.task;
108150ea7   Oleg Nesterov   [PATCH] posix-tim...
408
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409

108150ea7   Oleg Nesterov   [PATCH] posix-tim...
410
  	if (likely(p != NULL)) {
9465bee86   Linus Torvalds   Revert "Fix cpu t...
411
  		read_lock(&tasklist_lock);
d30fda355   Oleg Nesterov   posix-cpu-timers:...
412
  		if (unlikely(p->sighand == NULL)) {
9465bee86   Linus Torvalds   Revert "Fix cpu t...
413
414
415
416
417
418
  			/*
  			 * We raced with the reaping of the task.
  			 * The deletion should have cleared us off the list.
  			 */
  			BUG_ON(!list_empty(&timer->it.cpu.entry));
  		} else {
9465bee86   Linus Torvalds   Revert "Fix cpu t...
419
  			spin_lock(&p->sighand->siglock);
108150ea7   Oleg Nesterov   [PATCH] posix-tim...
420
421
422
423
  			if (timer->it.cpu.firing)
  				ret = TIMER_RETRY;
  			else
  				list_del(&timer->it.cpu.entry);
9465bee86   Linus Torvalds   Revert "Fix cpu t...
424
425
426
  			spin_unlock(&p->sighand->siglock);
  		}
  		read_unlock(&tasklist_lock);
108150ea7   Oleg Nesterov   [PATCH] posix-tim...
427
428
429
  
  		if (!ret)
  			put_task_struct(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431

108150ea7   Oleg Nesterov   [PATCH] posix-tim...
432
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
434
435
436
437
438
439
440
441
442
  }
  
  /*
   * Clean out CPU timers still ticking when a thread exited.  The task
   * pointer is cleared, and the expiry time is replaced with the residual
   * time for later timer_gettime calls to return.
   * This must be called with the siglock held.
   */
  static void cleanup_timers(struct list_head *head,
  			   cputime_t utime, cputime_t stime,
41b86e9c5   Ingo Molnar   sched: make posix...
443
  			   unsigned long long sum_exec_runtime)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
  {
  	struct cpu_timer_list *timer, *next;
648616343   Martin Schwidefsky   [S390] cputime: a...
446
  	cputime_t ptime = utime + stime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
  
  	list_for_each_entry_safe(timer, next, head, entry) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  		list_del_init(&timer->entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
450
451
  		if (timer->expires.cpu < ptime) {
  			timer->expires.cpu = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
  		} else {
648616343   Martin Schwidefsky   [S390] cputime: a...
453
  			timer->expires.cpu -= ptime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
456
457
458
  		}
  	}
  
  	++head;
  	list_for_each_entry_safe(timer, next, head, entry) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  		list_del_init(&timer->entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
460
461
  		if (timer->expires.cpu < utime) {
  			timer->expires.cpu = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  		} else {
648616343   Martin Schwidefsky   [S390] cputime: a...
463
  			timer->expires.cpu -= utime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
467
468
  		}
  	}
  
  	++head;
  	list_for_each_entry_safe(timer, next, head, entry) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
  		list_del_init(&timer->entry);
41b86e9c5   Ingo Molnar   sched: make posix...
470
  		if (timer->expires.sched < sum_exec_runtime) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
  			timer->expires.sched = 0;
  		} else {
41b86e9c5   Ingo Molnar   sched: make posix...
473
  			timer->expires.sched -= sum_exec_runtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
475
476
477
478
479
480
481
482
483
484
  		}
  	}
  }
  
  /*
   * These are both called with the siglock held, when the current thread
   * is being reaped.  When the final (leader) thread in the group is reaped,
   * posix_cpu_timers_exit_group will be called after posix_cpu_timers_exit.
   */
  void posix_cpu_timers_exit(struct task_struct *tsk)
  {
6fac4829c   Frederic Weisbecker   cputime: Use acce...
485
  	cputime_t utime, stime;
613370549   Nick Kossifidis   random: Mix cputi...
486
487
  	add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
  						sizeof(unsigned long long));
6fac4829c   Frederic Weisbecker   cputime: Use acce...
488
  	task_cputime(tsk, &utime, &stime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  	cleanup_timers(tsk->cpu_timers,
6fac4829c   Frederic Weisbecker   cputime: Use acce...
490
  		       utime, stime, tsk->se.sum_exec_runtime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
494
  
  }
  void posix_cpu_timers_exit_group(struct task_struct *tsk)
  {
17d42c1c4   Stanislaw Gruszka   posix_cpu_timers_...
495
  	struct signal_struct *const sig = tsk->signal;
6fac4829c   Frederic Weisbecker   cputime: Use acce...
496
  	cputime_t utime, stime;
ca531a0a5   Oleg Nesterov   [PATCH] posix-tim...
497

6fac4829c   Frederic Weisbecker   cputime: Use acce...
498
  	task_cputime(tsk, &utime, &stime);
f06febc96   Frank Mayhar   timers: fix itime...
499
  	cleanup_timers(tsk->signal->cpu_timers,
6fac4829c   Frederic Weisbecker   cputime: Use acce...
500
  		       utime + sig->utime, stime + sig->stime,
17d42c1c4   Stanislaw Gruszka   posix_cpu_timers_...
501
  		       tsk->se.sum_exec_runtime + sig->sum_sched_runtime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
504
505
506
507
508
509
510
511
512
513
514
515
  }
  
  static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
  {
  	/*
  	 * That's all for this thread or process.
  	 * We leave our residual in expires to be reported.
  	 */
  	put_task_struct(timer->it.cpu.task);
  	timer->it.cpu.task = NULL;
  	timer->it.cpu.expires = cpu_time_sub(timer->it_clock,
  					     timer->it.cpu.expires,
  					     now);
  }
d1e3b6d19   Stanislaw Gruszka   itimers: Simplify...
516
517
  static inline int expires_gt(cputime_t expires, cputime_t new_exp)
  {
648616343   Martin Schwidefsky   [S390] cputime: a...
518
  	return expires == 0 || expires > new_exp;
d1e3b6d19   Stanislaw Gruszka   itimers: Simplify...
519
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
  /*
   * Insert the timer on the appropriate list before any timers that
   * expire later.  This must be called with the tasklist_lock held
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
523
   * for reading, interrupts disabled and p->sighand->siglock taken.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
524
   */
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
525
  static void arm_timer(struct k_itimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
  {
  	struct task_struct *p = timer->it.cpu.task;
  	struct list_head *head, *listpos;
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
529
  	struct task_cputime *cputime_expires;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
  	struct cpu_timer_list *const nt = &timer->it.cpu;
  	struct cpu_timer_list *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532

5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
533
534
535
536
537
538
539
  	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
  		head = p->cpu_timers;
  		cputime_expires = &p->cputime_expires;
  	} else {
  		head = p->signal->cpu_timers;
  		cputime_expires = &p->signal->cputime_expires;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  	head += CPUCLOCK_WHICH(timer->it_clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  	listpos = head;
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
542
543
544
545
  	list_for_each_entry(next, head, entry) {
  		if (cpu_time_before(timer->it_clock, nt->expires, next->expires))
  			break;
  		listpos = &next->entry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
549
  	}
  	list_add(&nt->entry, listpos);
  
  	if (listpos == head) {
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
550
  		union cpu_time_count *exp = &nt->expires;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
  		/*
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
552
553
554
555
  		 * We are the new earliest-expiring POSIX 1.b timer, hence
  		 * need to update expiration cache. Take into account that
  		 * for process timers we share expiration cache with itimers
  		 * and RLIMIT_CPU and for thread timers with RLIMIT_RTTIME.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
  		 */
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
557
558
559
560
561
562
563
564
565
566
567
568
569
570
  		switch (CPUCLOCK_WHICH(timer->it_clock)) {
  		case CPUCLOCK_PROF:
  			if (expires_gt(cputime_expires->prof_exp, exp->cpu))
  				cputime_expires->prof_exp = exp->cpu;
  			break;
  		case CPUCLOCK_VIRT:
  			if (expires_gt(cputime_expires->virt_exp, exp->cpu))
  				cputime_expires->virt_exp = exp->cpu;
  			break;
  		case CPUCLOCK_SCHED:
  			if (cputime_expires->sched_exp == 0 ||
  			    cputime_expires->sched_exp > exp->sched)
  				cputime_expires->sched_exp = exp->sched;
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
575
576
577
578
579
  }
  
  /*
   * The timer is locked, fire it and arrange for its reload.
   */
  static void cpu_timer_fire(struct k_itimer *timer)
  {
1f169f84d   Stanislaw Gruszka   cpu-timers: Chang...
580
581
582
583
584
585
  	if ((timer->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
  		/*
  		 * User don't want any signal.
  		 */
  		timer->it.cpu.expires.sched = 0;
  	} else if (unlikely(timer->sigq == NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
  		/*
  		 * This a special case for clock_nanosleep,
  		 * not a normal timer from sys_timer_create.
  		 */
  		wake_up_process(timer->it_process);
  		timer->it.cpu.expires.sched = 0;
  	} else if (timer->it.cpu.incr.sched == 0) {
  		/*
  		 * One-shot timer.  Clear it as soon as it's fired.
  		 */
  		posix_timer_event(timer, 0);
  		timer->it.cpu.expires.sched = 0;
  	} else if (posix_timer_event(timer, ++timer->it_requeue_pending)) {
  		/*
  		 * The signal did not get queued because the signal
  		 * was ignored, so we won't get any callback to
  		 * reload the timer.  But we need to keep it
  		 * ticking in case the signal is deliverable next time.
  		 */
  		posix_cpu_timer_schedule(timer);
  	}
  }
  
  /*
3997ad317   Peter Zijlstra   timers: more cons...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
   * Sample a process (thread group) timer for the given group_leader task.
   * Must be called with tasklist_lock held for reading.
   */
  static int cpu_timer_sample_group(const clockid_t which_clock,
  				  struct task_struct *p,
  				  union cpu_time_count *cpu)
  {
  	struct task_cputime cputime;
  
  	thread_group_cputimer(p, &cputime);
  	switch (CPUCLOCK_WHICH(which_clock)) {
  	default:
  		return -EINVAL;
  	case CPUCLOCK_PROF:
648616343   Martin Schwidefsky   [S390] cputime: a...
624
  		cpu->cpu = cputime.utime + cputime.stime;
3997ad317   Peter Zijlstra   timers: more cons...
625
626
627
628
629
630
631
632
633
634
  		break;
  	case CPUCLOCK_VIRT:
  		cpu->cpu = cputime.utime;
  		break;
  	case CPUCLOCK_SCHED:
  		cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
  		break;
  	}
  	return 0;
  }
a85721601   Frederic Weisbecker   posix_timers: Kic...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  #ifdef CONFIG_NO_HZ_FULL
  static void nohz_kick_work_fn(struct work_struct *work)
  {
  	tick_nohz_full_kick_all();
  }
  
  static DECLARE_WORK(nohz_kick_work, nohz_kick_work_fn);
  
  /*
   * We need the IPIs to be sent from sane process context.
   * The posix cpu timers are always set with irqs disabled.
   */
  static void posix_cpu_timer_kick_nohz(void)
  {
  	schedule_work(&nohz_kick_work);
  }
555347f6c   Frederic Weisbecker   posix_timers: New...
651
652
653
654
  
  bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk)
  {
  	if (!task_cputime_zero(&tsk->cputime_expires))
6ac29178b   Frederic Weisbecker   posix_timers: Fix...
655
  		return false;
555347f6c   Frederic Weisbecker   posix_timers: New...
656
657
  
  	if (tsk->signal->cputimer.running)
6ac29178b   Frederic Weisbecker   posix_timers: Fix...
658
  		return false;
555347f6c   Frederic Weisbecker   posix_timers: New...
659

6ac29178b   Frederic Weisbecker   posix_timers: Fix...
660
  	return true;
555347f6c   Frederic Weisbecker   posix_timers: New...
661
  }
a85721601   Frederic Weisbecker   posix_timers: Kic...
662
663
664
  #else
  static inline void posix_cpu_timer_kick_nohz(void) { }
  #endif
3997ad317   Peter Zijlstra   timers: more cons...
665
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
667
668
669
670
   * Guts of sys_timer_settime for CPU timers.
   * This is called with the timer locked and interrupts disabled.
   * If we return TIMER_RETRY, it's necessary to release the timer's lock
   * and try again.  (This happens when the timer is in the middle of firing.)
   */
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
671
672
  static int posix_cpu_timer_set(struct k_itimer *timer, int flags,
  			       struct itimerspec *new, struct itimerspec *old)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
674
  {
  	struct task_struct *p = timer->it.cpu.task;
ae1a78eec   Stanislaw Gruszka   cpu-timers: Retur...
675
  	union cpu_time_count old_expires, new_expires, old_incr, val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  	int ret;
  
  	if (unlikely(p == NULL)) {
  		/*
  		 * Timer refers to a dead task's clock.
  		 */
  		return -ESRCH;
  	}
  
  	new_expires = timespec_to_sample(timer->it_clock, &new->it_value);
  
  	read_lock(&tasklist_lock);
  	/*
  	 * We need the tasklist_lock to protect against reaping that
d30fda355   Oleg Nesterov   posix-cpu-timers:...
690
  	 * clears p->sighand.  If p has just been reaped, we can no
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
  	 * longer get any information about it at all.
  	 */
d30fda355   Oleg Nesterov   posix-cpu-timers:...
693
  	if (unlikely(p->sighand == NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
696
697
698
699
700
701
702
703
  		read_unlock(&tasklist_lock);
  		put_task_struct(p);
  		timer->it.cpu.task = NULL;
  		return -ESRCH;
  	}
  
  	/*
  	 * Disarm any old timer after extracting its expiry time.
  	 */
  	BUG_ON(!irqs_disabled());
a69ac4a78   Oleg Nesterov   [PATCH] posix-tim...
704
705
  
  	ret = 0;
ae1a78eec   Stanislaw Gruszka   cpu-timers: Retur...
706
  	old_incr = timer->it.cpu.incr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
708
  	spin_lock(&p->sighand->siglock);
  	old_expires = timer->it.cpu.expires;
a69ac4a78   Oleg Nesterov   [PATCH] posix-tim...
709
710
711
712
713
  	if (unlikely(timer->it.cpu.firing)) {
  		timer->it.cpu.firing = -1;
  		ret = TIMER_RETRY;
  	} else
  		list_del_init(&timer->it.cpu.entry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
715
716
717
718
719
720
721
722
723
724
725
  
  	/*
  	 * We need to sample the current value to convert the new
  	 * value from to relative and absolute, and to convert the
  	 * old value from absolute to relative.  To set a process
  	 * timer, we need a sample to balance the thread expiry
  	 * times (in arm_timer).  With an absolute time, we must
  	 * check if it's already passed.  In short, we need a sample.
  	 */
  	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
  		cpu_clock_sample(timer->it_clock, p, &val);
  	} else {
3997ad317   Peter Zijlstra   timers: more cons...
726
  		cpu_timer_sample_group(timer->it_clock, p, &val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
  	}
  
  	if (old) {
  		if (old_expires.sched == 0) {
  			old->it_value.tv_sec = 0;
  			old->it_value.tv_nsec = 0;
  		} else {
  			/*
  			 * Update the timer in case it has
  			 * overrun already.  If it has,
  			 * we'll report it as having overrun
  			 * and with the next reloaded timer
  			 * already ticking, though we are
  			 * swallowing that pending
  			 * notification here to install the
  			 * new setting.
  			 */
  			bump_cpu_timer(timer, val);
  			if (cpu_time_before(timer->it_clock, val,
  					    timer->it.cpu.expires)) {
  				old_expires = cpu_time_sub(
  					timer->it_clock,
  					timer->it.cpu.expires, val);
  				sample_to_timespec(timer->it_clock,
  						   old_expires,
  						   &old->it_value);
  			} else {
  				old->it_value.tv_nsec = 1;
  				old->it_value.tv_sec = 0;
  			}
  		}
  	}
a69ac4a78   Oleg Nesterov   [PATCH] posix-tim...
759
  	if (unlikely(ret)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
761
762
763
764
765
  		/*
  		 * We are colliding with the timer actually firing.
  		 * Punt after filling in the timer's old value, and
  		 * disable this firing since we are already reporting
  		 * it as an overrun (thanks to bump_cpu_timer above).
  		 */
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
766
  		spin_unlock(&p->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
  		read_unlock(&tasklist_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
769
770
771
772
773
774
775
776
777
778
779
780
781
  		goto out;
  	}
  
  	if (new_expires.sched != 0 && !(flags & TIMER_ABSTIME)) {
  		cpu_time_add(timer->it_clock, &new_expires, val);
  	}
  
  	/*
  	 * Install the new expiry time (or zero).
  	 * For a timer with no notification action, we don't actually
  	 * arm the timer (we'll just fake it for timer_gettime).
  	 */
  	timer->it.cpu.expires = new_expires;
  	if (new_expires.sched != 0 &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
  	    cpu_time_before(timer->it_clock, val, new_expires)) {
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
783
  		arm_timer(timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  	}
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
785
  	spin_unlock(&p->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
  	read_unlock(&tasklist_lock);
  
  	/*
  	 * Install the new reload setting, and
  	 * set up the signal and overrun bookkeeping.
  	 */
  	timer->it.cpu.incr = timespec_to_sample(timer->it_clock,
  						&new->it_interval);
  
  	/*
  	 * This acts as a modification timestamp for the timer,
  	 * so any automatic reload attempt will punt on seeing
  	 * that we have reset the timer manually.
  	 */
  	timer->it_requeue_pending = (timer->it_requeue_pending + 2) &
  		~REQUEUE_PENDING;
  	timer->it_overrun_last = 0;
  	timer->it_overrun = -1;
  
  	if (new_expires.sched != 0 &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
807
808
809
810
811
812
813
814
815
816
817
818
  	    !cpu_time_before(timer->it_clock, val, new_expires)) {
  		/*
  		 * The designated time already passed, so we notify
  		 * immediately, even if the thread never runs to
  		 * accumulate more time on this clock.
  		 */
  		cpu_timer_fire(timer);
  	}
  
  	ret = 0;
   out:
  	if (old) {
  		sample_to_timespec(timer->it_clock,
ae1a78eec   Stanislaw Gruszka   cpu-timers: Retur...
819
  				   old_incr, &old->it_interval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
820
  	}
a85721601   Frederic Weisbecker   posix_timers: Kic...
821
822
  	if (!ret)
  		posix_cpu_timer_kick_nohz();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
824
  	return ret;
  }
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
825
  static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
  {
  	union cpu_time_count now;
  	struct task_struct *p = timer->it.cpu.task;
  	int clear_dead;
  
  	/*
  	 * Easy part: convert the reload time.
  	 */
  	sample_to_timespec(timer->it_clock,
  			   timer->it.cpu.incr, &itp->it_interval);
  
  	if (timer->it.cpu.expires.sched == 0) {	/* Timer not armed at all.  */
  		itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
  		return;
  	}
  
  	if (unlikely(p == NULL)) {
  		/*
  		 * This task already died and the timer will never fire.
  		 * In this case, expires is actually the dead value.
  		 */
  	dead:
  		sample_to_timespec(timer->it_clock, timer->it.cpu.expires,
  				   &itp->it_value);
  		return;
  	}
  
  	/*
  	 * Sample the clock to take the difference with the expiry time.
  	 */
  	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
  		cpu_clock_sample(timer->it_clock, p, &now);
  		clear_dead = p->exit_state;
  	} else {
  		read_lock(&tasklist_lock);
d30fda355   Oleg Nesterov   posix-cpu-timers:...
861
  		if (unlikely(p->sighand == NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
865
866
867
868
869
870
871
872
  			/*
  			 * The process has been reaped.
  			 * We can't even collect a sample any more.
  			 * Call the timer disarmed, nothing else to do.
  			 */
  			put_task_struct(p);
  			timer->it.cpu.task = NULL;
  			timer->it.cpu.expires.sched = 0;
  			read_unlock(&tasklist_lock);
  			goto dead;
  		} else {
3997ad317   Peter Zijlstra   timers: more cons...
873
  			cpu_timer_sample_group(timer->it_clock, p, &now);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
876
877
878
  			clear_dead = (unlikely(p->exit_state) &&
  				      thread_group_empty(p));
  		}
  		read_unlock(&tasklist_lock);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
  	if (unlikely(clear_dead)) {
  		/*
  		 * We've noticed that the thread is dead, but
  		 * not yet reaped.  Take this opportunity to
  		 * drop our task ref.
  		 */
  		clear_dead_task(timer, now);
  		goto dead;
  	}
  
  	if (cpu_time_before(timer->it_clock, now, timer->it.cpu.expires)) {
  		sample_to_timespec(timer->it_clock,
  				   cpu_time_sub(timer->it_clock,
  						timer->it.cpu.expires, now),
  				   &itp->it_value);
  	} else {
  		/*
  		 * The timer should have expired already, but the firing
  		 * hasn't taken place yet.  Say it's just about to expire.
  		 */
  		itp->it_value.tv_nsec = 1;
  		itp->it_value.tv_sec = 0;
  	}
  }
  
  /*
   * Check for any per-thread CPU timers that have fired and move them off
   * the tsk->cpu_timers[N] list onto the firing list.  Here we update the
   * tsk->it_*_expires values to reflect the remaining thread CPU timers.
   */
  static void check_thread_timers(struct task_struct *tsk,
  				struct list_head *firing)
  {
e80eda94d   Linus Torvalds   Posix timers: lim...
912
  	int maxfire;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  	struct list_head *timers = tsk->cpu_timers;
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
914
  	struct signal_struct *const sig = tsk->signal;
d4bb52743   Jiri Slaby   posix-cpu-timers:...
915
  	unsigned long soft;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
916

e80eda94d   Linus Torvalds   Posix timers: lim...
917
  	maxfire = 20;
648616343   Martin Schwidefsky   [S390] cputime: a...
918
  	tsk->cputime_expires.prof_exp = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  	while (!list_empty(timers)) {
b5e618181   Pavel Emelianov   Introduce a handy...
920
  		struct cpu_timer_list *t = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
922
  						      struct cpu_timer_list,
  						      entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
923
  		if (!--maxfire || prof_ticks(tsk) < t->expires.cpu) {
f06febc96   Frank Mayhar   timers: fix itime...
924
  			tsk->cputime_expires.prof_exp = t->expires.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
926
927
928
929
930
931
  			break;
  		}
  		t->firing = 1;
  		list_move_tail(&t->entry, firing);
  	}
  
  	++timers;
e80eda94d   Linus Torvalds   Posix timers: lim...
932
  	maxfire = 20;
648616343   Martin Schwidefsky   [S390] cputime: a...
933
  	tsk->cputime_expires.virt_exp = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
  	while (!list_empty(timers)) {
b5e618181   Pavel Emelianov   Introduce a handy...
935
  		struct cpu_timer_list *t = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
937
  						      struct cpu_timer_list,
  						      entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
938
  		if (!--maxfire || virt_ticks(tsk) < t->expires.cpu) {
f06febc96   Frank Mayhar   timers: fix itime...
939
  			tsk->cputime_expires.virt_exp = t->expires.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940
941
942
943
944
945
946
  			break;
  		}
  		t->firing = 1;
  		list_move_tail(&t->entry, firing);
  	}
  
  	++timers;
e80eda94d   Linus Torvalds   Posix timers: lim...
947
  	maxfire = 20;
f06febc96   Frank Mayhar   timers: fix itime...
948
  	tsk->cputime_expires.sched_exp = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
  	while (!list_empty(timers)) {
b5e618181   Pavel Emelianov   Introduce a handy...
950
  		struct cpu_timer_list *t = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
952
  						      struct cpu_timer_list,
  						      entry);
41b86e9c5   Ingo Molnar   sched: make posix...
953
  		if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) {
f06febc96   Frank Mayhar   timers: fix itime...
954
  			tsk->cputime_expires.sched_exp = t->expires.sched;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
958
959
  			break;
  		}
  		t->firing = 1;
  		list_move_tail(&t->entry, firing);
  	}
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
960
961
962
963
  
  	/*
  	 * Check for the special case thread timers.
  	 */
78d7d407b   Jiri Slaby   kernel core: use ...
964
  	soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
d4bb52743   Jiri Slaby   posix-cpu-timers:...
965
  	if (soft != RLIM_INFINITY) {
78d7d407b   Jiri Slaby   kernel core: use ...
966
967
  		unsigned long hard =
  			ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max);
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
968

5a52dd500   Peter Zijlstra   sched: rt-watchdo...
969
970
  		if (hard != RLIM_INFINITY &&
  		    tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
971
972
973
974
975
976
977
  			/*
  			 * At the hard limit, we just die.
  			 * No need to calculate anything else now.
  			 */
  			__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
  			return;
  		}
d4bb52743   Jiri Slaby   posix-cpu-timers:...
978
  		if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
979
980
981
  			/*
  			 * At the soft limit, send a SIGXCPU every second.
  			 */
d4bb52743   Jiri Slaby   posix-cpu-timers:...
982
983
984
  			if (soft < hard) {
  				soft += USEC_PER_SEC;
  				sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
985
  			}
81d50bb25   Hiroshi Shimamoto   posix-timers: pri...
986
987
988
989
  			printk(KERN_INFO
  				"RT Watchdog Timeout: %s[%d]
  ",
  				tsk->comm, task_pid_nr(tsk));
78f2c7db6   Peter Zijlstra   sched: SCHED_FIFO...
990
991
992
  			__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
  }
15365c108   Stanislaw Gruszka   posix-cpu-timers:...
994
  static void stop_process_timers(struct signal_struct *sig)
3fccfd67d   Peter Zijlstra   timers: split pro...
995
  {
15365c108   Stanislaw Gruszka   posix-cpu-timers:...
996
  	struct thread_group_cputimer *cputimer = &sig->cputimer;
3fccfd67d   Peter Zijlstra   timers: split pro...
997
  	unsigned long flags;
ee30a7b2f   Thomas Gleixner   locking, sched: A...
998
  	raw_spin_lock_irqsave(&cputimer->lock, flags);
3fccfd67d   Peter Zijlstra   timers: split pro...
999
  	cputimer->running = 0;
ee30a7b2f   Thomas Gleixner   locking, sched: A...
1000
  	raw_spin_unlock_irqrestore(&cputimer->lock, flags);
3fccfd67d   Peter Zijlstra   timers: split pro...
1001
  }
8356b5f9c   Stanislaw Gruszka   itimers: Fix peri...
1002
  static u32 onecputick;
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1003
1004
1005
  static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
  			     cputime_t *expires, cputime_t cur_time, int signo)
  {
648616343   Martin Schwidefsky   [S390] cputime: a...
1006
  	if (!it->expires)
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1007
  		return;
648616343   Martin Schwidefsky   [S390] cputime: a...
1008
1009
1010
  	if (cur_time >= it->expires) {
  		if (it->incr) {
  			it->expires += it->incr;
8356b5f9c   Stanislaw Gruszka   itimers: Fix peri...
1011
1012
  			it->error += it->incr_error;
  			if (it->error >= onecputick) {
648616343   Martin Schwidefsky   [S390] cputime: a...
1013
  				it->expires -= cputime_one_jiffy;
8356b5f9c   Stanislaw Gruszka   itimers: Fix peri...
1014
1015
  				it->error -= onecputick;
  			}
3f0a525eb   Xiao Guangrong   itimers: Add trac...
1016
  		} else {
648616343   Martin Schwidefsky   [S390] cputime: a...
1017
  			it->expires = 0;
3f0a525eb   Xiao Guangrong   itimers: Add trac...
1018
  		}
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1019

3f0a525eb   Xiao Guangrong   itimers: Add trac...
1020
1021
1022
  		trace_itimer_expire(signo == SIGPROF ?
  				    ITIMER_PROF : ITIMER_VIRTUAL,
  				    tsk->signal->leader_pid, cur_time);
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1023
1024
  		__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
  	}
648616343   Martin Schwidefsky   [S390] cputime: a...
1025
  	if (it->expires && (!*expires || it->expires < *expires)) {
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1026
1027
1028
  		*expires = it->expires;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
1031
1032
1033
1034
1035
1036
  /*
   * Check for any per-thread CPU timers that have fired and move them
   * off the tsk->*_timers list onto the firing list.  Per-thread timers
   * have already been taken off.
   */
  static void check_process_timers(struct task_struct *tsk,
  				 struct list_head *firing)
  {
e80eda94d   Linus Torvalds   Posix timers: lim...
1037
  	int maxfire;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  	struct signal_struct *const sig = tsk->signal;
f06febc96   Frank Mayhar   timers: fix itime...
1039
  	cputime_t utime, ptime, virt_expires, prof_expires;
41b86e9c5   Ingo Molnar   sched: make posix...
1040
  	unsigned long long sum_sched_runtime, sched_expires;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
  	struct list_head *timers = sig->cpu_timers;
f06febc96   Frank Mayhar   timers: fix itime...
1042
  	struct task_cputime cputime;
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1043
  	unsigned long soft;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
1045
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1046
1047
  	 * Collect the current process totals.
  	 */
4cd4c1b40   Peter Zijlstra   timers: split pro...
1048
  	thread_group_cputimer(tsk, &cputime);
f06febc96   Frank Mayhar   timers: fix itime...
1049
  	utime = cputime.utime;
648616343   Martin Schwidefsky   [S390] cputime: a...
1050
  	ptime = utime + cputime.stime;
f06febc96   Frank Mayhar   timers: fix itime...
1051
  	sum_sched_runtime = cputime.sum_exec_runtime;
e80eda94d   Linus Torvalds   Posix timers: lim...
1052
  	maxfire = 20;
648616343   Martin Schwidefsky   [S390] cputime: a...
1053
  	prof_expires = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
  	while (!list_empty(timers)) {
ee7dd205b   WANG Cong   posix-timers: fix...
1055
  		struct cpu_timer_list *tl = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
1057
  						      struct cpu_timer_list,
  						      entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
1058
  		if (!--maxfire || ptime < tl->expires.cpu) {
ee7dd205b   WANG Cong   posix-timers: fix...
1059
  			prof_expires = tl->expires.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
  			break;
  		}
ee7dd205b   WANG Cong   posix-timers: fix...
1062
1063
  		tl->firing = 1;
  		list_move_tail(&tl->entry, firing);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
1065
1066
  	}
  
  	++timers;
e80eda94d   Linus Torvalds   Posix timers: lim...
1067
  	maxfire = 20;
648616343   Martin Schwidefsky   [S390] cputime: a...
1068
  	virt_expires = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1069
  	while (!list_empty(timers)) {
ee7dd205b   WANG Cong   posix-timers: fix...
1070
  		struct cpu_timer_list *tl = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
1072
  						      struct cpu_timer_list,
  						      entry);
648616343   Martin Schwidefsky   [S390] cputime: a...
1073
  		if (!--maxfire || utime < tl->expires.cpu) {
ee7dd205b   WANG Cong   posix-timers: fix...
1074
  			virt_expires = tl->expires.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1075
1076
  			break;
  		}
ee7dd205b   WANG Cong   posix-timers: fix...
1077
1078
  		tl->firing = 1;
  		list_move_tail(&tl->entry, firing);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
1080
1081
  	}
  
  	++timers;
e80eda94d   Linus Torvalds   Posix timers: lim...
1082
  	maxfire = 20;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083
1084
  	sched_expires = 0;
  	while (!list_empty(timers)) {
ee7dd205b   WANG Cong   posix-timers: fix...
1085
  		struct cpu_timer_list *tl = list_first_entry(timers,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1086
1087
  						      struct cpu_timer_list,
  						      entry);
ee7dd205b   WANG Cong   posix-timers: fix...
1088
1089
  		if (!--maxfire || sum_sched_runtime < tl->expires.sched) {
  			sched_expires = tl->expires.sched;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
1091
  			break;
  		}
ee7dd205b   WANG Cong   posix-timers: fix...
1092
1093
  		tl->firing = 1;
  		list_move_tail(&tl->entry, firing);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1094
1095
1096
1097
1098
  	}
  
  	/*
  	 * Check for the special case process timers.
  	 */
42c4ab41a   Stanislaw Gruszka   itimers: Merge IT...
1099
1100
1101
1102
  	check_cpu_itimer(tsk, &sig->it[CPUCLOCK_PROF], &prof_expires, ptime,
  			 SIGPROF);
  	check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
  			 SIGVTALRM);
78d7d407b   Jiri Slaby   kernel core: use ...
1103
  	soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1104
  	if (soft != RLIM_INFINITY) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  		unsigned long psecs = cputime_to_secs(ptime);
78d7d407b   Jiri Slaby   kernel core: use ...
1106
1107
  		unsigned long hard =
  			ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
  		cputime_t x;
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1109
  		if (psecs >= hard) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1110
1111
1112
1113
1114
1115
1116
  			/*
  			 * At the hard limit, we just die.
  			 * No need to calculate anything else now.
  			 */
  			__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
  			return;
  		}
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1117
  		if (psecs >= soft) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118
1119
1120
1121
  			/*
  			 * At the soft limit, send a SIGXCPU every second.
  			 */
  			__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1122
1123
1124
  			if (soft < hard) {
  				soft++;
  				sig->rlim[RLIMIT_CPU].rlim_cur = soft;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
  			}
  		}
d4bb52743   Jiri Slaby   posix-cpu-timers:...
1127
  		x = secs_to_cputime(soft);
648616343   Martin Schwidefsky   [S390] cputime: a...
1128
  		if (!prof_expires || x < prof_expires) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1129
1130
1131
  			prof_expires = x;
  		}
  	}
29f87b793   Stanislaw Gruszka   posix-cpu-timers:...
1132
1133
1134
1135
1136
  	sig->cputime_expires.prof_exp = prof_expires;
  	sig->cputime_expires.virt_exp = virt_expires;
  	sig->cputime_expires.sched_exp = sched_expires;
  	if (task_cputime_zero(&sig->cputime_expires))
  		stop_process_timers(sig);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
  }
  
  /*
   * This is called from the signal code (via do_schedule_next_timer)
   * when the last timer signal was delivered and we have to reload the timer.
   */
  void posix_cpu_timer_schedule(struct k_itimer *timer)
  {
  	struct task_struct *p = timer->it.cpu.task;
  	union cpu_time_count now;
  
  	if (unlikely(p == NULL))
  		/*
  		 * The task was cleaned up already, no future firings.
  		 */
708f430dc   Roland McGrath   [PATCH] posix-cpu...
1152
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
1154
1155
1156
1157
1158
1159
1160
1161
  
  	/*
  	 * Fetch the current sample and update the timer's expiry time.
  	 */
  	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
  		cpu_clock_sample(timer->it_clock, p, &now);
  		bump_cpu_timer(timer, now);
  		if (unlikely(p->exit_state)) {
  			clear_dead_task(timer, now);
708f430dc   Roland McGrath   [PATCH] posix-cpu...
1162
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1163
1164
  		}
  		read_lock(&tasklist_lock); /* arm_timer needs it.  */
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
1165
  		spin_lock(&p->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166
1167
  	} else {
  		read_lock(&tasklist_lock);
d30fda355   Oleg Nesterov   posix-cpu-timers:...
1168
  		if (unlikely(p->sighand == NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
1170
1171
1172
1173
1174
1175
  			/*
  			 * The process has been reaped.
  			 * We can't even collect a sample any more.
  			 */
  			put_task_struct(p);
  			timer->it.cpu.task = p = NULL;
  			timer->it.cpu.expires.sched = 0;
708f430dc   Roland McGrath   [PATCH] posix-cpu...
1176
  			goto out_unlock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177
1178
1179
1180
1181
1182
1183
  		} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
  			/*
  			 * We've noticed that the thread is dead, but
  			 * not yet reaped.  Take this opportunity to
  			 * drop our task ref.
  			 */
  			clear_dead_task(timer, now);
708f430dc   Roland McGrath   [PATCH] posix-cpu...
1184
  			goto out_unlock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1185
  		}
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
1186
  		spin_lock(&p->sighand->siglock);
3997ad317   Peter Zijlstra   timers: more cons...
1187
  		cpu_timer_sample_group(timer->it_clock, p, &now);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
1189
1190
1191
1192
1193
1194
  		bump_cpu_timer(timer, now);
  		/* Leave the tasklist_lock locked for the call below.  */
  	}
  
  	/*
  	 * Now re-arm for the new expiry time.
  	 */
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
1195
  	BUG_ON(!irqs_disabled());
5eb9aa641   Stanislaw Gruszka   cpu-timers: Clean...
1196
  	arm_timer(timer);
c28739375   Stanislaw Gruszka   cpu-timers: Avoid...
1197
  	spin_unlock(&p->sighand->siglock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198

708f430dc   Roland McGrath   [PATCH] posix-cpu...
1199
  out_unlock:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200
  	read_unlock(&tasklist_lock);
708f430dc   Roland McGrath   [PATCH] posix-cpu...
1201
1202
1203
1204
1205
  
  out:
  	timer->it_overrun_last = timer->it_overrun;
  	timer->it_overrun = -1;
  	++timer->it_requeue_pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
  }
f06febc96   Frank Mayhar   timers: fix itime...
1207
  /**
f06febc96   Frank Mayhar   timers: fix itime...
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
   * task_cputime_expired - Compare two task_cputime entities.
   *
   * @sample:	The task_cputime structure to be checked for expiration.
   * @expires:	Expiration times, against which @sample will be checked.
   *
   * Checks @sample against @expires to see if any field of @sample has expired.
   * Returns true if any field of the former is greater than the corresponding
   * field of the latter if the latter field is set.  Otherwise returns false.
   */
  static inline int task_cputime_expired(const struct task_cputime *sample,
  					const struct task_cputime *expires)
  {
648616343   Martin Schwidefsky   [S390] cputime: a...
1220
  	if (expires->utime && sample->utime >= expires->utime)
f06febc96   Frank Mayhar   timers: fix itime...
1221
  		return 1;
648616343   Martin Schwidefsky   [S390] cputime: a...
1222
  	if (expires->stime && sample->utime + sample->stime >= expires->stime)
f06febc96   Frank Mayhar   timers: fix itime...
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
  		return 1;
  	if (expires->sum_exec_runtime != 0 &&
  	    sample->sum_exec_runtime >= expires->sum_exec_runtime)
  		return 1;
  	return 0;
  }
  
  /**
   * fastpath_timer_check - POSIX CPU timers fast path.
   *
   * @tsk:	The task (thread) being checked.
f06febc96   Frank Mayhar   timers: fix itime...
1234
   *
bb34d92f6   Frank Mayhar   timers: fix itime...
1235
1236
1237
1238
   * Check the task and thread group timers.  If both are zero (there are no
   * timers set) return false.  Otherwise snapshot the task and thread group
   * timers and compare them with the corresponding expiration times.  Return
   * true if a timer has expired, else return false.
f06febc96   Frank Mayhar   timers: fix itime...
1239
   */
bb34d92f6   Frank Mayhar   timers: fix itime...
1240
  static inline int fastpath_timer_check(struct task_struct *tsk)
f06febc96   Frank Mayhar   timers: fix itime...
1241
  {
ad133ba3d   Oleg Nesterov   sched, signals: f...
1242
  	struct signal_struct *sig;
6fac4829c   Frederic Weisbecker   cputime: Use acce...
1243
1244
1245
  	cputime_t utime, stime;
  
  	task_cputime(tsk, &utime, &stime);
bb34d92f6   Frank Mayhar   timers: fix itime...
1246

bb34d92f6   Frank Mayhar   timers: fix itime...
1247
1248
  	if (!task_cputime_zero(&tsk->cputime_expires)) {
  		struct task_cputime task_sample = {
6fac4829c   Frederic Weisbecker   cputime: Use acce...
1249
1250
  			.utime = utime,
  			.stime = stime,
bb34d92f6   Frank Mayhar   timers: fix itime...
1251
1252
1253
1254
1255
1256
  			.sum_exec_runtime = tsk->se.sum_exec_runtime
  		};
  
  		if (task_cputime_expired(&task_sample, &tsk->cputime_expires))
  			return 1;
  	}
ad133ba3d   Oleg Nesterov   sched, signals: f...
1257
1258
  
  	sig = tsk->signal;
29f87b793   Stanislaw Gruszka   posix-cpu-timers:...
1259
  	if (sig->cputimer.running) {
bb34d92f6   Frank Mayhar   timers: fix itime...
1260
  		struct task_cputime group_sample;
ee30a7b2f   Thomas Gleixner   locking, sched: A...
1261
  		raw_spin_lock(&sig->cputimer.lock);
8d1f431cb   Oleg Nesterov   sched: Fix the ra...
1262
  		group_sample = sig->cputimer.cputime;
ee30a7b2f   Thomas Gleixner   locking, sched: A...
1263
  		raw_spin_unlock(&sig->cputimer.lock);
8d1f431cb   Oleg Nesterov   sched: Fix the ra...
1264

bb34d92f6   Frank Mayhar   timers: fix itime...
1265
1266
1267
  		if (task_cputime_expired(&group_sample, &sig->cputime_expires))
  			return 1;
  	}
37bebc70d   Oleg Nesterov   posix timers: fix...
1268

f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1269
  	return 0;
f06febc96   Frank Mayhar   timers: fix itime...
1270
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1271
1272
1273
1274
1275
1276
1277
1278
1279
  /*
   * This is called from the timer interrupt handler.  The irq handler has
   * already updated our counts.  We need to check if any timers fire now.
   * Interrupts are disabled.
   */
  void run_posix_cpu_timers(struct task_struct *tsk)
  {
  	LIST_HEAD(firing);
  	struct k_itimer *timer, *next;
0bdd2ed41   Oleg Nesterov   sched: run_posix_...
1280
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
1282
  
  	BUG_ON(!irqs_disabled());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
  	/*
f06febc96   Frank Mayhar   timers: fix itime...
1284
  	 * The fast path checks that there are no expired thread or thread
bb34d92f6   Frank Mayhar   timers: fix itime...
1285
  	 * group timers.  If that's so, just return.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
  	 */
bb34d92f6   Frank Mayhar   timers: fix itime...
1287
  	if (!fastpath_timer_check(tsk))
f06febc96   Frank Mayhar   timers: fix itime...
1288
  		return;
5ce73a4a5   Ingo Molnar   timers: fix itime...
1289

0bdd2ed41   Oleg Nesterov   sched: run_posix_...
1290
1291
  	if (!lock_task_sighand(tsk, &flags))
  		return;
bb34d92f6   Frank Mayhar   timers: fix itime...
1292
1293
1294
1295
1296
1297
  	/*
  	 * Here we take off tsk->signal->cpu_timers[N] and
  	 * tsk->cpu_timers[N] all the timers that are firing, and
  	 * put them on the firing list.
  	 */
  	check_thread_timers(tsk, &firing);
29f87b793   Stanislaw Gruszka   posix-cpu-timers:...
1298
1299
1300
1301
1302
1303
  	/*
  	 * If there are any active process wide timers (POSIX 1.b, itimers,
  	 * RLIMIT_CPU) cputimer must be running.
  	 */
  	if (tsk->signal->cputimer.running)
  		check_process_timers(tsk, &firing);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304

bb34d92f6   Frank Mayhar   timers: fix itime...
1305
1306
1307
1308
1309
1310
1311
1312
  	/*
  	 * We must release these locks before taking any timer's lock.
  	 * There is a potential race with timer deletion here, as the
  	 * siglock now protects our private firing list.  We have set
  	 * the firing flag in each timer, so that a deletion attempt
  	 * that gets the timer lock before we do will give it up and
  	 * spin until we've taken care of that timer below.
  	 */
0bdd2ed41   Oleg Nesterov   sched: run_posix_...
1313
  	unlock_task_sighand(tsk, &flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
1315
1316
  
  	/*
  	 * Now that all the timers on our list have the firing flag,
25985edce   Lucas De Marchi   Fix common misspe...
1317
  	 * no one will touch their list entries but us.  We'll take
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1318
1319
1320
1321
  	 * each timer's lock before clearing its firing flag, so no
  	 * timer call will interfere.
  	 */
  	list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
6e85c5ba7   H Hartley Sweeten   kernel/posix-cpu-...
1322
  		int cpu_firing;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
1324
  		spin_lock(&timer->it_lock);
  		list_del_init(&timer->it.cpu.entry);
6e85c5ba7   H Hartley Sweeten   kernel/posix-cpu-...
1325
  		cpu_firing = timer->it.cpu.firing;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1326
1327
1328
1329
1330
1331
  		timer->it.cpu.firing = 0;
  		/*
  		 * The firing flag is -1 if we collided with a reset
  		 * of the timer, which already reported this
  		 * almost-firing as an overrun.  So don't generate an event.
  		 */
6e85c5ba7   H Hartley Sweeten   kernel/posix-cpu-...
1332
  		if (likely(cpu_firing >= 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
  			cpu_timer_fire(timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1334
1335
  		spin_unlock(&timer->it_lock);
  	}
a85721601   Frederic Weisbecker   posix_timers: Kic...
1336
1337
1338
1339
1340
1341
1342
  
  	/*
  	 * In case some timers were rescheduled after the queue got emptied,
  	 * wake up full dynticks CPUs.
  	 */
  	if (tsk->signal->cputimer.running)
  		posix_cpu_timer_kick_nohz();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1343
1344
1345
  }
  
  /*
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1346
   * Set one of the process-wide special case CPU timers or RLIMIT_CPU.
f06febc96   Frank Mayhar   timers: fix itime...
1347
   * The tsk->sighand->siglock must be held by the caller.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1348
1349
1350
1351
1352
   */
  void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
  			   cputime_t *newval, cputime_t *oldval)
  {
  	union cpu_time_count now;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
1354
  
  	BUG_ON(clock_idx == CPUCLOCK_SCHED);
4cd4c1b40   Peter Zijlstra   timers: split pro...
1355
  	cpu_timer_sample_group(clock_idx, tsk, &now);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
1357
  
  	if (oldval) {
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1358
1359
1360
1361
1362
  		/*
  		 * We are setting itimer. The *oldval is absolute and we update
  		 * it to be relative, *newval argument is relative and we update
  		 * it to be absolute.
  		 */
648616343   Martin Schwidefsky   [S390] cputime: a...
1363
1364
  		if (*oldval) {
  			if (*oldval <= now.cpu) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1365
  				/* Just about to fire. */
a42548a18   Stanislaw Gruszka   cputime: Optimize...
1366
  				*oldval = cputime_one_jiffy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
  			} else {
648616343   Martin Schwidefsky   [S390] cputime: a...
1368
  				*oldval -= now.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
1370
  			}
  		}
648616343   Martin Schwidefsky   [S390] cputime: a...
1371
  		if (!*newval)
a85721601   Frederic Weisbecker   posix_timers: Kic...
1372
  			goto out;
648616343   Martin Schwidefsky   [S390] cputime: a...
1373
  		*newval += now.cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
1375
1376
  	}
  
  	/*
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1377
1378
  	 * Update expiration cache if we are the earliest timer, or eventually
  	 * RLIMIT_CPU limit is earlier than prof_exp cpu timer expire.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1379
  	 */
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1380
1381
1382
  	switch (clock_idx) {
  	case CPUCLOCK_PROF:
  		if (expires_gt(tsk->signal->cputime_expires.prof_exp, *newval))
f06febc96   Frank Mayhar   timers: fix itime...
1383
  			tsk->signal->cputime_expires.prof_exp = *newval;
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1384
1385
1386
  		break;
  	case CPUCLOCK_VIRT:
  		if (expires_gt(tsk->signal->cputime_expires.virt_exp, *newval))
f06febc96   Frank Mayhar   timers: fix itime...
1387
  			tsk->signal->cputime_expires.virt_exp = *newval;
f55db6090   Stanislaw Gruszka   cpu-timers: Simpl...
1388
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1389
  	}
a85721601   Frederic Weisbecker   posix_timers: Kic...
1390
1391
  out:
  	posix_cpu_timer_kick_nohz();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
  }
e4b765551   Toyo Abe   [PATCH] posix-tim...
1393
1394
  static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
  			    struct timespec *rqtp, struct itimerspec *it)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
1397
1398
1399
  	struct k_itimer timer;
  	int error;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400
1401
1402
1403
1404
1405
1406
1407
1408
  	 * Set up a temporary timer and then wait for it to go off.
  	 */
  	memset(&timer, 0, sizeof timer);
  	spin_lock_init(&timer.it_lock);
  	timer.it_clock = which_clock;
  	timer.it_overrun = -1;
  	error = posix_cpu_timer_create(&timer);
  	timer.it_process = current;
  	if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409
  		static struct itimerspec zero_it;
e4b765551   Toyo Abe   [PATCH] posix-tim...
1410
1411
1412
  
  		memset(it, 0, sizeof *it);
  		it->it_value = *rqtp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
1414
  
  		spin_lock_irq(&timer.it_lock);
e4b765551   Toyo Abe   [PATCH] posix-tim...
1415
  		error = posix_cpu_timer_set(&timer, flags, it, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
1417
1418
1419
1420
1421
1422
1423
  		if (error) {
  			spin_unlock_irq(&timer.it_lock);
  			return error;
  		}
  
  		while (!signal_pending(current)) {
  			if (timer.it.cpu.expires.sched == 0) {
  				/*
e6c42c295   Stanislaw Gruszka   posix-cpu-timers:...
1424
1425
  				 * Our timer fired and was reset, below
  				 * deletion can not fail.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1426
  				 */
e6c42c295   Stanislaw Gruszka   posix-cpu-timers:...
1427
  				posix_cpu_timer_del(&timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
  				spin_unlock_irq(&timer.it_lock);
  				return 0;
  			}
  
  			/*
  			 * Block until cpu_timer_fire (or a signal) wakes us.
  			 */
  			__set_current_state(TASK_INTERRUPTIBLE);
  			spin_unlock_irq(&timer.it_lock);
  			schedule();
  			spin_lock_irq(&timer.it_lock);
  		}
  
  		/*
  		 * We were interrupted by a signal.
  		 */
  		sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
e6c42c295   Stanislaw Gruszka   posix-cpu-timers:...
1445
1446
1447
1448
1449
1450
1451
  		error = posix_cpu_timer_set(&timer, 0, &zero_it, it);
  		if (!error) {
  			/*
  			 * Timer is now unarmed, deletion can not fail.
  			 */
  			posix_cpu_timer_del(&timer);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
  		spin_unlock_irq(&timer.it_lock);
e6c42c295   Stanislaw Gruszka   posix-cpu-timers:...
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
  		while (error == TIMER_RETRY) {
  			/*
  			 * We need to handle case when timer was or is in the
  			 * middle of firing. In other cases we already freed
  			 * resources.
  			 */
  			spin_lock_irq(&timer.it_lock);
  			error = posix_cpu_timer_del(&timer);
  			spin_unlock_irq(&timer.it_lock);
  		}
e4b765551   Toyo Abe   [PATCH] posix-tim...
1463
  		if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
1466
1467
1468
  			/*
  			 * It actually did fire already.
  			 */
  			return 0;
  		}
e4b765551   Toyo Abe   [PATCH] posix-tim...
1469
1470
1471
1472
1473
  		error = -ERESTART_RESTARTBLOCK;
  	}
  
  	return error;
  }
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
1474
1475
1476
1477
  static long posix_cpu_nsleep_restart(struct restart_block *restart_block);
  
  static int posix_cpu_nsleep(const clockid_t which_clock, int flags,
  			    struct timespec *rqtp, struct timespec __user *rmtp)
e4b765551   Toyo Abe   [PATCH] posix-tim...
1478
1479
  {
  	struct restart_block *restart_block =
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1480
  		&current_thread_info()->restart_block;
e4b765551   Toyo Abe   [PATCH] posix-tim...
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  	struct itimerspec it;
  	int error;
  
  	/*
  	 * Diagnose required errors first.
  	 */
  	if (CPUCLOCK_PERTHREAD(which_clock) &&
  	    (CPUCLOCK_PID(which_clock) == 0 ||
  	     CPUCLOCK_PID(which_clock) == current->pid))
  		return -EINVAL;
  
  	error = do_cpu_nanosleep(which_clock, flags, rqtp, &it);
  
  	if (error == -ERESTART_RESTARTBLOCK) {
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1495
  		if (flags & TIMER_ABSTIME)
e4b765551   Toyo Abe   [PATCH] posix-tim...
1496
  			return -ERESTARTNOHAND;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
  		/*
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1498
1499
1500
  		 * Report back to the user the time still remaining.
  		 */
  		if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1501
  			return -EFAULT;
1711ef386   Toyo Abe   [PATCH] posix-tim...
1502
  		restart_block->fn = posix_cpu_nsleep_restart;
ab8177bc5   Thomas Gleixner   hrtimers: Avoid t...
1503
  		restart_block->nanosleep.clockid = which_clock;
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1504
1505
  		restart_block->nanosleep.rmtp = rmtp;
  		restart_block->nanosleep.expires = timespec_to_ns(rqtp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
1508
  	return error;
  }
bc2c8ea48   Thomas Gleixner   posix-timers: Mak...
1509
  static long posix_cpu_nsleep_restart(struct restart_block *restart_block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
  {
ab8177bc5   Thomas Gleixner   hrtimers: Avoid t...
1511
  	clockid_t which_clock = restart_block->nanosleep.clockid;
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
1512
  	struct timespec t;
e4b765551   Toyo Abe   [PATCH] posix-tim...
1513
1514
  	struct itimerspec it;
  	int error;
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
1515

3751f9f29   Thomas Gleixner   posix-timers: Cle...
1516
  	t = ns_to_timespec(restart_block->nanosleep.expires);
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
1517

e4b765551   Toyo Abe   [PATCH] posix-tim...
1518
1519
1520
  	error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it);
  
  	if (error == -ERESTART_RESTARTBLOCK) {
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1521
  		struct timespec __user *rmtp = restart_block->nanosleep.rmtp;
e4b765551   Toyo Abe   [PATCH] posix-tim...
1522
  		/*
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1523
1524
1525
  		 * Report back to the user the time still remaining.
  		 */
  		if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
e4b765551   Toyo Abe   [PATCH] posix-tim...
1526
  			return -EFAULT;
3751f9f29   Thomas Gleixner   posix-timers: Cle...
1527
  		restart_block->nanosleep.expires = timespec_to_ns(&t);
e4b765551   Toyo Abe   [PATCH] posix-tim...
1528
1529
  	}
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
1532
  #define PROCESS_CLOCK	MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)
  #define THREAD_CLOCK	MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED)
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
1533
1534
  static int process_cpu_clock_getres(const clockid_t which_clock,
  				    struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
1536
1537
  {
  	return posix_cpu_clock_getres(PROCESS_CLOCK, tp);
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
1538
1539
  static int process_cpu_clock_get(const clockid_t which_clock,
  				 struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1540
1541
1542
1543
1544
1545
1546
1547
  {
  	return posix_cpu_clock_get(PROCESS_CLOCK, tp);
  }
  static int process_cpu_timer_create(struct k_itimer *timer)
  {
  	timer->it_clock = PROCESS_CLOCK;
  	return posix_cpu_timer_create(timer);
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
1548
  static int process_cpu_nsleep(const clockid_t which_clock, int flags,
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
1549
1550
  			      struct timespec *rqtp,
  			      struct timespec __user *rmtp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
  {
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
1552
  	return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1553
  }
1711ef386   Toyo Abe   [PATCH] posix-tim...
1554
1555
1556
1557
  static long process_cpu_nsleep_restart(struct restart_block *restart_block)
  {
  	return -EINVAL;
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
1558
1559
  static int thread_cpu_clock_getres(const clockid_t which_clock,
  				   struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1560
1561
1562
  {
  	return posix_cpu_clock_getres(THREAD_CLOCK, tp);
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
1563
1564
  static int thread_cpu_clock_get(const clockid_t which_clock,
  				struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1565
1566
1567
1568
1569
1570
1571
1572
  {
  	return posix_cpu_clock_get(THREAD_CLOCK, tp);
  }
  static int thread_cpu_timer_create(struct k_itimer *timer)
  {
  	timer->it_clock = THREAD_CLOCK;
  	return posix_cpu_timer_create(timer);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573

1976945ee   Thomas Gleixner   posix-timers: Int...
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
  struct k_clock clock_posix_cpu = {
  	.clock_getres	= posix_cpu_clock_getres,
  	.clock_set	= posix_cpu_clock_set,
  	.clock_get	= posix_cpu_clock_get,
  	.timer_create	= posix_cpu_timer_create,
  	.nsleep		= posix_cpu_nsleep,
  	.nsleep_restart	= posix_cpu_nsleep_restart,
  	.timer_set	= posix_cpu_timer_set,
  	.timer_del	= posix_cpu_timer_del,
  	.timer_get	= posix_cpu_timer_get,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1585
1586
1587
  static __init int init_posix_cpu_timers(void)
  {
  	struct k_clock process = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
1588
1589
  		.clock_getres	= process_cpu_clock_getres,
  		.clock_get	= process_cpu_clock_get,
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
1590
1591
1592
  		.timer_create	= process_cpu_timer_create,
  		.nsleep		= process_cpu_nsleep,
  		.nsleep_restart	= process_cpu_nsleep_restart,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1593
1594
  	};
  	struct k_clock thread = {
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
1595
1596
  		.clock_getres	= thread_cpu_clock_getres,
  		.clock_get	= thread_cpu_clock_get,
2fd1f0408   Thomas Gleixner   posix-timers: Cle...
1597
  		.timer_create	= thread_cpu_timer_create,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1598
  	};
8356b5f9c   Stanislaw Gruszka   itimers: Fix peri...
1599
  	struct timespec ts;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1600

527087374   Thomas Gleixner   posix-timers: Cle...
1601
1602
  	posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
  	posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603

a42548a18   Stanislaw Gruszka   cputime: Optimize...
1604
  	cputime_to_timespec(cputime_one_jiffy, &ts);
8356b5f9c   Stanislaw Gruszka   itimers: Fix peri...
1605
1606
  	onecputick = ts.tv_nsec;
  	WARN_ON(ts.tv_sec != 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
1609
  	return 0;
  }
  __initcall(init_posix_cpu_timers);