aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c80
-rw-r--r--kernel/time/tick-sched.c13
-rw-r--r--kernel/timer.c13
3 files changed, 69 insertions, 37 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 5b03679ff712..635eaffe1e4c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4139,7 +4139,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
4139 cputime_t cputime, cputime_t cputime_scaled) 4139 cputime_t cputime, cputime_t cputime_scaled)
4140{ 4140{
4141 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; 4141 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4142 struct rq *rq = this_rq();
4143 cputime64_t tmp; 4142 cputime64_t tmp;
4144 4143
4145 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { 4144 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
@@ -4158,37 +4157,84 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
4158 cpustat->irq = cputime64_add(cpustat->irq, tmp); 4157 cpustat->irq = cputime64_add(cpustat->irq, tmp);
4159 else if (softirq_count()) 4158 else if (softirq_count())
4160 cpustat->softirq = cputime64_add(cpustat->softirq, tmp); 4159 cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
4161 else if (p != rq->idle)
4162 cpustat->system = cputime64_add(cpustat->system, tmp);
4163 else if (atomic_read(&rq->nr_iowait) > 0)
4164 cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
4165 else 4160 else
4166 cpustat->idle = cputime64_add(cpustat->idle, tmp); 4161 cpustat->system = cputime64_add(cpustat->system, tmp);
4162
4167 /* Account for system time used */ 4163 /* Account for system time used */
4168 acct_update_integrals(p); 4164 acct_update_integrals(p);
4169} 4165}
4170 4166
4171/* 4167/*
4172 * Account for involuntary wait time. 4168 * Account for involuntary wait time.
4173 * @p: the process from which the cpu time has been stolen
4174 * @steal: the cpu time spent in involuntary wait 4169 * @steal: the cpu time spent in involuntary wait
4175 */ 4170 */
4176void account_steal_time(struct task_struct *p, cputime_t steal) 4171void account_steal_time(cputime_t cputime)
4172{
4173 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4174 cputime64_t cputime64 = cputime_to_cputime64(cputime);
4175
4176 cpustat->steal = cputime64_add(cpustat->steal, cputime64);
4177}
4178
4179/*
4180 * Account for idle time.
4181 * @cputime: the cpu time spent in idle wait
4182 */
4183void account_idle_time(cputime_t cputime)
4177{ 4184{
4178 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; 4185 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
4179 cputime64_t tmp = cputime_to_cputime64(steal); 4186 cputime64_t cputime64 = cputime_to_cputime64(cputime);
4180 struct rq *rq = this_rq(); 4187 struct rq *rq = this_rq();
4181 4188
4182 if (p == rq->idle) { 4189 if (atomic_read(&rq->nr_iowait) > 0)
4183 p->stime = cputime_add(p->stime, steal); 4190 cpustat->iowait = cputime64_add(cpustat->iowait, cputime64);
4184 if (atomic_read(&rq->nr_iowait) > 0) 4191 else
4185 cpustat->iowait = cputime64_add(cpustat->iowait, tmp); 4192 cpustat->idle = cputime64_add(cpustat->idle, cputime64);
4186 else 4193}
4187 cpustat->idle = cputime64_add(cpustat->idle, tmp); 4194
4188 } else 4195#ifndef CONFIG_VIRT_CPU_ACCOUNTING
4189 cpustat->steal = cputime64_add(cpustat->steal, tmp); 4196
4197/*
4198 * Account a single tick of cpu time.
4199 * @p: the process that the cpu time gets accounted to
4200 * @user_tick: indicates if the tick is a user or a system tick
4201 */
4202void account_process_tick(struct task_struct *p, int user_tick)
4203{
4204 cputime_t one_jiffy = jiffies_to_cputime(1);
4205 cputime_t one_jiffy_scaled = cputime_to_scaled(one_jiffy);
4206 struct rq *rq = this_rq();
4207
4208 if (user_tick)
4209 account_user_time(p, one_jiffy, one_jiffy_scaled);
4210 else if (p != rq->idle)
4211 account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
4212 one_jiffy_scaled);
4213 else
4214 account_idle_time(one_jiffy);
4215}
4216
4217/*
4218 * Account multiple ticks of steal time.
4219 * @p: the process from which the cpu time has been stolen
4220 * @ticks: number of stolen ticks
4221 */
4222void account_steal_ticks(unsigned long ticks)
4223{
4224 account_steal_time(jiffies_to_cputime(ticks));
4225}
4226
4227/*
4228 * Account multiple ticks of idle time.
4229 * @ticks: number of stolen ticks
4230 */
4231void account_idle_ticks(unsigned long ticks)
4232{
4233 account_idle_time(jiffies_to_cputime(ticks));
4190} 4234}
4191 4235
4236#endif
4237
4192/* 4238/*
4193 * Use precise platform statistics if available: 4239 * Use precise platform statistics if available:
4194 */ 4240 */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 1f2fce2479fe..611fa4c0baab 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -419,8 +419,9 @@ void tick_nohz_restart_sched_tick(void)
419{ 419{
420 int cpu = smp_processor_id(); 420 int cpu = smp_processor_id();
421 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 421 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
422#ifndef CONFIG_VIRT_CPU_ACCOUNTING
422 unsigned long ticks; 423 unsigned long ticks;
423 cputime_t cputime; 424#endif
424 ktime_t now; 425 ktime_t now;
425 426
426 local_irq_disable(); 427 local_irq_disable();
@@ -442,6 +443,7 @@ void tick_nohz_restart_sched_tick(void)
442 tick_do_update_jiffies64(now); 443 tick_do_update_jiffies64(now);
443 cpu_clear(cpu, nohz_cpu_mask); 444 cpu_clear(cpu, nohz_cpu_mask);
444 445
446#ifndef CONFIG_VIRT_CPU_ACCOUNTING
445 /* 447 /*
446 * We stopped the tick in idle. Update process times would miss the 448 * We stopped the tick in idle. Update process times would miss the
447 * time we slept as update_process_times does only a 1 tick 449 * time we slept as update_process_times does only a 1 tick
@@ -451,12 +453,9 @@ void tick_nohz_restart_sched_tick(void)
451 /* 453 /*
452 * We might be one off. Do not randomly account a huge number of ticks! 454 * We might be one off. Do not randomly account a huge number of ticks!
453 */ 455 */
454 if (ticks && ticks < LONG_MAX) { 456 if (ticks && ticks < LONG_MAX)
455 add_preempt_count(HARDIRQ_OFFSET); 457 account_idle_ticks(ticks);
456 cputime = jiffies_to_cputime(ticks); 458#endif
457 account_system_time(current, HARDIRQ_OFFSET, cputime, cputime);
458 sub_preempt_count(HARDIRQ_OFFSET);
459 }
460 459
461 touch_softlockup_watchdog(); 460 touch_softlockup_watchdog();
462 /* 461 /*
diff --git a/kernel/timer.c b/kernel/timer.c
index b5efb528aa1d..dee3f641a7a7 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1018,19 +1018,6 @@ unsigned long get_next_timer_interrupt(unsigned long now)
1018} 1018}
1019#endif 1019#endif
1020 1020
1021#ifndef CONFIG_VIRT_CPU_ACCOUNTING
1022void account_process_tick(struct task_struct *p, int user_tick)
1023{
1024 cputime_t one_jiffy = jiffies_to_cputime(1);
1025
1026 if (user_tick)
1027 account_user_time(p, one_jiffy, cputime_to_scaled(one_jiffy));
1028 else
1029 account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
1030 cputime_to_scaled(one_jiffy));
1031}
1032#endif
1033
1034/* 1021/*
1035 * Called from the timer interrupt handler to charge one tick to the current 1022 * Called from the timer interrupt handler to charge one tick to the current
1036 * process. user_tick is 1 if the tick is user time, 0 for system. 1023 * process. user_tick is 1 if the tick is user time, 0 for system.