aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2012-11-21 18:58:35 -0500
committerFrederic Weisbecker <fweisbec@gmail.com>2012-11-28 11:08:10 -0500
commitd37f761dbd276790f70dcf73a287fde2c3464482 (patch)
tree302d4bda699ab2e159b3a180f253019a38bf8132
parente80d0a1ae8bb8fee0edd37427836f108b30f596b (diff)
cputime: Consolidate cputime adjustment code
task_cputime_adjusted() and thread_group_cputime_adjusted() essentially share the same code. They just don't use the same source: * The first function uses the cputime in the task struct and the previous adjusted snapshot that ensures monotonicity. * The second adds the cputime of all tasks in the group and the previous adjusted snapshot of the whole group from the signal structure. Just consolidate the common code that does the adjustment. These functions just need to fetch the values from the appropriate source. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--include/linux/sched.h23
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sched/cputime.c46
3 files changed, 43 insertions, 28 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e75cab5820ab..5dafac366811 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -434,13 +434,28 @@ struct cpu_itimer {
434}; 434};
435 435
436/** 436/**
437 * struct cputime - snaphsot of system and user cputime
438 * @utime: time spent in user mode
439 * @stime: time spent in system mode
440 *
441 * Gathers a generic snapshot of user and system time.
442 */
443struct cputime {
444 cputime_t utime;
445 cputime_t stime;
446};
447
448/**
437 * struct task_cputime - collected CPU time counts 449 * struct task_cputime - collected CPU time counts
438 * @utime: time spent in user mode, in &cputime_t units 450 * @utime: time spent in user mode, in &cputime_t units
439 * @stime: time spent in kernel mode, in &cputime_t units 451 * @stime: time spent in kernel mode, in &cputime_t units
440 * @sum_exec_runtime: total time spent on the CPU, in nanoseconds 452 * @sum_exec_runtime: total time spent on the CPU, in nanoseconds
441 * 453 *
442 * This structure groups together three kinds of CPU time that are 454 * This is an extension of struct cputime that includes the total runtime
443 * tracked for threads and thread groups. Most things considering 455 * spent by the task from the scheduler point of view.
456 *
457 * As a result, this structure groups together three kinds of CPU time
458 * that are tracked for threads and thread groups. Most things considering
444 * CPU time want to group these counts together and treat all three 459 * CPU time want to group these counts together and treat all three
445 * of them in parallel. 460 * of them in parallel.
446 */ 461 */
@@ -581,7 +596,7 @@ struct signal_struct {
581 cputime_t gtime; 596 cputime_t gtime;
582 cputime_t cgtime; 597 cputime_t cgtime;
583#ifndef CONFIG_VIRT_CPU_ACCOUNTING 598#ifndef CONFIG_VIRT_CPU_ACCOUNTING
584 cputime_t prev_utime, prev_stime; 599 struct cputime prev_cputime;
585#endif 600#endif
586 unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; 601 unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
587 unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; 602 unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
@@ -1340,7 +1355,7 @@ struct task_struct {
1340 cputime_t utime, stime, utimescaled, stimescaled; 1355 cputime_t utime, stime, utimescaled, stimescaled;
1341 cputime_t gtime; 1356 cputime_t gtime;
1342#ifndef CONFIG_VIRT_CPU_ACCOUNTING 1357#ifndef CONFIG_VIRT_CPU_ACCOUNTING
1343 cputime_t prev_utime, prev_stime; 1358 struct cputime prev_cputime;
1344#endif 1359#endif
1345 unsigned long nvcsw, nivcsw; /* context switch counts */ 1360 unsigned long nvcsw, nivcsw; /* context switch counts */
1346 struct timespec start_time; /* monotonic time */ 1361 struct timespec start_time; /* monotonic time */
diff --git a/kernel/fork.c b/kernel/fork.c
index 8b20ab7d3aa2..0e7cdb90476f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1222,7 +1222,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1222 p->utime = p->stime = p->gtime = 0; 1222 p->utime = p->stime = p->gtime = 0;
1223 p->utimescaled = p->stimescaled = 0; 1223 p->utimescaled = p->stimescaled = 0;
1224#ifndef CONFIG_VIRT_CPU_ACCOUNTING 1224#ifndef CONFIG_VIRT_CPU_ACCOUNTING
1225 p->prev_utime = p->prev_stime = 0; 1225 p->prev_cputime.utime = p->prev_cputime.stime = 0;
1226#endif 1226#endif
1227#if defined(SPLIT_RSS_COUNTING) 1227#if defined(SPLIT_RSS_COUNTING)
1228 memset(&p->rss_stat, 0, sizeof(p->rss_stat)); 1228 memset(&p->rss_stat, 0, sizeof(p->rss_stat));
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 7dc155371b95..220fdc4db770 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -516,14 +516,18 @@ static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total)
516 return (__force cputime_t) temp; 516 return (__force cputime_t) temp;
517} 517}
518 518
519void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st) 519static void cputime_adjust(struct task_cputime *curr,
520 struct cputime *prev,
521 cputime_t *ut, cputime_t *st)
520{ 522{
521 cputime_t rtime, utime = p->utime, total = utime + p->stime; 523 cputime_t rtime, utime, total;
522 524
525 utime = curr->utime;
526 total = utime + curr->stime;
523 /* 527 /*
524 * Use CFS's precise accounting: 528 * Use CFS's precise accounting:
525 */ 529 */
526 rtime = nsecs_to_cputime(p->se.sum_exec_runtime); 530 rtime = nsecs_to_cputime(curr->sum_exec_runtime);
527 531
528 if (total) 532 if (total)
529 utime = scale_utime(utime, rtime, total); 533 utime = scale_utime(utime, rtime, total);
@@ -533,11 +537,22 @@ void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
533 /* 537 /*
534 * Compare with previous values, to keep monotonicity: 538 * Compare with previous values, to keep monotonicity:
535 */ 539 */
536 p->prev_utime = max(p->prev_utime, utime); 540 prev->utime = max(prev->utime, utime);
537 p->prev_stime = max(p->prev_stime, rtime - p->prev_utime); 541 prev->stime = max(prev->stime, rtime - prev->utime);
542
543 *ut = prev->utime;
544 *st = prev->stime;
545}
538 546
539 *ut = p->prev_utime; 547void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
540 *st = p->prev_stime; 548{
549 struct task_cputime cputime = {
550 .utime = p->utime,
551 .stime = p->stime,
552 .sum_exec_runtime = p->se.sum_exec_runtime,
553 };
554
555 cputime_adjust(&cputime, &p->prev_cputime, ut, st);
541} 556}
542 557
543/* 558/*
@@ -545,24 +560,9 @@ void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
545 */ 560 */
546void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st) 561void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
547{ 562{
548 struct signal_struct *sig = p->signal;
549 struct task_cputime cputime; 563 struct task_cputime cputime;
550 cputime_t rtime, utime, total;
551 564
552 thread_group_cputime(p, &cputime); 565 thread_group_cputime(p, &cputime);
553 566 cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st);
554 total = cputime.utime + cputime.stime;
555 rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
556
557 if (total)
558 utime = scale_utime(cputime.utime, rtime, total);
559 else
560 utime = rtime;
561
562 sig->prev_utime = max(sig->prev_utime, utime);
563 sig->prev_stime = max(sig->prev_stime, rtime - sig->prev_utime);
564
565 *ut = sig->prev_utime;
566 *st = sig->prev_stime;
567} 567}
568#endif 568#endif