There is a requirement to collect real usage values of each partition in LPAR environment on pseries as well as iseries. This patch enables that feature. The current purr (processor Utilization register ) values of each of the processors is stored in a per_cpu data array. this is then summed and used to calculate various numbers for managing lpars. The patch also calculates how much real cpu time each process uses and stores this value in a ppc64 specific struct. The value is needed by CKRM to do further calculations. ===== 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-01-11 16:25:59 -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,19 @@ 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 that are already present */ + static unsigned long get_purr(void) { unsigned long sum_purr = 0; + int cpu; + struct purr_data *cus; + + for_each_cpu(cpu){ + cus = &per_cpu(purr_data_array, cpu); + sum_purr += cus->current_purr; + } 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-01-11 14:40:29 -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 purr_data, purr_data_array); + struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { @@ -205,6 +208,19 @@ 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 */ +#if defined(CONFIG_SMP) && defined(CONFIG_PPC_PSERIES) + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + struct purr_data *pd = &__get_cpu_var(purr_data_array); + long unsigned start_purr, current_purr; + start_purr = old_thread->start_purr; + pd->current_purr = current_purr = mfspr(PURR); + old_thread->total_dp += (current_purr - start_purr); + new_thread->start_purr = current_purr; + } +#endif + local_irq_save(flags); last = _switch(old_thread, new_thread); ===== 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-01-11 15:04:53 -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_purr; /* Start purr when proc switched in */ + unsigned long total_dp ; /* Total delta purr accum 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-01-11 16:00:30 -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 purr_data, purr_data_array); + +struct purr_data { + u64 current_purr; /* Holds the current purr register values */ +}; + #endif /* __KERNEL__ */ #endif /* __PPC64_TIME_H */