diff options
-rw-r--r-- | include/linux/sched.h | 23 | ||||
-rw-r--r-- | kernel/fork.c | 2 | ||||
-rw-r--r-- | kernel/sched/cputime.c | 46 |
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 | */ | ||
443 | struct 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 | ||
519 | void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st) | 519 | static 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; | 547 | void 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 | */ |
546 | void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st) | 561 | void 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 |