[PATCH] PPC64 collect and export low-level cpu usage statistics
Stephen Rothwell
sfr at canb.auug.org.au
Tue Feb 14 18:32:59 EST 2006
Hi Manish,
Paul has asked me to have a look at this patch and to also consider what
has been done for similar work in s390. I will compare this to s390
tomorrow, but for now here are some preliminary comments:
> Index: linux-2.6.15-rc6/arch/powerpc/kernel/asm-offsets.c
> ===================================================================
> --- linux-2.6.15-rc6.orig/arch/powerpc/kernel/asm-offsets.c 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/arch/powerpc/kernel/asm-offsets.c 2006-01-17 15:39:03.000000000 -0800
> @@ -144,6 +144,10 @@
> DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
> DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
> DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
> + DEFINE(PACA_STARTB, offsetof(struct paca_struct, start_tb));
> + DEFINE(PACA_CDFLAG, offsetof(struct paca_struct, cdflag));
> + DEFINE(PACA_DELTATB, offsetof(struct paca_struct, delta_tb));
Why not PACA_START_TB and PACA_DELTA_TB? Also, start_tb and delta_tb don't really
store time base values, but PURR values.
> Index: linux-2.6.15-rc6/arch/powerpc/kernel/entry_64.S
> ===================================================================
> --- linux-2.6.15-rc6.orig/arch/powerpc/kernel/entry_64.S 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/arch/powerpc/kernel/entry_64.S 2006-01-17 15:39:03.000000000 -0800
> @@ -520,7 +520,19 @@
> * r13 is our per cpu area, only restore it if we are returning to
> * userspace
> */
> +
> beq 1f
> +BEGIN_FTR_SECTION
> + li r10,0
> + stb r10,PACA_CDFLAG(r13)
cdflag get set here but not set or used anywhere else.
> Index: linux-2.6.15-rc6/arch/powerpc/kernel/process.c
> ===================================================================
> --- linux-2.6.15-rc6.orig/arch/powerpc/kernel/process.c 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/arch/powerpc/kernel/process.c 2006-01-17 21:20:25.000000000 -0800
> @@ -243,6 +243,7 @@
> struct thread_struct *new_thread, *old_thread;
> unsigned long flags;
> struct task_struct *last;
> + struct paca_struct *lpaca;
This could have been declared below (near pd)
>
> #ifdef CONFIG_SMP
> /* avoid complexity of lazy save/restore of fpu
> @@ -313,19 +314,34 @@
> new_thread = &new->thread;
> old_thread = ¤t->thread;
>
> -#ifdef CONFIG_PPC64
> - /*
> - * Collect processor utilization data per process
> - */
> - if (firmware_has_feature(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(SPRN_PURR);
> - old_thread->accum_tb += (current_tb - start_tb);
> - new_thread->start_tb = current_tb;
> +
> +/* Collect cpu_util utilization data per process and per processor wise */
> + if (cpu_has_feature(CPU_FTR_PURR)) {
> + struct cpu_usage *pd = &__get_cpu_var(cpu_usage_array);
Was there some good reason to change this variable name from cu to pd?
> + long unsigned start_cpu_util, current_cpu_util;
> +
> + if ( old_thread->start_cpu_util )
> + pd->current_cpu_util = current_cpu_util = mfspr(SPRN_PURR);
> + else
> + old_thread->start_cpu_util = pd->current_cpu_util = current_cpu_util = mfspr(SPRN_PURR);
Probably better would be:
pd->current_cpu_util = current_cpu_util = mfspr(SPRN_PURR);
if (old_thread->start_cpu_util == 0)
old_thread->start_cpu_util = current_cpu_util;
> +
> + /* store delta_tb & mftb into cpu_util data array for *
> + * later easy access otherwise you have to do run_on_cpu *
> + * which is expensive */
Comment style should be:
/* store delta_tb & mftb into cpu_util data array for
* later easy access otherwise you have to do run_on_cpu
* which is expensive
*/
> +
> + lpaca = get_paca();
> + pd->collected_krntb = lpaca->delta_tb;
> + pd->collected_timebase = mftb();
> +
> + start_cpu_util = old_thread->start_cpu_util;
> + old_thread->total_dp += (current_cpu_util - start_cpu_util);
> +
> + /* collect time from entry into kernel to now and account it *
> + * in process kernel time */
Comment style again.
> +
> + old_thread->proc_stime += (current_cpu_util - lpaca->start_tb);
> + new_thread->start_cpu_util = current_cpu_util;
> }
> -#endif
>
> local_irq_save(flags);
> last = _switch(old_thread, new_thread);
> Index: linux-2.6.15-rc6/arch/powerpc/kernel/setup_64.c
> ===================================================================
> --- linux-2.6.15-rc6.orig/arch/powerpc/kernel/setup_64.c 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/arch/powerpc/kernel/setup_64.c 2006-02-10 11:51:28.197401840 -0800
> @@ -851,3 +851,153 @@
> +static void collect_cpu_deltas(int cpu)
> +static void post_cpu_deltas(int cpu)
Should those two be #ifdef CONFIG_HOTPLUG_CPU ?
> + /* Initialize the global variables to zero */
> + offline_cpu_total_tb = 0;
> + offline_cpu_total_cpu_util = 0;
> + offline_cpu_total_krncycles = 0;
> + offline_cpu_total_idle = 0;
You don't need to set these to zero explicitly.
> Index: linux-2.6.15-rc6/arch/powerpc/kernel/sysfs.c
> ===================================================================
> --- linux-2.6.15-rc6.orig/arch/powerpc/kernel/sysfs.c 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/arch/powerpc/kernel/sysfs.c 2006-02-10 12:36:02.375372096 -0800
> @@ -232,8 +240,11 @@
> if (cur_cpu_spec->num_pmcs >= 8)
> sysdev_create_file(s, &attr_pmc8);
>
> - if (cpu_has_feature(CPU_FTR_SMT))
> + if (cpu_has_feature(CPU_FTR_PURR)) {
> sysdev_create_file(s, &attr_purr);
This will mean that the "purr" file doesn't exist in some cases where it
used to (even if it was useless). Not sure if that is a problem for any
user mode utilities.
> Index: linux-2.6.15-rc6/include/asm-powerpc/processor.h
> ===================================================================
> --- linux-2.6.15-rc6.orig/include/asm-powerpc/processor.h 2005-12-18 16:36:54.000000000 -0800
> +++ linux-2.6.15-rc6/include/asm-powerpc/processor.h 2006-01-17 21:31:17.000000000 -0800
> @@ -177,6 +177,9 @@
> #ifdef CONFIG_PPC64
> unsigned long start_tb; /* Start purr when proc switched in */
> unsigned long accum_tb; /* Total accumilated purr for process */
> + unsigned long start_cpu_util; /* Start cpu_util when proc switch in */
> + unsigned long total_dp ; /* Total delta cpu_util accum for proc */
> + unsigned long proc_stime; /* Was pad,Now process cpu_util stime */
total_dp and proc_stime are not used anywhere and start_tb accum_tb are no longer used.
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
More information about the Linuxppc64-dev
mailing list