|
@@ -282,26 +282,16 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
|
|
|
* Account time for a transition between system, hard irq
|
|
|
* or soft irq state.
|
|
|
*/
|
|
|
-static unsigned long vtime_delta(struct task_struct *tsk,
|
|
|
- unsigned long *stime_scaled,
|
|
|
- unsigned long *steal_time)
|
|
|
+static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct,
|
|
|
+ unsigned long now, unsigned long stime)
|
|
|
{
|
|
|
- unsigned long now, nowscaled, deltascaled;
|
|
|
- unsigned long stime;
|
|
|
+ unsigned long stime_scaled;
|
|
|
+ unsigned long nowscaled, deltascaled;
|
|
|
unsigned long utime, utime_scaled;
|
|
|
- struct cpu_accounting_data *acct = get_accounting(tsk);
|
|
|
|
|
|
- WARN_ON_ONCE(!irqs_disabled());
|
|
|
-
|
|
|
- now = mftb();
|
|
|
nowscaled = read_spurr(now);
|
|
|
- stime = now - acct->starttime;
|
|
|
- acct->starttime = now;
|
|
|
deltascaled = nowscaled - acct->startspurr;
|
|
|
acct->startspurr = nowscaled;
|
|
|
-
|
|
|
- *steal_time = calculate_stolen_time(now);
|
|
|
-
|
|
|
utime = acct->utime - acct->utime_sspurr;
|
|
|
acct->utime_sspurr = acct->utime;
|
|
|
|
|
@@ -315,18 +305,38 @@ static unsigned long vtime_delta(struct task_struct *tsk,
|
|
|
* the user ticks get saved up in paca->user_time_scaled to be
|
|
|
* used by account_process_tick.
|
|
|
*/
|
|
|
- *stime_scaled = stime;
|
|
|
+ stime_scaled = stime;
|
|
|
utime_scaled = utime;
|
|
|
if (deltascaled != stime + utime) {
|
|
|
if (utime) {
|
|
|
- *stime_scaled = deltascaled * stime / (stime + utime);
|
|
|
- utime_scaled = deltascaled - *stime_scaled;
|
|
|
+ stime_scaled = deltascaled * stime / (stime + utime);
|
|
|
+ utime_scaled = deltascaled - stime_scaled;
|
|
|
} else {
|
|
|
- *stime_scaled = deltascaled;
|
|
|
+ stime_scaled = deltascaled;
|
|
|
}
|
|
|
}
|
|
|
acct->utime_scaled += utime_scaled;
|
|
|
|
|
|
+ return stime_scaled;
|
|
|
+}
|
|
|
+
|
|
|
+static unsigned long vtime_delta(struct task_struct *tsk,
|
|
|
+ unsigned long *stime_scaled,
|
|
|
+ unsigned long *steal_time)
|
|
|
+{
|
|
|
+ unsigned long now, stime;
|
|
|
+ struct cpu_accounting_data *acct = get_accounting(tsk);
|
|
|
+
|
|
|
+ WARN_ON_ONCE(!irqs_disabled());
|
|
|
+
|
|
|
+ now = mftb();
|
|
|
+ stime = now - acct->starttime;
|
|
|
+ acct->starttime = now;
|
|
|
+
|
|
|
+ *stime_scaled = vtime_delta_scaled(acct, now, stime);
|
|
|
+
|
|
|
+ *steal_time = calculate_stolen_time(now);
|
|
|
+
|
|
|
return stime;
|
|
|
}
|
|
|
|
|
@@ -365,6 +375,19 @@ void vtime_account_idle(struct task_struct *tsk)
|
|
|
acct->idle_time += stime + steal_time;
|
|
|
}
|
|
|
|
|
|
+static void vtime_flush_scaled(struct task_struct *tsk,
|
|
|
+ struct cpu_accounting_data *acct)
|
|
|
+{
|
|
|
+ if (acct->utime_scaled)
|
|
|
+ tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled);
|
|
|
+ if (acct->stime_scaled)
|
|
|
+ tsk->stimescaled += cputime_to_nsecs(acct->stime_scaled);
|
|
|
+
|
|
|
+ acct->utime_scaled = 0;
|
|
|
+ acct->utime_sspurr = 0;
|
|
|
+ acct->stime_scaled = 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Account the whole cputime accumulated in the paca
|
|
|
* Must be called with interrupts disabled.
|
|
@@ -379,9 +402,6 @@ void vtime_flush(struct task_struct *tsk)
|
|
|
if (acct->utime)
|
|
|
account_user_time(tsk, cputime_to_nsecs(acct->utime));
|
|
|
|
|
|
- if (acct->utime_scaled)
|
|
|
- tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled);
|
|
|
-
|
|
|
if (acct->gtime)
|
|
|
account_guest_time(tsk, cputime_to_nsecs(acct->gtime));
|
|
|
|
|
@@ -394,8 +414,6 @@ void vtime_flush(struct task_struct *tsk)
|
|
|
if (acct->stime)
|
|
|
account_system_index_time(tsk, cputime_to_nsecs(acct->stime),
|
|
|
CPUTIME_SYSTEM);
|
|
|
- if (acct->stime_scaled)
|
|
|
- tsk->stimescaled += cputime_to_nsecs(acct->stime_scaled);
|
|
|
|
|
|
if (acct->hardirq_time)
|
|
|
account_system_index_time(tsk, cputime_to_nsecs(acct->hardirq_time),
|
|
@@ -404,14 +422,13 @@ void vtime_flush(struct task_struct *tsk)
|
|
|
account_system_index_time(tsk, cputime_to_nsecs(acct->softirq_time),
|
|
|
CPUTIME_SOFTIRQ);
|
|
|
|
|
|
+ vtime_flush_scaled(tsk, acct);
|
|
|
+
|
|
|
acct->utime = 0;
|
|
|
- acct->utime_scaled = 0;
|
|
|
- acct->utime_sspurr = 0;
|
|
|
acct->gtime = 0;
|
|
|
acct->steal_time = 0;
|
|
|
acct->idle_time = 0;
|
|
|
acct->stime = 0;
|
|
|
- acct->stime_scaled = 0;
|
|
|
acct->hardirq_time = 0;
|
|
|
acct->softirq_time = 0;
|
|
|
}
|