lkml.org 
[lkml]   [2008]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC PATCH 16/22 -v2] add get_monotonic_cycles
    * Steven Rostedt (rostedt@goodmis.org) wrote:
    > The latency tracer needs a way to get an accurate time
    > without grabbing any locks. Locks themselves might call
    > the latency tracer and cause at best a slow down.
    >
    > This patch adds get_monotonic_cycles that returns cycles
    > from a reliable clock source in a monotonic fashion.
    >
    > Signed-off-by: Steven Rostedt <srostedt@redhat.com>
    > ---
    > include/linux/clocksource.h | 3 ++
    > kernel/time/timekeeping.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
    > 2 files changed, 51 insertions(+)
    >
    > Index: linux-compile-i386.git/kernel/time/timekeeping.c
    > ===================================================================
    > --- linux-compile-i386.git.orig/kernel/time/timekeeping.c 2008-01-09 14:27:26.000000000 -0500
    > +++ linux-compile-i386.git/kernel/time/timekeeping.c 2008-01-09 14:34:40.000000000 -0500
    > @@ -103,6 +103,54 @@ static inline void __get_realtime_clock_
    > timespec_add_ns(ts, nsecs);
    > }
    >
    > +cycle_t notrace get_monotonic_cycles(void)
    > +{
    > + cycle_t cycle_now, cycle_delta, cycle_raw, cycle_last;
    > +
    > + do {
    > + /*
    > + * cycle_raw and cycle_last can change on
    > + * another CPU and we need the delta calculation
    > + * of cycle_now and cycle_last happen atomic, as well
    > + * as the adding to cycle_raw. We don't need to grab
    > + * any locks, we just keep trying until get all the
    > + * calculations together in one state.
    > + *
    > + * In fact, we __cant__ grab any locks. This
    > + * function is called from the latency_tracer which can
    > + * be called anywhere. To grab any locks (including
    > + * seq_locks) we risk putting ourselves into a deadlock.
    > + */

    I wonder what makes the compiler read the clock->cycle_raw and
    clock->cycle_last variables twice ? I guess some memory barriers could
    be welcome here ?

    > + cycle_raw = clock->cycle_raw;
    > + cycle_last = clock->cycle_last;
    > +
    > + /* read clocksource: */
    > + cycle_now = clocksource_read(clock);
    > +
    > + /* calculate the delta since the last update_wall_time: */
    > + cycle_delta = (cycle_now - cycle_last) & clock->mask;
    > +
    > + } while (cycle_raw != clock->cycle_raw ||
    > + cycle_last != clock->cycle_last);
    > +
    > + return cycle_raw + cycle_delta;
    > +}
    > +
    > +unsigned long notrace cycles_to_usecs(cycle_t cycles)
    > +{
    > + u64 ret = cyc2ns(clock, cycles);
    > +
    > + ret += NSEC_PER_USEC/2; /* For rounding in do_div() */
    > + do_div(ret, NSEC_PER_USEC);
    > +
    > + return ret;
    > +}
    > +
    > +cycle_t notrace usecs_to_cycles(unsigned long usecs)
    > +{
    > + return ns2cyc(clock, (u64)usecs * 1000);
    > +}
    > +
    > /**
    > * getnstimeofday - Returns the time of day in a timespec
    > * @ts: pointer to the timespec to be set
    > Index: linux-compile-i386.git/include/linux/clocksource.h
    > ===================================================================
    > --- linux-compile-i386.git.orig/include/linux/clocksource.h 2008-01-09 14:27:51.000000000 -0500
    > +++ linux-compile-i386.git/include/linux/clocksource.h 2008-01-09 14:29:44.000000000 -0500
    > @@ -273,6 +273,9 @@ extern int clocksource_register(struct c
    > extern struct clocksource* clocksource_get_next(void);
    > extern void clocksource_change_rating(struct clocksource *cs, int rating);
    > extern void clocksource_resume(void);
    > +extern cycle_t get_monotonic_cycles(void);
    > +extern unsigned long cycles_to_usecs(cycle_t cycles);
    > +extern cycle_t usecs_to_cycles(unsigned long usecs);
    >
    > /* used to initialize clock */
    > extern struct clocksource clocksource_jiffies;
    >
    > --

    --
    Mathieu Desnoyers
    Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
    OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68


    \
     
     \ /
      Last update: 2008-01-15 22:49    [W:0.032 / U:0.424 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site