===== arch/ppc64/kernel/lparcfg.c 1.18 vs edited ===== --- 1.18/arch/ppc64/kernel/lparcfg.c 2005-01-04 18:48:02 -08:00 +++ edited/arch/ppc64/kernel/lparcfg.c 2005-02-03 20:56:41 -08:00 @@ -33,8 +33,9 @@ #include #include #include +#include -#define MODULE_VERS "1.5" +#define MODULE_VERS "1.6" #define MODULE_NAME "lparcfg" /* #define LPARCFG_DEBUG */ @@ -214,13 +215,20 @@ static void h_pic(unsigned long *pool_id } static unsigned long get_purr(void); -/* ToDo: get sum of purr across all processors. The purr collection code - * is coming, but at this time is still problematic, so for now this - * function will return 0. - */ + +/* Track sum of all purrs accross all processors. This is used to further */ +/* calculate usage values by different applications */ + static unsigned long get_purr(void) { unsigned long sum_purr = 0; + int cpu; + struct cpu_usage *cu; + + for_each_cpu(cpu) { + cu = &per_cpu(cpu_usage_array, cpu); + sum_purr += cu->current_tb; + } return sum_purr; } ===== arch/ppc64/kernel/process.c 1.68 vs edited ===== --- 1.68/arch/ppc64/kernel/process.c 2004-10-20 01:37:09 -07:00 +++ edited/arch/ppc64/kernel/process.c 2005-02-03 20:58:06 -08:00 @@ -51,6 +51,7 @@ #include #include #include +#include #ifndef CONFIG_SMP struct task_struct *last_task_used_math = NULL; @@ -168,6 +169,8 @@ int dump_task_altivec(struct pt_regs *re #endif /* CONFIG_ALTIVEC */ +DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); + struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { @@ -205,6 +208,21 @@ struct task_struct *__switch_to(struct t new_thread = &new->thread; old_thread = ¤t->thread; + +/* Collect purr utilization data per process and per processor wise */ +/* purr is nothing but processor time base */ + +#if defined(CONFIG_PPC_PSERIES) + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); + long unsigned start_tb, current_tb; + start_tb = old_thread->start_tb; + cu->current_tb = current_tb = mfspr(PURR); + old_thread->accum_tb += (current_tb - start_tb); + new_thread->start_tb = current_tb; + } +#endif + local_irq_save(flags); last = _switch(old_thread, new_thread); ===== arch/ppc64/kernel/time.c 1.44 vs edited ===== --- 1.44/arch/ppc64/kernel/time.c 2005-01-04 18:48:14 -08:00 +++ edited/arch/ppc64/kernel/time.c 2005-02-03 21:00:26 -08:00 @@ -296,6 +296,14 @@ int timer_interrupt(struct pt_regs * reg } #endif +/* collect purr register values often, for accurate calculations */ +#if defined(CONFIG_PPC_PSERIES) + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); + cu->current_tb = mfspr(PURR); + } +#endif + irq_exit(); return 1; ===== include/asm-ppc64/processor.h 1.59 vs edited ===== --- 1.59/include/asm-ppc64/processor.h 2005-01-10 17:29:24 -08:00 +++ edited/include/asm-ppc64/processor.h 2005-02-03 15:43:21 -08:00 @@ -558,7 +558,9 @@ struct thread_struct { double fpr[32]; /* Complete floating point set */ unsigned long fpscr; /* Floating point status (plus pad) */ unsigned long fpexc_mode; /* Floating-point exception mode */ - unsigned long pad[3]; /* was saved_msr, saved_softe */ + unsigned long start_tb; /* Start purr when proc switched in */ + unsigned long accum_tb; /* Total accumilated purr for process */ + unsigned long pad; /* was saved_msr, saved_softe */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ vector128 vr[32] __attribute((aligned(16))); ===== include/asm-ppc64/time.h 1.9 vs edited ===== --- 1.9/include/asm-ppc64/time.h 2005-01-04 18:48:02 -08:00 +++ edited/include/asm-ppc64/time.h 2005-02-03 13:25:37 -08:00 @@ -102,5 +102,13 @@ static inline unsigned long tb_ticks_sin unsigned mulhwu_scale_factor(unsigned, unsigned); void div128_by_32( unsigned long dividend_high, unsigned long dividend_low, unsigned divisor, struct div_result *dr ); + +/* Used to store Processor Utilization register (purr) values */ +DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array); + +struct cpu_usage { + u64 current_tb; /* Holds the current purr register values */ +}; + #endif /* __KERNEL__ */ #endif /* __PPC64_TIME_H */