lkml.org 
[lkml]   [2007]   [May]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRe: [PATCH] Introduce boot based time
    From
    Date
    On Thu, 2007-05-10 at 19:10 +0200, Tomas Janousek wrote:
    > The commits
    > 411187fb05cd11676b0979d9fbf3291db69dbce2 (GTOD: persistent clock support)
    > c1d370e167d66b10bca3b602d3740405469383de (i386: use GTOD persistent clock
    > support)
    > changed the monotonic time so that it no longer jumps after resume, but it's
    > not possible to use it for boot time and process start time calculations then.
    > Also, the uptime no longer increases during suspend.
    >
    > I add a variable to track the wall_to_monotonic changes, a function to get the
    > real boot time and a function to get the boot based time from the monotonic
    > one.
    >
    > Signed-off-by: Tomas Janousek <tjanouse@redhat.com>
    > Cc: Tomas Smetana <tsmetana@redhat.com>
    > Cc: John Stultz <johnstul@us.ibm.com>

    Looks good! Thanks again for catching this!

    Acked-by: John Stultz <johnstul@us.ibm.com>

    > ---
    > include/linux/time.h | 2 ++
    > kernel/time/timekeeping.c | 41 +++++++++++++++++++++++++++++++++++++++++
    > 2 files changed, 43 insertions(+), 0 deletions(-)
    >
    > diff --git a/include/linux/time.h b/include/linux/time.h
    > index 8997b61..06f3eaf 100644
    > --- a/include/linux/time.h
    > +++ b/include/linux/time.h
    > @@ -116,6 +116,8 @@ extern int do_setitimer(int which, struct itimerval *value,
    > extern unsigned int alarm_setitimer(unsigned int seconds);
    > extern int do_getitimer(int which, struct itimerval *value);
    > extern void getnstimeofday(struct timespec *tv);
    > +extern void getboottime(struct timespec *ts);
    > +extern void monotonic_to_bootbased(struct timespec *ts);
    >
    > extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
    > extern int timekeeping_is_continuous(void);
    > diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
    > index f9217bf..dd9647a 100644
    > --- a/kernel/time/timekeeping.c
    > +++ b/kernel/time/timekeeping.c
    > @@ -36,9 +36,17 @@ EXPORT_SYMBOL(xtime_lock);
    > * at zero at system boot time, so wall_to_monotonic will be negative,
    > * however, we will ALWAYS keep the tv_nsec part positive so we can use
    > * the usual normalization.
    > + *
    > + * wall_to_monotonic is moved after resume from suspend for the monotonic
    > + * time not to jump. We need to add total_sleep_time to wall_to_monotonic
    > + * to get the real boot based time offset.
    > + *
    > + * - wall_to_monotonic is no longer the boot time, getboottime must be
    > + * used instead.
    > */
    > struct timespec xtime __attribute__ ((aligned (16)));
    > struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
    > +static unsigned long total_sleep_time;
    >
    > EXPORT_SYMBOL(xtime);
    >
    > @@ -251,6 +259,7 @@ void __init timekeeping_init(void)
    > xtime.tv_nsec = 0;
    > set_normalized_timespec(&wall_to_monotonic,
    > -xtime.tv_sec, -xtime.tv_nsec);
    > + total_sleep_time = 0;
    >
    > write_sequnlock_irqrestore(&xtime_lock, flags);
    > }
    > @@ -280,6 +289,7 @@ static int timekeeping_resume(struct sys_device *dev)
    >
    > xtime.tv_sec += sleep_length;
    > wall_to_monotonic.tv_sec -= sleep_length;
    > + total_sleep_time += sleep_length;
    > }
    > /* re-base the last cycle value */
    > clock->cycle_last = clocksource_read(clock);
    > @@ -474,3 +484,34 @@ void update_wall_time(void)
    > change_clocksource();
    > update_vsyscall(&xtime, clock);
    > }
    > +
    > +/**
    > + * getboottime - Return the real time of system boot.
    > + * @ts: pointer to the timespec to be set
    > + *
    > + * Returns the time of day in a timespec.
    > + *
    > + * This is based on the wall_to_monotonic offset and the total suspend
    > + * time. Calls to settimeofday will affect the value returned (which
    > + * basically means that however wrong your real time clock is at boot time,
    > + * you get the right time here).
    > + */
    > +void getboottime(struct timespec *ts)
    > +{
    > + set_normalized_timespec(ts,
    > + - (wall_to_monotonic.tv_sec + total_sleep_time),
    > + - wall_to_monotonic.tv_nsec);
    > +}
    > +
    > +EXPORT_SYMBOL(getboottime);
    > +
    > +/**
    > + * monotonic_to_bootbased - Convert the monotonic time to boot based.
    > + * @ts: pointer to the timespec to be converted
    > + */
    > +void monotonic_to_bootbased(struct timespec *ts)
    > +{
    > + ts->tv_sec += total_sleep_time;
    > +}
    > +
    > +EXPORT_SYMBOL(monotonic_to_bootbased);
    > --
    > 1.5.1.4
    >
    >

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-05-10 20:45    [W:3.385 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site