aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/posix-cpu-timers.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r--kernel/posix-cpu-timers.c165
1 files changed, 91 insertions, 74 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 157de3a47832..db107c9bbc05 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -10,76 +10,6 @@
10#include <linux/kernel_stat.h> 10#include <linux/kernel_stat.h>
11 11
12/* 12/*
13 * Allocate the thread_group_cputime structure appropriately and fill in the
14 * current values of the fields. Called from copy_signal() via
15 * thread_group_cputime_clone_thread() when adding a second or subsequent
16 * thread to a thread group. Assumes interrupts are enabled when called.
17 */
18int thread_group_cputime_alloc(struct task_struct *tsk)
19{
20 struct signal_struct *sig = tsk->signal;
21 struct task_cputime *cputime;
22
23 /*
24 * If we have multiple threads and we don't already have a
25 * per-CPU task_cputime struct (checked in the caller), allocate
26 * one and fill it in with the times accumulated so far. We may
27 * race with another thread so recheck after we pick up the sighand
28 * lock.
29 */
30 cputime = alloc_percpu(struct task_cputime);
31 if (cputime == NULL)
32 return -ENOMEM;
33 spin_lock_irq(&tsk->sighand->siglock);
34 if (sig->cputime.totals) {
35 spin_unlock_irq(&tsk->sighand->siglock);
36 free_percpu(cputime);
37 return 0;
38 }
39 sig->cputime.totals = cputime;
40 cputime = per_cpu_ptr(sig->cputime.totals, smp_processor_id());
41 cputime->utime = tsk->utime;
42 cputime->stime = tsk->stime;
43 cputime->sum_exec_runtime = tsk->se.sum_exec_runtime;
44 spin_unlock_irq(&tsk->sighand->siglock);
45 return 0;
46}
47
48/**
49 * thread_group_cputime - Sum the thread group time fields across all CPUs.
50 *
51 * @tsk: The task we use to identify the thread group.
52 * @times: task_cputime structure in which we return the summed fields.
53 *
54 * Walk the list of CPUs to sum the per-CPU time fields in the thread group
55 * time structure.
56 */
57void thread_group_cputime(
58 struct task_struct *tsk,
59 struct task_cputime *times)
60{
61 struct task_cputime *totals, *tot;
62 int i;
63
64 totals = tsk->signal->cputime.totals;
65 if (!totals) {
66 times->utime = tsk->utime;
67 times->stime = tsk->stime;
68 times->sum_exec_runtime = tsk->se.sum_exec_runtime;
69 return;
70 }
71
72 times->stime = times->utime = cputime_zero;
73 times->sum_exec_runtime = 0;
74 for_each_possible_cpu(i) {
75 tot = per_cpu_ptr(totals, i);
76 times->utime = cputime_add(times->utime, tot->utime);
77 times->stime = cputime_add(times->stime, tot->stime);
78 times->sum_exec_runtime += tot->sum_exec_runtime;
79 }
80}
81
82/*
83 * Called after updating RLIMIT_CPU to set timer expiration if necessary. 13 * Called after updating RLIMIT_CPU to set timer expiration if necessary.
84 */ 14 */
85void update_rlimit_cpu(unsigned long rlim_new) 15void update_rlimit_cpu(unsigned long rlim_new)
@@ -300,6 +230,37 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
300 return 0; 230 return 0;
301} 231}
302 232
233void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
234{
235 struct sighand_struct *sighand;
236 struct signal_struct *sig;
237 struct task_struct *t;
238
239 *times = INIT_CPUTIME;
240
241 rcu_read_lock();
242 sighand = rcu_dereference(tsk->sighand);
243 if (!sighand)
244 goto out;
245
246 sig = tsk->signal;
247
248 t = tsk;
249 do {
250 times->utime = cputime_add(times->utime, t->utime);
251 times->stime = cputime_add(times->stime, t->stime);
252 times->sum_exec_runtime += t->se.sum_exec_runtime;
253
254 t = next_thread(t);
255 } while (t != tsk);
256
257 times->utime = cputime_add(times->utime, sig->utime);
258 times->stime = cputime_add(times->stime, sig->stime);
259 times->sum_exec_runtime += sig->sum_sched_runtime;
260out:
261 rcu_read_unlock();
262}
263
303/* 264/*
304 * Sample a process (thread group) clock for the given group_leader task. 265 * Sample a process (thread group) clock for the given group_leader task.
305 * Must be called with tasklist_lock held for reading. 266 * Must be called with tasklist_lock held for reading.
@@ -546,6 +507,29 @@ static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
546} 507}
547 508
548/* 509/*
510 * Enable the process wide cpu timer accounting.
511 *
512 * serialized using ->sighand->siglock
513 */
514static void start_process_timers(struct task_struct *tsk)
515{
516 tsk->signal->cputimer.running = 1;
517 barrier();
518}
519
520/*
521 * Release the process wide timer accounting -- timer stops ticking when
522 * nobody cares about it.
523 *
524 * serialized using ->sighand->siglock
525 */
526static void stop_process_timers(struct task_struct *tsk)
527{
528 tsk->signal->cputimer.running = 0;
529 barrier();
530}
531
532/*
549 * Insert the timer on the appropriate list before any timers that 533 * Insert the timer on the appropriate list before any timers that
550 * expire later. This must be called with the tasklist_lock held 534 * expire later. This must be called with the tasklist_lock held
551 * for reading, and interrupts disabled. 535 * for reading, and interrupts disabled.
@@ -565,6 +549,9 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
565 BUG_ON(!irqs_disabled()); 549 BUG_ON(!irqs_disabled());
566 spin_lock(&p->sighand->siglock); 550 spin_lock(&p->sighand->siglock);
567 551
552 if (!CPUCLOCK_PERTHREAD(timer->it_clock))
553 start_process_timers(p);
554
568 listpos = head; 555 listpos = head;
569 if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) { 556 if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {
570 list_for_each_entry(next, head, entry) { 557 list_for_each_entry(next, head, entry) {
@@ -1057,13 +1044,15 @@ static void check_process_timers(struct task_struct *tsk,
1057 sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && 1044 sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
1058 list_empty(&timers[CPUCLOCK_VIRT]) && 1045 list_empty(&timers[CPUCLOCK_VIRT]) &&
1059 cputime_eq(sig->it_virt_expires, cputime_zero) && 1046 cputime_eq(sig->it_virt_expires, cputime_zero) &&
1060 list_empty(&timers[CPUCLOCK_SCHED])) 1047 list_empty(&timers[CPUCLOCK_SCHED])) {
1048 stop_process_timers(tsk);
1061 return; 1049 return;
1050 }
1062 1051
1063 /* 1052 /*
1064 * Collect the current process totals. 1053 * Collect the current process totals.
1065 */ 1054 */
1066 thread_group_cputime(tsk, &cputime); 1055 thread_group_cputimer(tsk, &cputime);
1067 utime = cputime.utime; 1056 utime = cputime.utime;
1068 ptime = cputime_add(utime, cputime.stime); 1057 ptime = cputime_add(utime, cputime.stime);
1069 sum_sched_runtime = cputime.sum_exec_runtime; 1058 sum_sched_runtime = cputime.sum_exec_runtime;
@@ -1329,7 +1318,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
1329 if (!task_cputime_zero(&sig->cputime_expires)) { 1318 if (!task_cputime_zero(&sig->cputime_expires)) {
1330 struct task_cputime group_sample; 1319 struct task_cputime group_sample;
1331 1320
1332 thread_group_cputime(tsk, &group_sample); 1321 thread_group_cputimer(tsk, &group_sample);
1333 if (task_cputime_expired(&group_sample, &sig->cputime_expires)) 1322 if (task_cputime_expired(&group_sample, &sig->cputime_expires))
1334 return 1; 1323 return 1;
1335 } 1324 }
@@ -1399,6 +1388,33 @@ void run_posix_cpu_timers(struct task_struct *tsk)
1399} 1388}
1400 1389
1401/* 1390/*
1391 * Sample a process (thread group) timer for the given group_leader task.
1392 * Must be called with tasklist_lock held for reading.
1393 */
1394static int cpu_timer_sample_group(const clockid_t which_clock,
1395 struct task_struct *p,
1396 union cpu_time_count *cpu)
1397{
1398 struct task_cputime cputime;
1399
1400 thread_group_cputimer(p, &cputime);
1401 switch (CPUCLOCK_WHICH(which_clock)) {
1402 default:
1403 return -EINVAL;
1404 case CPUCLOCK_PROF:
1405 cpu->cpu = cputime_add(cputime.utime, cputime.stime);
1406 break;
1407 case CPUCLOCK_VIRT:
1408 cpu->cpu = cputime.utime;
1409 break;
1410 case CPUCLOCK_SCHED:
1411 cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
1412 break;
1413 }
1414 return 0;
1415}
1416
1417/*
1402 * Set one of the process-wide special case CPU timers. 1418 * Set one of the process-wide special case CPU timers.
1403 * The tsk->sighand->siglock must be held by the caller. 1419 * The tsk->sighand->siglock must be held by the caller.
1404 * The *newval argument is relative and we update it to be absolute, *oldval 1420 * The *newval argument is relative and we update it to be absolute, *oldval
@@ -1411,7 +1427,8 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
1411 struct list_head *head; 1427 struct list_head *head;
1412 1428
1413 BUG_ON(clock_idx == CPUCLOCK_SCHED); 1429 BUG_ON(clock_idx == CPUCLOCK_SCHED);
1414 cpu_clock_sample_group(clock_idx, tsk, &now); 1430 start_process_timers(tsk);
1431 cpu_timer_sample_group(clock_idx, tsk, &now);
1415 1432
1416 if (oldval) { 1433 if (oldval) {
1417 if (!cputime_eq(*oldval, cputime_zero)) { 1434 if (!cputime_eq(*oldval, cputime_zero)) {