[ltt-dev] trace-clock-userspace.patch for ARM/PowerPC ?

Abbas Raza abbas_raza at mentor.com
Thu Aug 18 03:39:48 EDT 2011


Hello Mathieu,

Sorry for late reply. Yes it can be used under LGPLv2.1/GPLv2 dual-license.

Thanks!

Abbas Raza

On 08/16/2011 03:55 PM, Mathieu Desnoyers wrote:
> Just to make sure this email did not get lost, I'm still waiting on the
> OK to use this code under LGPLv2.1/GPLv2 dual-license.
>
> Thanks,
>
> Mathieu
>
> * Abbas Raza (abbas_raza at mentor.com) wrote:
>> On 07/28/2011 10:26 PM, Mathieu Desnoyers wrote:
>>> * Abbas Raza (abbas_raza at mentor.com) wrote:
>>>> On 07/26/2011 11:02 PM, Mathieu Desnoyers wrote:
>>>>> * Abbas Raza (abbas_raza at mentor.com) wrote:
>>>>>> On 07/26/2011 10:17 PM, Mathieu Desnoyers wrote:
>>>>>>> * Abbas Raza (abbas_raza at mentor.com) wrote:
>>>>>>> [...]
>>>>>>>> Hi Mathieu,
>>>>>>>>
>>>>>>>> Some confusion here :(
>>>>>>>>
>>>>>>>> In case of LTTng 0.x, when we take kernel traces then timestamps for
>>>>>>>> these traces is based on TSC/TB . So after that we view these traces by
>>>>>>>> lttv and it shows timestamps with all events which occurred.
>>>>>>>> I print the timestamp in kernel ltt function 'ltt_trace_alloc()'  and it
>>>>>>>> comes out to be 22944596907 (by calling trace_clock_read64() ). While
>>>>>>>> lttv show Birth sec of first event to 367 second. How this conversion is
>>>>>>>> made from TSC to the Birth sec/nsec value displayed in lttv? just want
>>>>>>>> to confirm that whether timestamps shown in lttv (Birth sec/nsec) are
>>>>>>>> based on TSC values... if yes then how TSC values are converted to Birth
>>>>>>>> sec/nsec and i no then from where lttv gets timestamps to be displayed?
>>>>>>>> Or in simple words, do kernel traces which we get contain timestamps
>>>>>>>> based simply on TSC values or it is something else?
>>>>>>> Yes, we write, in the lttng 0.x headers, the following information:
>>>>>>>
>>>>>>> struct ltt_subbuffer_header {
>>>>>>>      [...]
>>>>>>>             uint64_t start_freq;            /*
>>>>>>>                                              * Frequency at trace start,
>>>>>>>                                              * used all along the trace.
>>>>>>>                                              */
>>>>>>>             uint32_t freq_scale;            /* Frequency scaling (divisor) */
>>>>>>> [...]
>>>>>>> }
>>>>>>>
>>>>>>> so by using the start frequency and the scale, we can convert from TSC
>>>>>>> values to nanoseconds. Please note that LTTng 0.x requires the clock
>>>>>>> source to appear as if it has a constant rate.
>>>>>>>
>>>>>>> These values map to trace_clock_frequency() and trace_clock_freq_scale()
>>>>>>> trace clock functions.
>>>>>>>
>>>>>>> Best regards,
>>>>>>>
>>>>>>> Mathieu
>>>>>>>
>>>>>>>> Thanks a lot again for help :)
>>>>>>>>
>>>>>>>>
>>>>>>>> Abbas Raza
>>>>>>>>
>>>>>> Just to confirm that TSC's just have raw values of clock cycles and lttv
>>>>>> converts these values into sec/nsec by reading ltt_subbuffer_header ?
>>>>> Yes, that's it.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Mathieu
>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> Abbas Raza
>>>>>>
>>>> Hello Mathieu,
>>>>
>>>> Just wanted to ask that trace clock userspace patch for x86 adds
>>>> functionality to register posix clocks like
>>>>
>>>> register_posix_clock(CLOCK_TRACE,&clock_trace);
>>>> register_posix_clock(CLOCK_TRACE_FREQ,&clock_trace_freq);
>>>>
>>>> What we understood is that these clocks are registered to provide system
>>>> call functionality for CLOCK_TRACE and CLOCK_TRACE_FREQ clocks just like
>>>> other posix clocks. Right?
>>>>
>>>> And same we will have to do for powerpc (even if we have got vdso
>>>> functionality for these clocks)?
>>> Yes, exactly. The kernel always needs to provide a system call fallback
>>> for vDSO, just in case the vDSO cannot be used.
>>>
>>> Thanks
>>>
>>> Mathieu
>>>
>>>> Thanks !
>>>>
>>>> --
>>>> Abbas Raza
>>>>
>> Hello Mathieu,
>>
>> We have added userspace trace clock support for powerpc architecture. We
>> have verified our changes and userspace, kernel traces appear to be in
>> sync for powerpc now. Patches are attached for kernel and UST.
>>
>> Thanks!
>>
>> Abbas Raza
>>
>>  From 018e85ce1a15b9c02719de29663824e1e4f8bc2b Mon Sep 17 00:00:00 2001
>> From: Abbas Raza<Abbas_Raza at mentor.com>
>> Date: Thu, 4 Aug 2011 16:16:28 +0500
>> Subject: [PATCH] Make use of TRACE_CLOCK_FREQ functionality provided by clock_gettime for powerpc.
>>
>> Signed-off-by: Abbas Raza<Abbas_Raza at mentor.com>
>> ---
>>   include/ust/clock.h |    8 ++++----
>>   1 files changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/ust/clock.h b/include/ust/clock.h
>> index 5e8f755..13e49ab 100644
>> --- a/include/ust/clock.h
>> +++ b/include/ust/clock.h
>> @@ -41,7 +41,7 @@
>>      precision and monotonicity.
>>   */
>>
>> -/* Only available for x86 arch */
>> +/* Only available for x86/powerpc arch */
>>   #define CLOCK_TRACE_FREQ  14
>>   #define CLOCK_TRACE  15
>>   union lttng_timespec {
>> @@ -76,7 +76,7 @@ static __inline__ uint64_t trace_clock_read64(void)
>>   	return retval;
>>   }
>>
>> -#if __i386__ || __x86_64__
>> +#if __i386__ || __x86_64__ || __powerpc__
>>   static __inline__ uint64_t trace_clock_frequency(void)
>>   {
>>   	struct timespec ts;
>> @@ -88,12 +88,12 @@ static __inline__ uint64_t trace_clock_frequency(void)
>>   	}
>>   	return 1000000000LL;
>>   }
>> -#else /* #if __i386__ || __x86_64__ */
>> +#else /* #if __i386__ || __x86_64__ || __powerpc__ */
>>   static __inline__ uint64_t trace_clock_frequency(void)
>>   {
>>   	return 1000000000LL;
>>   }
>> -#endif /* #else #if __i386__ || __x86_64__ */
>> +#endif /* #else #if __i386__ || __x86_64__ || __powerpc__ */
>>
>>   static __inline__ uint32_t trace_clock_freq_scale(void)
>>   {
>> -- 
>> 1.7.0.4
>>
>>  From ac11b1d5235216be99d25f95da30c8b1e2dbb8ee Mon Sep 17 00:00:00 2001
>> From: Abbas Raza<Abbas_Raza at mentor.com>
>> Date: Thu, 4 Aug 2011 16:05:49 +0500
>> Subject: [PATCH] TRACE_CLOCK and TRACE_CLOCK_FREQ in clock_gettime for powerpc
>>
>> These new options to clock_gettime allows the user to retreive the TB frequency and the current TB from userspace.
>>
>> Signed-off-by: Abbas Raza<Abbas_Raza at mentor.com>
>> ---
>>   arch/powerpc/include/asm/trace-clock.h    |    8 +++
>>   arch/powerpc/kernel/Makefile              |    2 +-
>>   arch/powerpc/kernel/asm-offsets.c         |    2 +
>>   arch/powerpc/kernel/trace-clock.c         |   56 ++++++++++++++++++++++++
>>   arch/powerpc/kernel/vdso32/gettimeofday.S |   67 ++++++++++++++++++++++++++---
>>   5 files changed, 127 insertions(+), 8 deletions(-)
>>   create mode 100644 arch/powerpc/kernel/trace-clock.c
>>
>> diff --git a/arch/powerpc/include/asm/trace-clock.h b/arch/powerpc/include/asm/trace-clock.h
>> index 05facc3..9ed1108 100644
>> --- a/arch/powerpc/include/asm/trace-clock.h
>> +++ b/arch/powerpc/include/asm/trace-clock.h
>> @@ -13,6 +13,14 @@
>>   #include<linux/time.h>
>>   #include<asm/time.h>
>>
>> +#define TRACE_CLOCK_MIN_PROBE_DURATION 200
>> +#define TRACE_CLOCK_RES TRACE_CLOCK_MIN_PROBE_DURATION
>> +
>> +union lttng_timespec {
>> +       struct timespec ts;
>> +       u64 lttng_ts;
>> +};
>> +
>>   static inline u32 trace_clock_read32(void)
>>   {
>>   	return get_tbl();
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index 3bb2a3e..788a96d 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -120,7 +120,7 @@ obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
>>   ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
>>   obj-y				+= iomap.o
>>   endif
>> -
>> +obj-$(CONFIG_HAVE_TRACE_CLOCK) += trace-clock.o
>>   obj-$(CONFIG_PPC64)		+= $(obj64-y)
>>   obj-$(CONFIG_PPC32)		+= $(obj32-y)
>>
>> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
>> index 23e6a93..efb7ead 100644
>> --- a/arch/powerpc/kernel/asm-offsets.c
>> +++ b/arch/powerpc/kernel/asm-offsets.c
>> @@ -370,6 +370,8 @@ int main(void)
>>   	/* Other bits used by the vdso */
>>   	DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
>>   	DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
>> +        DEFINE(CLOCK_TRACE, CLOCK_TRACE);
>> +        DEFINE(CLOCK_TRACE_FREQ, CLOCK_TRACE_FREQ);
>>   	DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
>>   	DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
>>
>> diff --git a/arch/powerpc/kernel/trace-clock.c b/arch/powerpc/kernel/trace-clock.c
>> new file mode 100644
>> index 0000000..5592416
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/trace-clock.c
>> @@ -0,0 +1,56 @@
>> +/*
>> + * arch/powerpc/kernel/trace-clock.c
>> + *
>> + * Trace clock for powerpc.
>> + *
>> + * Abbas Raza<Abbas_Raza at mentor.com>, July 2011
>> + */
>> +
>> +#include<linux/module.h>
>> +#include<linux/trace-clock.h>
>> +#include<linux/timer.h>
>> +#include<linux/posix-timers.h>
>> +
>> +static int posix_get_trace(clockid_t which_clock, struct timespec *tp)
>> +{
>> +	union lttng_timespec *lts = (union lttng_timespec *) tp;
>> +
>> +	lts->lttng_ts = trace_clock_read64();
>> +	return 0;
>> +}
>> +
>> +static int posix_get_trace_freq(clockid_t which_clock, struct timespec *tp)
>> +{
>> +	union lttng_timespec *lts = (union lttng_timespec *) tp;
>> +
>> +	lts->lttng_ts = trace_clock_frequency();
>> +	return 0;
>> +}
>> +
>> +static int posix_get_trace_res(const clockid_t which_clock, struct timespec *tp)
>> +{
>> +	union lttng_timespec *lts = (union lttng_timespec *) tp;
>> +
>> +	lts->lttng_ts = TRACE_CLOCK_RES;
>> +	return 0;
>> +}
>> +
>> +static __init int init_trace_clock(void)
>> +{
>> +
>> +	struct k_clock clock_trace = {
>> +		.clock_getres = posix_get_trace_res,
>> +		.clock_get = posix_get_trace,
>> +	};
>> +	struct k_clock clock_trace_freq = {
>> +		.clock_getres = posix_get_trace_res,
>> +		.clock_get = posix_get_trace_freq,
>> +	};
>> +
>> +	register_posix_clock(CLOCK_TRACE,&clock_trace);
>> +	register_posix_clock(CLOCK_TRACE_FREQ,&clock_trace_freq);
>> +	
>> +	return 0;
>> +}
>> +
>> +early_initcall(init_trace_clock);
>> diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
>> index 4ee09ee..dce1344 100644
>> --- a/arch/powerpc/kernel/vdso32/gettimeofday.S
>> +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
>> @@ -75,7 +75,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
>>   	cmpli	cr0,r3,CLOCK_REALTIME
>>   	cmpli	cr1,r3,CLOCK_MONOTONIC
>>   	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
>> -	bne	cr0,99f
>> +	bne	cr0,80f
>>
>>   	mflr	r12			/* r12 saves lr */
>>     .cfi_register lr,r12
>> @@ -85,7 +85,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
>>   	lis	r7,NSEC_PER_SEC at h	/* want nanoseconds */
>>   	ori	r7,r7,NSEC_PER_SEC at l
>>   50:	bl	__do_get_tspec at local	/* get sec/nsec from tb&  kernel */
>> -	bne	cr1,80f			/* not monotonic ->  all done */
>> +	bne	cr1,99f			/* not monotonic ->  all done */
>>
>>   	/*
>>   	 * CLOCK_MONOTONIC
>> @@ -122,25 +122,53 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
>>   	blt	1f
>>   	subf	r4,r7,r4
>>   	addi	r3,r3,1
>> -1:	bge	cr1,80f
>> +1:	bge	cr1,99f
>>   	addi	r3,r3,-1
>>   	add	r4,r4,r7
>> +	b 99f
>> +
>> +80:
>> +	cmpli	cr0,r3,CLOCK_TRACE
>> +	bne	cr0,85f
>> +
>> +	mflr	r12			/* r12 saves lr */
>> +  .cfi_register lr,r12
>> +	mr	r11,r4			/* r11 saves tp */
>> +	bl	__get_datapage at local	/* get data page */
>> +	mr	r9,r3			/* datapage ptr in r9 */
>> +
>> +	bl	__do_get_tb at local	/* get sec/nsec from tb&  kernel */
>> +	b 99f
>> +
>> +85:
>> +        cmpli   cr0,r3,CLOCK_TRACE_FREQ
>> +        bne     cr0,100f
>>
>> -80:	stw	r3,TSPC32_TV_SEC(r11)
>> +	mflr	r5
>> +  .cfi_register lr,r5
>> +
>> +	mr r11,r4
>> +	bl	__kernel_get_tbfreq at local	
>> +	mr r12,r5
>> +
>> +99:
>> +	stw	r3,TSPC32_TV_SEC(r11)
>>   	stw	r4,TSPC32_TV_NSEC(r11)
>>
>>   	mtlr	r12
>>   	crclr	cr0*4+so
>>   	li	r3,0
>> +
>>   	blr
>>
>>   	/*
>>   	 * syscall fallback
>>   	 */
>> -99:
>> -	li	r0,__NR_clock_gettime
>> +100:
>> +
>> + 	li	r0,__NR_clock_gettime
>>   	sc
>> -	blr
>> +  	blr
>>     .cfi_endproc
>>   V_FUNCTION_END(__kernel_clock_gettime)
>>
>> @@ -264,3 +292,28 @@ __do_get_tspec:
>>
>>   	blr
>>     .cfi_endproc
>> +
>> +__do_get_tb:
>> +  .cfi_startproc
>> +	/* Check for update count&  load values. We use the low
>> +	 * order 32 bits of the update count
>> +	 */
>> +1:	lwz	r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
>> +	andi.	r0,r8,1			/* pending update ? loop */
>> +	bne-	1b
>> +	xor	r0,r8,r8		/* create dependency */
>> +	add	r9,r9,r0
>> +
>> +	/* Load orig stamp (offset to TB) */
>> +	lwz	r5,CFG_TB_ORIG_STAMP(r9)
>> +	lwz	r6,(CFG_TB_ORIG_STAMP+4)(r9)
>> +
>> +	/* Get a stable TB value */
>> +2:	mftbu	r3
>> +	mftbl	r4
>> +	mftbu	r0
>> +	cmpl	cr0,r3,r0
>> +	bne-	2b
>> +
>> +	blr
>> +  .cfi_endproc
>> -- 
>> 1.7.0.4
>>
>





More information about the lttng-dev mailing list