summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2016-11-14 21:06:51 -0500
committerIngo Molnar <mingo@kernel.org>2016-11-15 03:51:05 -0500
commit40565b5aedd6d0ca88b7dfd3859d709d2f6f8cf9 (patch)
tree5fc1766834a640d3ae404c463ba99c3194eba8c7
parent981ee2d444408fc55b9390d6a4a54a6697513611 (diff)
sched/cputime, powerpc, s390: Make scaled cputime arch specific
Only s390 and powerpc have hardware facilities allowing to measure cputimes scaled by frequency. On all other architectures utimescaled/stimescaled are equal to utime/stime (however they are accounted separately). Remove {u,s}timescaled accounting on all architectures except powerpc and s390, where those values are explicitly accounted in the proper places. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Michael Neuling <mikey@neuling.org> Cc: Paul Mackerras <paulus@ozlabs.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20161031162143.GB12646@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/ia64/kernel/time.c4
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/kernel/time.c6
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/kernel/vtime.c9
-rw-r--r--include/linux/kernel_stat.h4
-rw-r--r--include/linux/sched.h23
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sched/cputime.c61
10 files changed, 53 insertions, 61 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 659bdd079277..abab6590f08f 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -512,6 +512,9 @@ config HAVE_CONTEXT_TRACKING
512config HAVE_VIRT_CPU_ACCOUNTING 512config HAVE_VIRT_CPU_ACCOUNTING
513 bool 513 bool
514 514
515config ARCH_HAS_SCALED_CPUTIME
516 bool
517
515config HAVE_VIRT_CPU_ACCOUNTING_GEN 518config HAVE_VIRT_CPU_ACCOUNTING_GEN
516 bool 519 bool
517 default y if 64BIT 520 default y if 64BIT
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 6f892b94e906..021f44ab4bfb 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -68,7 +68,7 @@ void vtime_account_user(struct task_struct *tsk)
68 68
69 if (ti->ac_utime) { 69 if (ti->ac_utime) {
70 delta_utime = cycle_to_cputime(ti->ac_utime); 70 delta_utime = cycle_to_cputime(ti->ac_utime);
71 account_user_time(tsk, delta_utime, delta_utime); 71 account_user_time(tsk, delta_utime);
72 ti->ac_utime = 0; 72 ti->ac_utime = 0;
73 } 73 }
74} 74}
@@ -112,7 +112,7 @@ void vtime_account_system(struct task_struct *tsk)
112{ 112{
113 cputime_t delta = vtime_delta(tsk); 113 cputime_t delta = vtime_delta(tsk);
114 114
115 account_system_time(tsk, 0, delta, delta); 115 account_system_time(tsk, 0, delta);
116} 116}
117EXPORT_SYMBOL_GPL(vtime_account_system); 117EXPORT_SYMBOL_GPL(vtime_account_system);
118 118
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 65fba4c34cd7..c7f120aaa98f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -160,6 +160,7 @@ config PPC
160 select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS 160 select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
161 select GENERIC_CPU_AUTOPROBE 161 select GENERIC_CPU_AUTOPROBE
162 select HAVE_VIRT_CPU_ACCOUNTING 162 select HAVE_VIRT_CPU_ACCOUNTING
163 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
163 select HAVE_ARCH_HARDENED_USERCOPY 164 select HAVE_ARCH_HARDENED_USERCOPY
164 select HAVE_KERNEL_GZIP 165 select HAVE_KERNEL_GZIP
165 166
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 81051986739c..be9751f1cb2a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -358,7 +358,8 @@ void vtime_account_system(struct task_struct *tsk)
358 unsigned long delta, sys_scaled, stolen; 358 unsigned long delta, sys_scaled, stolen;
359 359
360 delta = vtime_delta(tsk, &sys_scaled, &stolen); 360 delta = vtime_delta(tsk, &sys_scaled, &stolen);
361 account_system_time(tsk, 0, delta, sys_scaled); 361 account_system_time(tsk, 0, delta);
362 tsk->stimescaled += sys_scaled;
362 if (stolen) 363 if (stolen)
363 account_steal_time(stolen); 364 account_steal_time(stolen);
364} 365}
@@ -391,7 +392,8 @@ void vtime_account_user(struct task_struct *tsk)
391 acct->user_time = 0; 392 acct->user_time = 0;
392 acct->user_time_scaled = 0; 393 acct->user_time_scaled = 0;
393 acct->utime_sspurr = 0; 394 acct->utime_sspurr = 0;
394 account_user_time(tsk, utime, utimescaled); 395 account_user_time(tsk, utime);
396 tsk->utimescaled += utimescaled;
395} 397}
396 398
397#ifdef CONFIG_PPC32 399#ifdef CONFIG_PPC32
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 426481d4cc86..028f97be5bae 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -171,6 +171,7 @@ config S390
171 select SYSCTL_EXCEPTION_TRACE 171 select SYSCTL_EXCEPTION_TRACE
172 select TTY 172 select TTY
173 select VIRT_CPU_ACCOUNTING 173 select VIRT_CPU_ACCOUNTING
174 select ARCH_HAS_SCALED_CPUTIME
174 select VIRT_TO_BUS 175 select VIRT_TO_BUS
175 select HAVE_NMI 176 select HAVE_NMI
176 177
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 856e30d8463f..1bd5dde2d5a9 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -137,8 +137,10 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
137 user_scaled = (user_scaled * mult) / div; 137 user_scaled = (user_scaled * mult) / div;
138 system_scaled = (system_scaled * mult) / div; 138 system_scaled = (system_scaled * mult) / div;
139 } 139 }
140 account_user_time(tsk, user, user_scaled); 140 account_user_time(tsk, user);
141 account_system_time(tsk, hardirq_offset, system, system_scaled); 141 tsk->utimescaled += user_scaled;
142 account_system_time(tsk, hardirq_offset, system);
143 tsk->stimescaled += system_scaled;
142 144
143 steal = S390_lowcore.steal_timer; 145 steal = S390_lowcore.steal_timer;
144 if ((s64) steal > 0) { 146 if ((s64) steal > 0) {
@@ -202,7 +204,8 @@ void vtime_account_irq_enter(struct task_struct *tsk)
202 204
203 system_scaled = (system_scaled * mult) / div; 205 system_scaled = (system_scaled * mult) / div;
204 } 206 }
205 account_system_time(tsk, 0, system, system_scaled); 207 account_system_time(tsk, 0, system);
208 tsk->stimescaled += system_scaled;
206 209
207 virt_timer_forward(system); 210 virt_timer_forward(system);
208} 211}
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 44fda64ad434..00f776816aa3 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -78,8 +78,8 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
78 return kstat_cpu(cpu).irqs_sum; 78 return kstat_cpu(cpu).irqs_sum;
79} 79}
80 80
81extern void account_user_time(struct task_struct *, cputime_t, cputime_t); 81extern void account_user_time(struct task_struct *, cputime_t);
82extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); 82extern void account_system_time(struct task_struct *, int, cputime_t);
83extern void account_steal_time(cputime_t); 83extern void account_steal_time(cputime_t);
84extern void account_idle_time(cputime_t); 84extern void account_idle_time(cputime_t);
85 85
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 3762fe4e3a80..f72e81395dac 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1647,7 +1647,10 @@ struct task_struct {
1647 int __user *set_child_tid; /* CLONE_CHILD_SETTID */ 1647 int __user *set_child_tid; /* CLONE_CHILD_SETTID */
1648 int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ 1648 int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
1649 1649
1650 cputime_t utime, stime, utimescaled, stimescaled; 1650 cputime_t utime, stime;
1651#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
1652 cputime_t utimescaled, stimescaled;
1653#endif
1651 cputime_t gtime; 1654 cputime_t gtime;
1652 struct prev_cputime prev_cputime; 1655 struct prev_cputime prev_cputime;
1653#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 1656#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
@@ -2240,8 +2243,6 @@ struct task_struct *try_get_task_struct(struct task_struct **ptask);
2240#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 2243#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
2241extern void task_cputime(struct task_struct *t, 2244extern void task_cputime(struct task_struct *t,
2242 cputime_t *utime, cputime_t *stime); 2245 cputime_t *utime, cputime_t *stime);
2243extern void task_cputime_scaled(struct task_struct *t,
2244 cputime_t *utimescaled, cputime_t *stimescaled);
2245extern cputime_t task_gtime(struct task_struct *t); 2246extern cputime_t task_gtime(struct task_struct *t);
2246#else 2247#else
2247static inline void task_cputime(struct task_struct *t, 2248static inline void task_cputime(struct task_struct *t,
@@ -2253,6 +2254,13 @@ static inline void task_cputime(struct task_struct *t,
2253 *stime = t->stime; 2254 *stime = t->stime;
2254} 2255}
2255 2256
2257static inline cputime_t task_gtime(struct task_struct *t)
2258{
2259 return t->gtime;
2260}
2261#endif
2262
2263#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2256static inline void task_cputime_scaled(struct task_struct *t, 2264static inline void task_cputime_scaled(struct task_struct *t,
2257 cputime_t *utimescaled, 2265 cputime_t *utimescaled,
2258 cputime_t *stimescaled) 2266 cputime_t *stimescaled)
@@ -2262,12 +2270,15 @@ static inline void task_cputime_scaled(struct task_struct *t,
2262 if (stimescaled) 2270 if (stimescaled)
2263 *stimescaled = t->stimescaled; 2271 *stimescaled = t->stimescaled;
2264} 2272}
2265 2273#else
2266static inline cputime_t task_gtime(struct task_struct *t) 2274static inline void task_cputime_scaled(struct task_struct *t,
2275 cputime_t *utimescaled,
2276 cputime_t *stimescaled)
2267{ 2277{
2268 return t->gtime; 2278 task_cputime(t, utimescaled, stimescaled);
2269} 2279}
2270#endif 2280#endif
2281
2271extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); 2282extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
2272extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); 2283extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
2273 2284
diff --git a/kernel/fork.c b/kernel/fork.c
index 997ac1d584f7..600e93b5e539 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1551,7 +1551,9 @@ static __latent_entropy struct task_struct *copy_process(
1551 init_sigpending(&p->pending); 1551 init_sigpending(&p->pending);
1552 1552
1553 p->utime = p->stime = p->gtime = 0; 1553 p->utime = p->stime = p->gtime = 0;
1554#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
1554 p->utimescaled = p->stimescaled = 0; 1555 p->utimescaled = p->stimescaled = 0;
1556#endif
1555 prev_cputime_init(&p->prev_cputime); 1557 prev_cputime_init(&p->prev_cputime);
1556 1558
1557#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 1559#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 3229c7244fdd..ba55ebf77f9a 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -128,16 +128,13 @@ static inline void task_group_account_field(struct task_struct *p, int index,
128 * Account user cpu time to a process. 128 * Account user cpu time to a process.
129 * @p: the process that the cpu time gets accounted to 129 * @p: the process that the cpu time gets accounted to
130 * @cputime: the cpu time spent in user space since the last update 130 * @cputime: the cpu time spent in user space since the last update
131 * @cputime_scaled: cputime scaled by cpu frequency
132 */ 131 */
133void account_user_time(struct task_struct *p, cputime_t cputime, 132void account_user_time(struct task_struct *p, cputime_t cputime)
134 cputime_t cputime_scaled)
135{ 133{
136 int index; 134 int index;
137 135
138 /* Add user time to process. */ 136 /* Add user time to process. */
139 p->utime += cputime; 137 p->utime += cputime;
140 p->utimescaled += cputime_scaled;
141 account_group_user_time(p, cputime); 138 account_group_user_time(p, cputime);
142 139
143 index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER; 140 index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
@@ -153,16 +150,13 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
153 * Account guest cpu time to a process. 150 * Account guest cpu time to a process.
154 * @p: the process that the cpu time gets accounted to 151 * @p: the process that the cpu time gets accounted to
155 * @cputime: the cpu time spent in virtual machine since the last update 152 * @cputime: the cpu time spent in virtual machine since the last update
156 * @cputime_scaled: cputime scaled by cpu frequency
157 */ 153 */
158static void account_guest_time(struct task_struct *p, cputime_t cputime, 154static void account_guest_time(struct task_struct *p, cputime_t cputime)
159 cputime_t cputime_scaled)
160{ 155{
161 u64 *cpustat = kcpustat_this_cpu->cpustat; 156 u64 *cpustat = kcpustat_this_cpu->cpustat;
162 157
163 /* Add guest time to process. */ 158 /* Add guest time to process. */
164 p->utime += cputime; 159 p->utime += cputime;
165 p->utimescaled += cputime_scaled;
166 account_group_user_time(p, cputime); 160 account_group_user_time(p, cputime);
167 p->gtime += cputime; 161 p->gtime += cputime;
168 162
@@ -180,16 +174,13 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
180 * Account system cpu time to a process and desired cpustat field 174 * Account system cpu time to a process and desired cpustat field
181 * @p: the process that the cpu time gets accounted to 175 * @p: the process that the cpu time gets accounted to
182 * @cputime: the cpu time spent in kernel space since the last update 176 * @cputime: the cpu time spent in kernel space since the last update
183 * @cputime_scaled: cputime scaled by cpu frequency 177 * @index: pointer to cpustat field that has to be updated
184 * @target_cputime64: pointer to cpustat field that has to be updated
185 */ 178 */
186static inline 179static inline
187void __account_system_time(struct task_struct *p, cputime_t cputime, 180void __account_system_time(struct task_struct *p, cputime_t cputime, int index)
188 cputime_t cputime_scaled, int index)
189{ 181{
190 /* Add system time to process. */ 182 /* Add system time to process. */
191 p->stime += cputime; 183 p->stime += cputime;
192 p->stimescaled += cputime_scaled;
193 account_group_system_time(p, cputime); 184 account_group_system_time(p, cputime);
194 185
195 /* Add system time to cpustat. */ 186 /* Add system time to cpustat. */
@@ -204,15 +195,14 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
204 * @p: the process that the cpu time gets accounted to 195 * @p: the process that the cpu time gets accounted to
205 * @hardirq_offset: the offset to subtract from hardirq_count() 196 * @hardirq_offset: the offset to subtract from hardirq_count()
206 * @cputime: the cpu time spent in kernel space since the last update 197 * @cputime: the cpu time spent in kernel space since the last update
207 * @cputime_scaled: cputime scaled by cpu frequency
208 */ 198 */
209void account_system_time(struct task_struct *p, int hardirq_offset, 199void account_system_time(struct task_struct *p, int hardirq_offset,
210 cputime_t cputime, cputime_t cputime_scaled) 200 cputime_t cputime)
211{ 201{
212 int index; 202 int index;
213 203
214 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { 204 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
215 account_guest_time(p, cputime, cputime_scaled); 205 account_guest_time(p, cputime);
216 return; 206 return;
217 } 207 }
218 208
@@ -223,7 +213,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
223 else 213 else
224 index = CPUTIME_SYSTEM; 214 index = CPUTIME_SYSTEM;
225 215
226 __account_system_time(p, cputime, cputime_scaled, index); 216 __account_system_time(p, cputime, index);
227} 217}
228 218
229/* 219/*
@@ -410,15 +400,15 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
410 * So, we have to handle it separately here. 400 * So, we have to handle it separately here.
411 * Also, p->stime needs to be updated for ksoftirqd. 401 * Also, p->stime needs to be updated for ksoftirqd.
412 */ 402 */
413 __account_system_time(p, cputime, cputime, CPUTIME_SOFTIRQ); 403 __account_system_time(p, cputime, CPUTIME_SOFTIRQ);
414 } else if (user_tick) { 404 } else if (user_tick) {
415 account_user_time(p, cputime, cputime); 405 account_user_time(p, cputime);
416 } else if (p == rq->idle) { 406 } else if (p == rq->idle) {
417 account_idle_time(cputime); 407 account_idle_time(cputime);
418 } else if (p->flags & PF_VCPU) { /* System time or guest time */ 408 } else if (p->flags & PF_VCPU) { /* System time or guest time */
419 account_guest_time(p, cputime, cputime); 409 account_guest_time(p, cputime);
420 } else { 410 } else {
421 __account_system_time(p, cputime, cputime, CPUTIME_SYSTEM); 411 __account_system_time(p, cputime, CPUTIME_SYSTEM);
422 } 412 }
423} 413}
424 414
@@ -521,9 +511,9 @@ void account_process_tick(struct task_struct *p, int user_tick)
521 cputime -= steal; 511 cputime -= steal;
522 512
523 if (user_tick) 513 if (user_tick)
524 account_user_time(p, cputime, cputime); 514 account_user_time(p, cputime);
525 else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) 515 else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET))
526 account_system_time(p, HARDIRQ_OFFSET, cputime, cputime); 516 account_system_time(p, HARDIRQ_OFFSET, cputime);
527 else 517 else
528 account_idle_time(cputime); 518 account_idle_time(cputime);
529} 519}
@@ -744,7 +734,7 @@ static void __vtime_account_system(struct task_struct *tsk)
744{ 734{
745 cputime_t delta_cpu = get_vtime_delta(tsk); 735 cputime_t delta_cpu = get_vtime_delta(tsk);
746 736
747 account_system_time(tsk, irq_count(), delta_cpu, delta_cpu); 737 account_system_time(tsk, irq_count(), delta_cpu);
748} 738}
749 739
750void vtime_account_system(struct task_struct *tsk) 740void vtime_account_system(struct task_struct *tsk)
@@ -765,7 +755,7 @@ void vtime_account_user(struct task_struct *tsk)
765 tsk->vtime_snap_whence = VTIME_SYS; 755 tsk->vtime_snap_whence = VTIME_SYS;
766 if (vtime_delta(tsk)) { 756 if (vtime_delta(tsk)) {
767 delta_cpu = get_vtime_delta(tsk); 757 delta_cpu = get_vtime_delta(tsk);
768 account_user_time(tsk, delta_cpu, delta_cpu); 758 account_user_time(tsk, delta_cpu);
769 } 759 }
770 write_seqcount_end(&tsk->vtime_seqcount); 760 write_seqcount_end(&tsk->vtime_seqcount);
771} 761}
@@ -921,25 +911,4 @@ void task_cputime(struct task_struct *t, cputime_t *utime, cputime_t *stime)
921 if (stime) 911 if (stime)
922 *stime += sdelta; 912 *stime += sdelta;
923} 913}
924
925void task_cputime_scaled(struct task_struct *t,
926 cputime_t *utimescaled, cputime_t *stimescaled)
927{
928 cputime_t udelta, sdelta;
929
930 if (!vtime_accounting_enabled()) {
931 if (utimescaled)
932 *utimescaled = t->utimescaled;
933 if (stimescaled)
934 *stimescaled = t->stimescaled;
935 return;
936 }
937
938 fetch_task_cputime(t, utimescaled, stimescaled,
939 &t->utimescaled, &t->stimescaled, &udelta, &sdelta);
940 if (utimescaled)
941 *utimescaled += udelta;
942 if (stimescaled)
943 *stimescaled += sdelta;
944}
945#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ 914#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */