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