Blame view
kernel/delayacct.c
4.47 KB
ca74e92b4 [PATCH] per-task-... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* delayacct.c - per-task delay accounting * * Copyright (C) Shailabh Nagar, IBM Corp. 2006 * * 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 would 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. */ #include <linux/sched.h> #include <linux/slab.h> |
6952b61de headers: taskstat... |
18 |
#include <linux/taskstats.h> |
ca74e92b4 [PATCH] per-task-... |
19 20 21 |
#include <linux/time.h> #include <linux/sysctl.h> #include <linux/delayacct.h> |
c9aaa8957 KVM: Steal time i... |
22 |
#include <linux/module.h> |
ca74e92b4 [PATCH] per-task-... |
23 |
|
163ecdff0 [PATCH] delay acc... |
24 |
int delayacct_on __read_mostly = 1; /* Delay accounting turned on/off */ |
c9aaa8957 KVM: Steal time i... |
25 |
EXPORT_SYMBOL_GPL(delayacct_on); |
e18b890bb [PATCH] slab: rem... |
26 |
struct kmem_cache *delayacct_cache; |
ca74e92b4 [PATCH] per-task-... |
27 |
|
163ecdff0 [PATCH] delay acc... |
28 |
static int __init delayacct_setup_disable(char *str) |
ca74e92b4 [PATCH] per-task-... |
29 |
{ |
163ecdff0 [PATCH] delay acc... |
30 |
delayacct_on = 0; |
ca74e92b4 [PATCH] per-task-... |
31 32 |
return 1; } |
163ecdff0 [PATCH] delay acc... |
33 |
__setup("nodelayacct", delayacct_setup_disable); |
ca74e92b4 [PATCH] per-task-... |
34 35 36 |
void delayacct_init(void) { |
5d097056c kmemcg: account c... |
37 |
delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT); |
ca74e92b4 [PATCH] per-task-... |
38 39 40 41 42 |
delayacct_tsk_init(&init_task); } void __delayacct_tsk_init(struct task_struct *tsk) { |
e94b17660 [PATCH] slab: rem... |
43 |
tsk->delays = kmem_cache_zalloc(delayacct_cache, GFP_KERNEL); |
ca74e92b4 [PATCH] per-task-... |
44 45 46 |
if (tsk->delays) spin_lock_init(&tsk->delays->lock); } |
ca74e92b4 [PATCH] per-task-... |
47 |
/* |
9667a23db delayacct: Make a... |
48 49 |
* Finish delay accounting for a statistic using its timestamps (@start), * accumalator (@total) and @count |
ca74e92b4 [PATCH] per-task-... |
50 |
*/ |
9667a23db delayacct: Make a... |
51 |
static void delayacct_end(u64 *start, u64 *total, u32 *count) |
ca74e92b4 [PATCH] per-task-... |
52 |
{ |
9667a23db delayacct: Make a... |
53 |
s64 ns = ktime_get_ns() - *start; |
64efade11 [PATCH] lockdep: ... |
54 |
unsigned long flags; |
ca74e92b4 [PATCH] per-task-... |
55 |
|
9667a23db delayacct: Make a... |
56 57 58 59 60 61 |
if (ns > 0) { spin_lock_irqsave(¤t->delays->lock, flags); *total += ns; (*count)++; spin_unlock_irqrestore(¤t->delays->lock, flags); } |
ca74e92b4 [PATCH] per-task-... |
62 |
} |
0ff922452 [PATCH] per-task-... |
63 64 |
void __delayacct_blkio_start(void) { |
9667a23db delayacct: Make a... |
65 |
current->delays->blkio_start = ktime_get_ns(); |
0ff922452 [PATCH] per-task-... |
66 67 68 69 70 71 72 |
} void __delayacct_blkio_end(void) { if (current->delays->flags & DELAYACCT_PF_SWAPIN) /* Swapin block I/O */ delayacct_end(¤t->delays->blkio_start, |
0ff922452 [PATCH] per-task-... |
73 74 75 76 |
¤t->delays->swapin_delay, ¤t->delays->swapin_count); else /* Other block I/O */ delayacct_end(¤t->delays->blkio_start, |
0ff922452 [PATCH] per-task-... |
77 78 79 |
¤t->delays->blkio_delay, ¤t->delays->blkio_count); } |
6f44993fe [PATCH] per-task-... |
80 81 82 |
int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) { |
6fac4829c cputime: Use acce... |
83 |
cputime_t utime, stime, stimescaled, utimescaled; |
68f6783d2 delayacct: Remove... |
84 85 86 |
unsigned long long t2, t3; unsigned long flags, t1; s64 tmp; |
6f44993fe [PATCH] per-task-... |
87 |
|
6fac4829c cputime: Use acce... |
88 |
task_cputime(tsk, &utime, &stime); |
68f6783d2 delayacct: Remove... |
89 90 |
tmp = (s64)d->cpu_run_real_total; tmp += cputime_to_nsecs(utime + stime); |
6f44993fe [PATCH] per-task-... |
91 |
d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp; |
6fac4829c cputime: Use acce... |
92 |
task_cputime_scaled(tsk, &utimescaled, &stimescaled); |
68f6783d2 delayacct: Remove... |
93 94 |
tmp = (s64)d->cpu_scaled_run_real_total; tmp += cputime_to_nsecs(utimescaled + stimescaled); |
c66f08be7 Add scaled time t... |
95 96 |
d->cpu_scaled_run_real_total = (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp; |
6f44993fe [PATCH] per-task-... |
97 98 99 100 |
/* * No locking available for sched_info (and too expensive to add one) * Mitigate by taking snapshot of values */ |
2d72376b3 sched: clean up s... |
101 |
t1 = tsk->sched_info.pcount; |
6f44993fe [PATCH] per-task-... |
102 |
t2 = tsk->sched_info.run_delay; |
9c2c48020 schedstat: consol... |
103 |
t3 = tsk->se.sum_exec_runtime; |
6f44993fe [PATCH] per-task-... |
104 105 |
d->cpu_count += t1; |
172ba844a sched: update del... |
106 |
tmp = (s64)d->cpu_delay_total + t2; |
6f44993fe [PATCH] per-task-... |
107 |
d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp; |
172ba844a sched: update del... |
108 |
tmp = (s64)d->cpu_run_virtual_total + t3; |
6f44993fe [PATCH] per-task-... |
109 110 111 112 |
d->cpu_run_virtual_total = (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp; /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */ |
64efade11 [PATCH] lockdep: ... |
113 |
spin_lock_irqsave(&tsk->delays->lock, flags); |
6f44993fe [PATCH] per-task-... |
114 115 116 117 |
tmp = d->blkio_delay_total + tsk->delays->blkio_delay; d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp; tmp = d->swapin_delay_total + tsk->delays->swapin_delay; d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp; |
016ae219b per-task-delay-ac... |
118 119 |
tmp = d->freepages_delay_total + tsk->delays->freepages_delay; d->freepages_delay_total = (tmp < d->freepages_delay_total) ? 0 : tmp; |
6f44993fe [PATCH] per-task-... |
120 121 |
d->blkio_count += tsk->delays->blkio_count; d->swapin_count += tsk->delays->swapin_count; |
016ae219b per-task-delay-ac... |
122 |
d->freepages_count += tsk->delays->freepages_count; |
64efade11 [PATCH] lockdep: ... |
123 |
spin_unlock_irqrestore(&tsk->delays->lock, flags); |
6f44993fe [PATCH] per-task-... |
124 |
|
6f44993fe [PATCH] per-task-... |
125 126 |
return 0; } |
258904546 [PATCH] per-task-... |
127 128 129 130 |
__u64 __delayacct_blkio_ticks(struct task_struct *tsk) { __u64 ret; |
64efade11 [PATCH] lockdep: ... |
131 |
unsigned long flags; |
258904546 [PATCH] per-task-... |
132 |
|
64efade11 [PATCH] lockdep: ... |
133 |
spin_lock_irqsave(&tsk->delays->lock, flags); |
258904546 [PATCH] per-task-... |
134 135 |
ret = nsec_to_clock_t(tsk->delays->blkio_delay + tsk->delays->swapin_delay); |
64efade11 [PATCH] lockdep: ... |
136 |
spin_unlock_irqrestore(&tsk->delays->lock, flags); |
258904546 [PATCH] per-task-... |
137 138 |
return ret; } |
873b47717 per-task-delay-ac... |
139 140 |
void __delayacct_freepages_start(void) { |
9667a23db delayacct: Make a... |
141 |
current->delays->freepages_start = ktime_get_ns(); |
873b47717 per-task-delay-ac... |
142 143 144 145 146 |
} void __delayacct_freepages_end(void) { delayacct_end(¤t->delays->freepages_start, |
873b47717 per-task-delay-ac... |
147 148 149 |
¤t->delays->freepages_delay, ¤t->delays->freepages_count); } |