Index: kvm/include/linux/sched.h =================================================================== --- kvm.orig/include/linux/sched.h 2007-08-16 15:23:27.000000000 +0200 +++ kvm/include/linux/sched.h 2007-08-16 15:23:41.000000000 +0200 @@ -955,6 +955,10 @@ /* list of struct preempt_notifier: */ struct hlist_head preempt_notifiers; #endif +#ifdef CONFIG_ACCOUNT_MODIFIERS + /* list of struct account_modifiers: */ + struct hlist_head account_modifiers; +#endif unsigned short ioprio; #ifdef CONFIG_BLK_DEV_IO_TRACE @@ -1873,6 +1877,31 @@ } #endif +#ifdef CONFIG_ACCOUNT_MODIFIERS +struct account_modifier; +struct account_ops { + cputime_t (*user_time)(struct account_modifier *, + struct task_struct *, cputime_t ); + cputime_t (*system_time)(struct account_modifier *, + struct task_struct *, int, cputime_t); +}; + +struct account_modifier { + struct hlist_node link; + struct account_ops *ops; +}; + +void account_modifier_register(struct account_modifier *modifier); +void account_modifier_unregister(struct account_modifier *modifier); + +static inline void account_modifier_init(struct account_modifier *modifier, + struct account_ops *ops) +{ + INIT_HLIST_NODE(&modifier->link); + modifier->ops = ops; +} +#endif + #endif /* __KERNEL__ */ #endif Index: kvm/kernel/sched.c =================================================================== --- kvm.orig/kernel/sched.c 2007-08-16 15:15:33.000000000 +0200 +++ kvm/kernel/sched.c 2007-08-16 15:23:28.000000000 +0200 @@ -1593,6 +1593,9 @@ #ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD(&p->preempt_notifiers); #endif +#ifdef CONFIG_ACCOUNT_MODIFIERS + INIT_HLIST_HEAD(&p->account_modifiers); +#endif /* * We mark the process as running here, but have not actually @@ -1731,6 +1734,62 @@ } #endif +#ifdef CONFIG_ACCOUNT_MODIFIERS + +void account_modifier_register(struct account_modifier *modifier) +{ + hlist_add_head(&modifier->link, ¤t->account_modifiers); +} +EXPORT_SYMBOL_GPL(account_modifier_register); + +void account_modifier_unregister(struct account_modifier *modifier) +{ + hlist_del(&modifier->link); +} +EXPORT_SYMBOL_GPL(account_modifier_unregister); + +static cputime_t fire_user_time_account_modifiers(struct task_struct *curr, + cputime_t cputime) +{ + struct account_modifier *modifier; + struct hlist_node *node; + + hlist_for_each_entry(modifier, node, &curr->account_modifiers, link) + if (modifier->ops->user_time) + cputime = modifier->ops->user_time(modifier, + curr, cputime); + return cputime; +} + +static cputime_t fire_system_time_account_modifiers(struct task_struct *curr, + int hardirq_offset, + cputime_t cputime) +{ + struct account_modifier *modifier; + struct hlist_node *node; + + hlist_for_each_entry(modifier, node, &curr->account_modifiers, link) + if (modifier->ops->system_time) + cputime = modifier->ops->system_time(modifier, + curr, hardirq_offset, cputime); + return cputime; +} + +#else + +static inline cputime_t fire_user_time_account_modifiers(struct task_struct *curr, cputime_t cputime) +{ + return cputime; +} + +static inline cputime_t fire_system_time_account_modifiers(struct task_struct *curr, + int hardirq_offset, + cputime_t cputime) +{ + return cputime; +} + +#endif /** * prepare_task_switch - prepare to switch tasks @@ -3223,6 +3282,8 @@ struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; cputime64_t tmp; + cputime = fire_user_time_account_modifiers(p, cputime); + p->utime = cputime_add(p->utime, cputime); /* Add user time to cpustat. */ @@ -3246,6 +3307,8 @@ struct rq *rq = this_rq(); cputime64_t tmp; + cputime = fire_system_time_account_modifiers(p,hardirq_offset, cputime); + p->stime = cputime_add(p->stime, cputime); /* Add system time to cpustat. */ @@ -6522,6 +6585,9 @@ #ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD(&init_task.preempt_notifiers); #endif +#ifdef CONFIG_ACCOUNT_MODIFIERS + INIT_HLIST_HEAD(&init_task.account_modifiers); +#endif #ifdef CONFIG_SMP nr_cpu_ids = highest_cpu + 1;