]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/time.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[karo-tx-linux.git] / arch / powerpc / kernel / time.c
index bd693a11d86edafe0cc84684a0198678271ec8a0..c9986fd400d89947966d4e94746f8d8c9913b7a2 100644 (file)
@@ -291,13 +291,12 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
-void account_system_vtime(struct task_struct *tsk)
+static u64 vtime_delta(struct task_struct *tsk,
+                       u64 *sys_scaled, u64 *stolen)
 {
-       u64 now, nowscaled, delta, deltascaled;
-       unsigned long flags;
-       u64 stolen, udelta, sys_scaled, user_scaled;
+       u64 now, nowscaled, deltascaled;
+       u64 udelta, delta, user_scaled;
 
-       local_irq_save(flags);
        now = mftb();
        nowscaled = read_spurr(now);
        get_paca()->system_time += now - get_paca()->starttime;
@@ -305,7 +304,7 @@ void account_system_vtime(struct task_struct *tsk)
        deltascaled = nowscaled - get_paca()->startspurr;
        get_paca()->startspurr = nowscaled;
 
-       stolen = calculate_stolen_time(now);
+       *stolen = calculate_stolen_time(now);
 
        delta = get_paca()->system_time;
        get_paca()->system_time = 0;
@@ -322,35 +321,45 @@ void account_system_vtime(struct task_struct *tsk)
         * the user ticks get saved up in paca->user_time_scaled to be
         * used by account_process_tick.
         */
-       sys_scaled = delta;
+       *sys_scaled = delta;
        user_scaled = udelta;
        if (deltascaled != delta + udelta) {
                if (udelta) {
-                       sys_scaled = deltascaled * delta / (delta + udelta);
-                       user_scaled = deltascaled - sys_scaled;
+                       *sys_scaled = deltascaled * delta / (delta + udelta);
+                       user_scaled = deltascaled - *sys_scaled;
                } else {
-                       sys_scaled = deltascaled;
+                       *sys_scaled = deltascaled;
                }
        }
        get_paca()->user_time_scaled += user_scaled;
 
-       if (in_interrupt() || idle_task(smp_processor_id()) != tsk) {
-               account_system_time(tsk, 0, delta, sys_scaled);
-               if (stolen)
-                       account_steal_time(stolen);
-       } else {
-               account_idle_time(delta + stolen);
-       }
-       local_irq_restore(flags);
+       return delta;
+}
+
+void vtime_account_system(struct task_struct *tsk)
+{
+       u64 delta, sys_scaled, stolen;
+
+       delta = vtime_delta(tsk, &sys_scaled, &stolen);
+       account_system_time(tsk, 0, delta, sys_scaled);
+       if (stolen)
+               account_steal_time(stolen);
+}
+
+void vtime_account_idle(struct task_struct *tsk)
+{
+       u64 delta, sys_scaled, stolen;
+
+       delta = vtime_delta(tsk, &sys_scaled, &stolen);
+       account_idle_time(delta + stolen);
 }
-EXPORT_SYMBOL_GPL(account_system_vtime);
 
 /*
  * Transfer the user and system times accumulated in the paca
  * by the exception entry and exit code to the generic process
  * user and system time records.
  * Must be called with interrupts disabled.
- * Assumes that account_system_vtime() has been called recently
+ * Assumes that vtime_account() has been called recently
  * (i.e. since the last entry from usermode) so that
  * get_paca()->user_time_scaled is up to date.
  */
@@ -366,6 +375,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
        account_user_time(tsk, utime, utimescaled);
 }
 
+void vtime_task_switch(struct task_struct *prev)
+{
+       vtime_account(prev);
+       account_process_tick(prev, 0);
+}
+
 #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
 #define calc_cputime_factors()
 #endif