On Tue, 2013-01-08 at 03:08 +0100, Frederic Weisbecker wrote: > diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c > index 07912dd..bf4f72d 100644 > --- a/kernel/sched/cputime.c > +++ b/kernel/sched/cputime.c > @@ -484,7 +484,7 @@ void vtime_task_switch(struct task_struct *prev) > * vtime_account(). > */ > #ifndef __ARCH_HAS_VTIME_ACCOUNT > -void vtime_account(struct task_struct *tsk) > +void vtime_account_irq_enter(struct task_struct *tsk) > { > if (!in_interrupt()) { > /* > @@ -505,7 +505,7 @@ void vtime_account(struct task_struct *tsk) > } > vtime_account_system(tsk); > } > -EXPORT_SYMBOL_GPL(vtime_account); > +EXPORT_SYMBOL_GPL(vtime_account_irq_enter); > #endif /* __ARCH_HAS_VTIME_ACCOUNT */ > #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ > > @@ -616,41 +616,67 @@ void thread_group_cputime_adjusted(struct task_struct > *p, cputime_t *ut, cputime > #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ > > #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN > -static DEFINE_PER_CPU(long, last_jiffies) = INITIAL_JIFFIES; > - > -static cputime_t get_vtime_delta(void) > +static cputime_t get_vtime_delta(struct task_struct *tsk) > { > long delta; > > - delta = jiffies - __this_cpu_read(last_jiffies); > - __this_cpu_add(last_jiffies, delta); > + delta = jiffies - tsk->prev_jiffies; > + tsk->prev_jiffies += delta; > > return jiffies_to_cputime(delta); > } > > -void vtime_account_system(struct task_struct *tsk) > +static void __vtime_account_system(struct task_struct *tsk) > { > - cputime_t delta_cpu = get_vtime_delta(); > + cputime_t delta_cpu = get_vtime_delta(tsk); > > account_system_time(tsk, irq_count(), delta_cpu, > cputime_to_scaled(delta_cpu)); > } > > +void vtime_account_system(struct task_struct *tsk) > +{ > + write_seqlock(&tsk->vtime_seqlock); > + __vtime_account_system(tsk);
__vtime_account_system() calls account_system_time() account_system_time() calls __account_system_time() __account_system_time() calls acct_update_integrals() (when CONFIG_TASK_XACCT is set) acct_update_integrals() calls task_cputime() task_cputime() grabs t->vtime_seqlock for read DEADLOCK ironically the subject says *Safely* read cputime ;-) -- Steve > + write_sequnlock(&tsk->vtime_seqlock); > +} > + > +void vtime_account_irq_exit(struct task_struct *tsk) > +{ > + write_seqlock(&tsk->vtime_seqlock); > + if (context_tracking_in_user()) > + tsk->prev_jiffies_whence = JIFFIES_USER; > + __vtime_account_system(tsk); > + write_sequnlock(&tsk->vtime_seqlock); > +} > + -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/