Re: [PATCH] Introduce boot based time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <[email protected]>
> Cc: Tomas Smetana <[email protected]>
> Cc: John Stultz <[email protected]>

Looks good! Thanks again for catching this!

Acked-by: John Stultz <[email protected]>

> ---
>  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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux