diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index cc1f81b50b82..c51b5d276665 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4037,23 +4037,56 @@ DEFINE_PER_CPU(struct kernel_stat, kstat); | |||
4037 | EXPORT_PER_CPU_SYMBOL(kstat); | 4037 | EXPORT_PER_CPU_SYMBOL(kstat); |
4038 | 4038 | ||
4039 | /* | 4039 | /* |
4040 | * Return any ns on the sched_clock that have not yet been banked in | ||
4041 | * @p in case that task is currently running. | ||
4042 | * | ||
4043 | * Called with task_rq_lock() held on @rq. | ||
4044 | */ | ||
4045 | static unsigned long long task_delta_exec(struct task_struct *p, struct rq *rq) | ||
4046 | { | ||
4047 | if (task_current(rq, p)) { | ||
4048 | u64 delta_exec; | ||
4049 | |||
4050 | update_rq_clock(rq); | ||
4051 | delta_exec = rq->clock - p->se.exec_start; | ||
4052 | if ((s64)delta_exec > 0) | ||
4053 | return delta_exec; | ||
4054 | } | ||
4055 | return 0; | ||
4056 | } | ||
4057 | |||
4058 | /* | ||
4040 | * Return p->sum_exec_runtime plus any more ns on the sched_clock | 4059 | * Return p->sum_exec_runtime plus any more ns on the sched_clock |
4041 | * that have not yet been banked in case the task is currently running. | 4060 | * that have not yet been banked in case the task is currently running. |
4042 | */ | 4061 | */ |
4043 | unsigned long long task_sched_runtime(struct task_struct *p) | 4062 | unsigned long long task_sched_runtime(struct task_struct *p) |
4044 | { | 4063 | { |
4045 | unsigned long flags; | 4064 | unsigned long flags; |
4046 | u64 ns, delta_exec; | 4065 | u64 ns; |
4047 | struct rq *rq; | 4066 | struct rq *rq; |
4048 | 4067 | ||
4049 | rq = task_rq_lock(p, &flags); | 4068 | rq = task_rq_lock(p, &flags); |
4050 | ns = p->se.sum_exec_runtime; | 4069 | ns = p->se.sum_exec_runtime + task_delta_exec(p, rq); |
4051 | if (task_current(rq, p)) { | 4070 | task_rq_unlock(rq, &flags); |
4052 | update_rq_clock(rq); | 4071 | |
4053 | delta_exec = rq->clock - p->se.exec_start; | 4072 | return ns; |
4054 | if ((s64)delta_exec > 0) | 4073 | } |
4055 | ns += delta_exec; | 4074 | |
4056 | } | 4075 | /* |
4076 | * Return sum_exec_runtime for the thread group plus any more ns on the | ||
4077 | * sched_clock that have not yet been banked in case the task is currently | ||
4078 | * running. | ||
4079 | */ | ||
4080 | unsigned long long thread_group_sched_runtime(struct task_struct *p) | ||
4081 | { | ||
4082 | unsigned long flags; | ||
4083 | u64 ns; | ||
4084 | struct rq *rq; | ||
4085 | struct task_cputime totals; | ||
4086 | |||
4087 | rq = task_rq_lock(p, &flags); | ||
4088 | thread_group_cputime(p, &totals); | ||
4089 | ns = totals.sum_exec_runtime + task_delta_exec(p, rq); | ||
4057 | task_rq_unlock(rq, &flags); | 4090 | task_rq_unlock(rq, &flags); |
4058 | 4091 | ||
4059 | return ns; | 4092 | return ns; |
@@ -4070,6 +4103,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime) | |||
4070 | cputime64_t tmp; | 4103 | cputime64_t tmp; |
4071 | 4104 | ||
4072 | p->utime = cputime_add(p->utime, cputime); | 4105 | p->utime = cputime_add(p->utime, cputime); |
4106 | account_group_user_time(p, cputime); | ||
4073 | 4107 | ||
4074 | /* Add user time to cpustat. */ | 4108 | /* Add user time to cpustat. */ |
4075 | tmp = cputime_to_cputime64(cputime); | 4109 | tmp = cputime_to_cputime64(cputime); |
@@ -4094,6 +4128,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime) | |||
4094 | tmp = cputime_to_cputime64(cputime); | 4128 | tmp = cputime_to_cputime64(cputime); |
4095 | 4129 | ||
4096 | p->utime = cputime_add(p->utime, cputime); | 4130 | p->utime = cputime_add(p->utime, cputime); |
4131 | account_group_user_time(p, cputime); | ||
4097 | p->gtime = cputime_add(p->gtime, cputime); | 4132 | p->gtime = cputime_add(p->gtime, cputime); |
4098 | 4133 | ||
4099 | cpustat->user = cputime64_add(cpustat->user, tmp); | 4134 | cpustat->user = cputime64_add(cpustat->user, tmp); |
@@ -4129,6 +4164,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset, | |||
4129 | } | 4164 | } |
4130 | 4165 | ||
4131 | p->stime = cputime_add(p->stime, cputime); | 4166 | p->stime = cputime_add(p->stime, cputime); |
4167 | account_group_system_time(p, cputime); | ||
4132 | 4168 | ||
4133 | /* Add system time to cpustat. */ | 4169 | /* Add system time to cpustat. */ |
4134 | tmp = cputime_to_cputime64(cputime); | 4170 | tmp = cputime_to_cputime64(cputime); |
@@ -4170,6 +4206,7 @@ void account_steal_time(struct task_struct *p, cputime_t steal) | |||
4170 | 4206 | ||
4171 | if (p == rq->idle) { | 4207 | if (p == rq->idle) { |
4172 | p->stime = cputime_add(p->stime, steal); | 4208 | p->stime = cputime_add(p->stime, steal); |
4209 | account_group_system_time(p, steal); | ||
4173 | if (atomic_read(&rq->nr_iowait) > 0) | 4210 | if (atomic_read(&rq->nr_iowait) > 0) |
4174 | cpustat->iowait = cputime64_add(cpustat->iowait, tmp); | 4211 | cpustat->iowait = cputime64_add(cpustat->iowait, tmp); |
4175 | else | 4212 | else |