aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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