Merge branch 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
um: Fix read_persistent_clock fallout
kgdb: Do not access xtime directly
powerpc: Clean up obsolete code relating to decrementer and timebase
powerpc: Rework VDSO gettimeofday to prevent time going backwards
clocksource: Add __clocksource_updatefreq_hz/khz methods
x86: Convert common clocksources to use clocksource_register_hz/khz
timekeeping: Make xtime and wall_to_monotonic static
hrtimer: Cleanup direct access to wall_to_monotonic
um: Convert to use read_persistent_clock
timkeeping: Fix update_vsyscall to provide wall_to_monotonic offset
powerpc: Cleanup xtime usage
powerpc: Simplify update_vsyscall
time: Kill off CONFIG_GENERIC_TIME
time: Implement timespec_add
x86: Fix vtime/file timestamp inconsistencies
Trivial conflicts in Documentation/feature-removal-schedule.txt
Much less trivial conflicts in arch/powerpc/kernel/time.c resolved as
per Thomas' earlier merge commit 47916be4e2
("Merge branch
'powerpc.cherry-picks' into timers/clocksource")
This commit is contained in:
commit
b62ad9ab18
|
@ -445,16 +445,6 @@ Who: Jan Kiszka <jan.kiszka@web.de>
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
What: xtime, wall_to_monotonic
|
|
||||||
When: 2.6.36+
|
|
||||||
Files: kernel/time/timekeeping.c include/linux/time.h
|
|
||||||
Why: Cleaning up timekeeping internal values. Please use
|
|
||||||
existing timekeeping accessor functions to access
|
|
||||||
the equivalent functionality.
|
|
||||||
Who: John Stultz <johnstul@us.ibm.com>
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
What: KVM paravirt mmu host support
|
What: KVM paravirt mmu host support
|
||||||
When: January 2011
|
When: January 2011
|
||||||
Why: The paravirt mmu host support is slower than non-paravirt mmu, both
|
Why: The paravirt mmu host support is slower than non-paravirt mmu, both
|
||||||
|
|
|
@ -73,7 +73,6 @@ parameter is applicable:
|
||||||
MTD MTD (Memory Technology Device) support is enabled.
|
MTD MTD (Memory Technology Device) support is enabled.
|
||||||
NET Appropriate network support is enabled.
|
NET Appropriate network support is enabled.
|
||||||
NUMA NUMA support is enabled.
|
NUMA NUMA support is enabled.
|
||||||
GENERIC_TIME The generic timeofday code is enabled.
|
|
||||||
NFS Appropriate NFS support is enabled.
|
NFS Appropriate NFS support is enabled.
|
||||||
OSS OSS sound support is enabled.
|
OSS OSS sound support is enabled.
|
||||||
PV_OPS A paravirtualized kernel is enabled.
|
PV_OPS A paravirtualized kernel is enabled.
|
||||||
|
@ -470,7 +469,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
clocksource is not available, it defaults to PIT.
|
clocksource is not available, it defaults to PIT.
|
||||||
Format: { pit | tsc | cyclone | pmtmr }
|
Format: { pit | tsc | cyclone | pmtmr }
|
||||||
|
|
||||||
clocksource= [GENERIC_TIME] Override the default clocksource
|
clocksource= Override the default clocksource
|
||||||
Format: <string>
|
Format: <string>
|
||||||
Override the default clocksource and use the clocksource
|
Override the default clocksource and use the clocksource
|
||||||
with the name specified.
|
with the name specified.
|
||||||
|
|
|
@ -47,10 +47,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,6 @@ config SYS_SUPPORTS_APM_EMULATION
|
||||||
config GENERIC_GPIO
|
config GENERIC_GPIO
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config ARCH_USES_GETTIMEOFFSET
|
config ARCH_USES_GETTIMEOFFSET
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -45,9 +45,6 @@ config GENERIC_IRQ_PROBE
|
||||||
config RWSEM_GENERIC_SPINLOCK
|
config RWSEM_GENERIC_SPINLOCK
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -614,9 +614,6 @@ comment "Kernel Timer/Scheduler"
|
||||||
|
|
||||||
source kernel/Kconfig.hz
|
source kernel/Kconfig.hz
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
bool "Generic clock events"
|
bool "Generic clock events"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -20,9 +20,6 @@ config RWSEM_GENERIC_SPINLOCK
|
||||||
config RWSEM_XCHGADD_ALGORITHM
|
config RWSEM_XCHGADD_ALGORITHM
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config TIME_LOW_RES
|
config TIME_LOW_RES
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -62,10 +62,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_BUG
|
config GENERIC_BUG
|
||||||
bool
|
bool
|
||||||
depends on BUG
|
depends on BUG
|
||||||
|
|
|
@ -82,10 +82,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_TIME_VSYSCALL
|
config GENERIC_TIME_VSYSCALL
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -471,7 +471,8 @@ void update_vsyscall_tz(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
|
void update_vsyscall(struct timespec *wall, struct timespec *wtm,
|
||||||
|
struct clocksource *c, u32 mult)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -487,9 +488,9 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
|
||||||
/* copy kernel time structures */
|
/* copy kernel time structures */
|
||||||
fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec;
|
fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec;
|
||||||
fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec;
|
fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec;
|
||||||
fsyscall_gtod_data.monotonic_time.tv_sec = wall_to_monotonic.tv_sec
|
fsyscall_gtod_data.monotonic_time.tv_sec = wtm->tv_sec
|
||||||
+ wall->tv_sec;
|
+ wall->tv_sec;
|
||||||
fsyscall_gtod_data.monotonic_time.tv_nsec = wall_to_monotonic.tv_nsec
|
fsyscall_gtod_data.monotonic_time.tv_nsec = wtm->tv_nsec
|
||||||
+ wall->tv_nsec;
|
+ wall->tv_nsec;
|
||||||
|
|
||||||
/* normalize */
|
/* normalize */
|
||||||
|
|
|
@ -44,9 +44,6 @@ config HZ
|
||||||
int
|
int
|
||||||
default 100
|
default 100
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config ARCH_USES_GETTIMEOFFSET
|
config ARCH_USES_GETTIMEOFFSET
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,6 @@ config HZ
|
||||||
int
|
int
|
||||||
default 100
|
default 100
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config ARCH_USES_GETTIMEOFFSET
|
config ARCH_USES_GETTIMEOFFSET
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -51,9 +51,6 @@ config GENERIC_IRQ_PROBE
|
||||||
config GENERIC_CALIBRATE_DELAY
|
config GENERIC_CALIBRATE_DELAY
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_TIME_VSYSCALL
|
config GENERIC_TIME_VSYSCALL
|
||||||
def_bool n
|
def_bool n
|
||||||
|
|
||||||
|
|
|
@ -758,10 +758,6 @@ config GENERIC_CLOCKEVENTS
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -46,9 +46,6 @@ config GENERIC_FIND_NEXT_BIT
|
||||||
config GENERIC_HWEIGHT
|
config GENERIC_HWEIGHT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_BUG
|
config GENERIC_BUG
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config TIME_LOW_RES
|
config TIME_LOW_RES
|
||||||
bool
|
bool
|
||||||
depends on SMP
|
depends on SMP
|
||||||
|
|
|
@ -29,9 +29,6 @@ config MMU
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_TIME_VSYSCALL
|
config GENERIC_TIME_VSYSCALL
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -796,36 +796,10 @@ static cycle_t timebase_read(struct clocksource *cs)
|
||||||
return (cycle_t)get_tb();
|
return (cycle_t)get_tb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
|
void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
|
||||||
u64 new_tb_to_xs, struct timespec *now,
|
struct clocksource *clock, u32 mult)
|
||||||
u32 frac_sec)
|
|
||||||
{
|
{
|
||||||
/*
|
u64 new_tb_to_xs, new_stamp_xsec;
|
||||||
* tb_update_count is used to allow the userspace gettimeofday code
|
|
||||||
* to assure itself that it sees a consistent view of the tb_to_xs and
|
|
||||||
* stamp_xsec variables. It reads the tb_update_count, then reads
|
|
||||||
* tb_to_xs and stamp_xsec and then reads tb_update_count again. If
|
|
||||||
* the two values of tb_update_count match and are even then the
|
|
||||||
* tb_to_xs and stamp_xsec values are consistent. If not, then it
|
|
||||||
* loops back and reads them again until this criteria is met.
|
|
||||||
* We expect the caller to have done the first increment of
|
|
||||||
* vdso_data->tb_update_count already.
|
|
||||||
*/
|
|
||||||
vdso_data->tb_orig_stamp = new_tb_stamp;
|
|
||||||
vdso_data->stamp_xsec = new_stamp_xsec;
|
|
||||||
vdso_data->tb_to_xs = new_tb_to_xs;
|
|
||||||
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
|
|
||||||
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
|
|
||||||
vdso_data->stamp_xtime = *now;
|
|
||||||
vdso_data->stamp_sec_fraction = frac_sec;
|
|
||||||
smp_wmb();
|
|
||||||
++(vdso_data->tb_update_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
|
||||||
u32 mult)
|
|
||||||
{
|
|
||||||
u64 t2x, stamp_xsec;
|
|
||||||
u32 frac_sec;
|
u32 frac_sec;
|
||||||
|
|
||||||
if (clock != &clocksource_timebase)
|
if (clock != &clocksource_timebase)
|
||||||
|
@ -837,15 +811,35 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
||||||
|
|
||||||
/* XXX this assumes clock->shift == 22 */
|
/* XXX this assumes clock->shift == 22 */
|
||||||
/* 4611686018 ~= 2^(20+64-22) / 1e9 */
|
/* 4611686018 ~= 2^(20+64-22) / 1e9 */
|
||||||
t2x = (u64) mult * 4611686018ULL;
|
new_tb_to_xs = (u64) mult * 4611686018ULL;
|
||||||
stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
|
new_stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
|
||||||
do_div(stamp_xsec, 1000000000);
|
do_div(new_stamp_xsec, 1000000000);
|
||||||
stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
|
new_stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
|
||||||
|
|
||||||
BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
|
BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
|
||||||
/* this is tv_nsec / 1e9 as a 0.32 fraction */
|
/* this is tv_nsec / 1e9 as a 0.32 fraction */
|
||||||
frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
|
frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
|
||||||
update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec);
|
|
||||||
|
/*
|
||||||
|
* tb_update_count is used to allow the userspace gettimeofday code
|
||||||
|
* to assure itself that it sees a consistent view of the tb_to_xs and
|
||||||
|
* stamp_xsec variables. It reads the tb_update_count, then reads
|
||||||
|
* tb_to_xs and stamp_xsec and then reads tb_update_count again. If
|
||||||
|
* the two values of tb_update_count match and are even then the
|
||||||
|
* tb_to_xs and stamp_xsec values are consistent. If not, then it
|
||||||
|
* loops back and reads them again until this criteria is met.
|
||||||
|
* We expect the caller to have done the first increment of
|
||||||
|
* vdso_data->tb_update_count already.
|
||||||
|
*/
|
||||||
|
vdso_data->tb_orig_stamp = clock->cycle_last;
|
||||||
|
vdso_data->stamp_xsec = new_stamp_xsec;
|
||||||
|
vdso_data->tb_to_xs = new_tb_to_xs;
|
||||||
|
vdso_data->wtom_clock_sec = wtm->tv_sec;
|
||||||
|
vdso_data->wtom_clock_nsec = wtm->tv_nsec;
|
||||||
|
vdso_data->stamp_xtime = *wall_time;
|
||||||
|
vdso_data->stamp_sec_fraction = frac_sec;
|
||||||
|
smp_wmb();
|
||||||
|
++(vdso_data->tb_update_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_vsyscall_tz(void)
|
void update_vsyscall_tz(void)
|
||||||
|
|
|
@ -40,9 +40,6 @@ config ARCH_HAS_ILOG2_U64
|
||||||
config GENERIC_HWEIGHT
|
config GENERIC_HWEIGHT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_TIME_VSYSCALL
|
config GENERIC_TIME_VSYSCALL
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -207,8 +207,8 @@ struct clocksource * __init clocksource_default_clock(void)
|
||||||
return &clocksource_tod;
|
return &clocksource_tod;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
|
||||||
u32 mult)
|
struct clocksource *clock, u32 mult)
|
||||||
{
|
{
|
||||||
if (clock != &clocksource_tod)
|
if (clock != &clocksource_tod)
|
||||||
return;
|
return;
|
||||||
|
@ -219,8 +219,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
||||||
vdso_data->xtime_tod_stamp = clock->cycle_last;
|
vdso_data->xtime_tod_stamp = clock->cycle_last;
|
||||||
vdso_data->xtime_clock_sec = wall_time->tv_sec;
|
vdso_data->xtime_clock_sec = wall_time->tv_sec;
|
||||||
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
|
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
|
||||||
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
|
vdso_data->wtom_clock_sec = wtm->tv_sec;
|
||||||
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
|
vdso_data->wtom_clock_nsec = wtm->tv_nsec;
|
||||||
vdso_data->ntp_mult = mult;
|
vdso_data->ntp_mult = mult;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
++vdso_data->tb_update_count;
|
++vdso_data->tb_update_count;
|
||||||
|
|
|
@ -55,9 +55,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config SCHED_NO_NO_OMIT_FRAME_POINTER
|
config SCHED_NO_NO_OMIT_FRAME_POINTER
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,6 @@ config GENERIC_CALIBRATE_DELAY
|
||||||
config GENERIC_IOMAP
|
config GENERIC_IOMAP
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -67,9 +67,6 @@ config BITS
|
||||||
default 32 if SPARC32
|
default 32 if SPARC32
|
||||||
default 64 if SPARC64
|
default 64 if SPARC64
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config ARCH_USES_GETTIMEOFFSET
|
config ARCH_USES_GETTIMEOFFSET
|
||||||
bool
|
bool
|
||||||
default y if SPARC32
|
default y if SPARC32
|
||||||
|
|
|
@ -55,10 +55,6 @@ config GENERIC_BUG
|
||||||
default y
|
default y
|
||||||
depends on BUG
|
depends on BUG
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -102,16 +102,16 @@ static void __init setup_itimer(void)
|
||||||
clockevents_register_device(&itimer_clockevent);
|
clockevents_register_device(&itimer_clockevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_persistent_clock(struct timespec *ts)
|
||||||
|
{
|
||||||
|
long long nsecs = os_nsecs();
|
||||||
|
|
||||||
|
set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
|
||||||
|
nsecs % NSEC_PER_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
void __init time_init(void)
|
void __init time_init(void)
|
||||||
{
|
{
|
||||||
long long nsecs;
|
|
||||||
|
|
||||||
timer_init();
|
timer_init();
|
||||||
|
|
||||||
nsecs = os_nsecs();
|
|
||||||
set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
|
|
||||||
-nsecs % NSEC_PER_SEC);
|
|
||||||
set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
|
|
||||||
nsecs % NSEC_PER_SEC);
|
|
||||||
late_time_init = setup_itimer;
|
late_time_init = setup_itimer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,6 @@ config ARCH_DEFCONFIG
|
||||||
default "arch/x86/configs/i386_defconfig" if X86_32
|
default "arch/x86/configs/i386_defconfig" if X86_32
|
||||||
default "arch/x86/configs/x86_64_defconfig" if X86_64
|
default "arch/x86/configs/x86_64_defconfig" if X86_64
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
config GENERIC_CMOS_UPDATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
@ -2047,7 +2044,7 @@ config SCx200
|
||||||
|
|
||||||
config SCx200HR_TIMER
|
config SCx200HR_TIMER
|
||||||
tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
|
tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
|
||||||
depends on SCx200 && GENERIC_TIME
|
depends on SCx200
|
||||||
default y
|
default y
|
||||||
---help---
|
---help---
|
||||||
This driver provides a clocksource built upon the on-chip
|
This driver provides a clocksource built upon the on-chip
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <asm/hpet.h>
|
#include <asm/hpet.h>
|
||||||
|
|
||||||
#define HPET_MASK CLOCKSOURCE_MASK(32)
|
#define HPET_MASK CLOCKSOURCE_MASK(32)
|
||||||
#define HPET_SHIFT 22
|
|
||||||
|
|
||||||
/* FSEC = 10^-15
|
/* FSEC = 10^-15
|
||||||
NSEC = 10^-9 */
|
NSEC = 10^-9 */
|
||||||
|
@ -787,7 +786,6 @@ static struct clocksource clocksource_hpet = {
|
||||||
.rating = 250,
|
.rating = 250,
|
||||||
.read = read_hpet,
|
.read = read_hpet,
|
||||||
.mask = HPET_MASK,
|
.mask = HPET_MASK,
|
||||||
.shift = HPET_SHIFT,
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
.resume = hpet_resume_counter,
|
.resume = hpet_resume_counter,
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
@ -798,6 +796,7 @@ static struct clocksource clocksource_hpet = {
|
||||||
static int hpet_clocksource_register(void)
|
static int hpet_clocksource_register(void)
|
||||||
{
|
{
|
||||||
u64 start, now;
|
u64 start, now;
|
||||||
|
u64 hpet_freq;
|
||||||
cycle_t t1;
|
cycle_t t1;
|
||||||
|
|
||||||
/* Start the counter */
|
/* Start the counter */
|
||||||
|
@ -832,9 +831,15 @@ static int hpet_clocksource_register(void)
|
||||||
* mult = (hpet_period * 2^shift)/10^6
|
* mult = (hpet_period * 2^shift)/10^6
|
||||||
* mult = (hpet_period << shift)/FSEC_PER_NSEC
|
* mult = (hpet_period << shift)/FSEC_PER_NSEC
|
||||||
*/
|
*/
|
||||||
clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
|
|
||||||
|
|
||||||
clocksource_register(&clocksource_hpet);
|
/* Need to convert hpet_period (fsec/cyc) to cyc/sec:
|
||||||
|
*
|
||||||
|
* cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
|
||||||
|
* cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
|
||||||
|
*/
|
||||||
|
hpet_freq = FSEC_PER_NSEC * NSEC_PER_SEC;
|
||||||
|
do_div(hpet_freq, hpet_period);
|
||||||
|
clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,7 +751,6 @@ static struct clocksource clocksource_tsc = {
|
||||||
.read = read_tsc,
|
.read = read_tsc,
|
||||||
.resume = resume_tsc,
|
.resume = resume_tsc,
|
||||||
.mask = CLOCKSOURCE_MASK(64),
|
.mask = CLOCKSOURCE_MASK(64),
|
||||||
.shift = 22,
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
|
||||||
CLOCK_SOURCE_MUST_VERIFY,
|
CLOCK_SOURCE_MUST_VERIFY,
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
@ -845,8 +844,6 @@ __cpuinit int unsynchronized_tsc(void)
|
||||||
|
|
||||||
static void __init init_tsc_clocksource(void)
|
static void __init init_tsc_clocksource(void)
|
||||||
{
|
{
|
||||||
clocksource_tsc.mult = clocksource_khz2mult(tsc_khz,
|
|
||||||
clocksource_tsc.shift);
|
|
||||||
if (tsc_clocksource_reliable)
|
if (tsc_clocksource_reliable)
|
||||||
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
||||||
/* lower the rating if we already know its unstable: */
|
/* lower the rating if we already know its unstable: */
|
||||||
|
@ -854,7 +851,7 @@ static void __init init_tsc_clocksource(void)
|
||||||
clocksource_tsc.rating = 0;
|
clocksource_tsc.rating = 0;
|
||||||
clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
|
clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
|
||||||
}
|
}
|
||||||
clocksource_register(&clocksource_tsc);
|
clocksource_register_khz(&clocksource_tsc, tsc_khz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
|
|
@ -73,8 +73,8 @@ void update_vsyscall_tz(void)
|
||||||
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
|
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
|
||||||
u32 mult)
|
struct clocksource *clock, u32 mult)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
||||||
vsyscall_gtod_data.clock.shift = clock->shift;
|
vsyscall_gtod_data.clock.shift = clock->shift;
|
||||||
vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
|
vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
|
||||||
vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
|
vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
|
||||||
vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
|
vsyscall_gtod_data.wall_to_monotonic = *wtm;
|
||||||
vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
|
vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
|
||||||
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
|
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
|
||||||
}
|
}
|
||||||
|
@ -169,13 +169,18 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
|
||||||
* unlikely */
|
* unlikely */
|
||||||
time_t __vsyscall(1) vtime(time_t *t)
|
time_t __vsyscall(1) vtime(time_t *t)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
unsigned seq;
|
||||||
time_t result;
|
time_t result;
|
||||||
if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
|
if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
|
||||||
return time_syscall(t);
|
return time_syscall(t);
|
||||||
|
|
||||||
vgettimeofday(&tv, NULL);
|
do {
|
||||||
result = tv.tv_sec;
|
seq = read_seqbegin(&__vsyscall_gtod_data.lock);
|
||||||
|
|
||||||
|
result = __vsyscall_gtod_data.wall_time_sec;
|
||||||
|
|
||||||
|
} while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
*t = result;
|
*t = result;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -48,9 +48,6 @@ config HZ
|
||||||
int
|
int
|
||||||
default 100
|
default 100
|
||||||
|
|
||||||
config GENERIC_TIME
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
source "init/Kconfig"
|
source "init/Kconfig"
|
||||||
source "kernel/Kconfig.freezer"
|
source "kernel/Kconfig.freezer"
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,9 @@ obj-y += firmware/
|
||||||
obj-$(CONFIG_CRYPTO) += crypto/
|
obj-$(CONFIG_CRYPTO) += crypto/
|
||||||
obj-$(CONFIG_SUPERH) += sh/
|
obj-$(CONFIG_SUPERH) += sh/
|
||||||
obj-$(CONFIG_ARCH_SHMOBILE) += sh/
|
obj-$(CONFIG_ARCH_SHMOBILE) += sh/
|
||||||
obj-$(CONFIG_GENERIC_TIME) += clocksource/
|
ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||||
|
obj-y += clocksource/
|
||||||
|
endif
|
||||||
obj-$(CONFIG_DMA_ENGINE) += dma/
|
obj-$(CONFIG_DMA_ENGINE) += dma/
|
||||||
obj-$(CONFIG_DCA) += dca/
|
obj-$(CONFIG_DCA) += dca/
|
||||||
obj-$(CONFIG_HID) += hid/
|
obj-$(CONFIG_HID) += hid/
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void power_saving_mwait_init(void)
|
||||||
power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
|
power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
|
||||||
(highest_subcstate - 1);
|
(highest_subcstate - 1);
|
||||||
|
|
||||||
#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
|
#if defined(CONFIG_X86)
|
||||||
switch (boot_cpu_data.x86_vendor) {
|
switch (boot_cpu_data.x86_vendor) {
|
||||||
case X86_VENDOR_AMD:
|
case X86_VENDOR_AMD:
|
||||||
case X86_VENDOR_INTEL:
|
case X86_VENDOR_INTEL:
|
||||||
|
|
|
@ -264,7 +264,7 @@ int acpi_processor_resume(struct acpi_device * device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
|
#if defined(CONFIG_X86)
|
||||||
static void tsc_check_state(int state)
|
static void tsc_check_state(int state)
|
||||||
{
|
{
|
||||||
switch (boot_cpu_data.x86_vendor) {
|
switch (boot_cpu_data.x86_vendor) {
|
||||||
|
|
|
@ -68,10 +68,7 @@ static struct clocksource clocksource_acpi_pm = {
|
||||||
.rating = 200,
|
.rating = 200,
|
||||||
.read = acpi_pm_read,
|
.read = acpi_pm_read,
|
||||||
.mask = (cycle_t)ACPI_PM_MASK,
|
.mask = (cycle_t)ACPI_PM_MASK,
|
||||||
.mult = 0, /*to be calculated*/
|
|
||||||
.shift = 22,
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,9 +187,6 @@ static int __init init_acpi_pm_clocksource(void)
|
||||||
if (!pmtmr_ioport)
|
if (!pmtmr_ioport)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC,
|
|
||||||
clocksource_acpi_pm.shift);
|
|
||||||
|
|
||||||
/* "verify" this timing source: */
|
/* "verify" this timing source: */
|
||||||
for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
|
for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
|
||||||
udelay(100 * j);
|
udelay(100 * j);
|
||||||
|
@ -220,7 +214,8 @@ static int __init init_acpi_pm_clocksource(void)
|
||||||
if (verify_pmtmr_rate() != 0)
|
if (verify_pmtmr_rate() != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return clocksource_register(&clocksource_acpi_pm);
|
return clocksource_register_hz(&clocksource_acpi_pm,
|
||||||
|
PMTMR_TICKS_PER_SEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We use fs_initcall because we want the PCI fixups to have run
|
/* We use fs_initcall because we want the PCI fixups to have run
|
||||||
|
|
|
@ -72,7 +72,7 @@ config ATMEL_TCLIB
|
||||||
|
|
||||||
config ATMEL_TCB_CLKSRC
|
config ATMEL_TCB_CLKSRC
|
||||||
bool "TC Block Clocksource"
|
bool "TC Block Clocksource"
|
||||||
depends on ATMEL_TCLIB && GENERIC_TIME
|
depends on ATMEL_TCLIB
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Select this to get a high precision clocksource based on a
|
Select this to get a high precision clocksource based on a
|
||||||
|
@ -240,7 +240,7 @@ config CS5535_MFGPT_DEFAULT_IRQ
|
||||||
|
|
||||||
config CS5535_CLOCK_EVENT_SRC
|
config CS5535_CLOCK_EVENT_SRC
|
||||||
tristate "CS5535/CS5536 high-res timer (MFGPT) events"
|
tristate "CS5535/CS5536 high-res timer (MFGPT) events"
|
||||||
depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
|
depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT
|
||||||
help
|
help
|
||||||
This driver provides a clock event source based on the MFGPT
|
This driver provides a clock event source based on the MFGPT
|
||||||
timer(s) in the CS5535 and CS5536 companion chips.
|
timer(s) in the CS5535 and CS5536 companion chips.
|
||||||
|
|
|
@ -292,6 +292,8 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
|
||||||
*/
|
*/
|
||||||
extern int
|
extern int
|
||||||
__clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
|
__clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
|
||||||
|
extern void
|
||||||
|
__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
|
||||||
|
|
||||||
static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
|
static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
|
||||||
{
|
{
|
||||||
|
@ -303,6 +305,15 @@ static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
|
||||||
return __clocksource_register_scale(cs, 1000, khz);
|
return __clocksource_register_scale(cs, 1000, khz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz)
|
||||||
|
{
|
||||||
|
__clocksource_updatefreq_scale(cs, 1, hz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
|
||||||
|
{
|
||||||
|
__clocksource_updatefreq_scale(cs, 1000, khz);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
|
clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
|
||||||
|
@ -313,11 +324,13 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
||||||
extern void
|
extern void
|
||||||
update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult);
|
update_vsyscall(struct timespec *ts, struct timespec *wtm,
|
||||||
|
struct clocksource *c, u32 mult);
|
||||||
extern void update_vsyscall_tz(void);
|
extern void update_vsyscall_tz(void);
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult)
|
update_vsyscall(struct timespec *ts, struct timespec *wtm,
|
||||||
|
struct clocksource *c, u32 mult)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,25 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
|
||||||
const unsigned int min, const unsigned int sec);
|
const unsigned int min, const unsigned int sec);
|
||||||
|
|
||||||
extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
|
extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* timespec_add_safe assumes both values are positive and checks
|
||||||
|
* for overflow. It will return TIME_T_MAX if the reutrn would be
|
||||||
|
* smaller then either of the arguments.
|
||||||
|
*/
|
||||||
extern struct timespec timespec_add_safe(const struct timespec lhs,
|
extern struct timespec timespec_add_safe(const struct timespec lhs,
|
||||||
const struct timespec rhs);
|
const struct timespec rhs);
|
||||||
|
|
||||||
|
|
||||||
|
static inline struct timespec timespec_add(struct timespec lhs,
|
||||||
|
struct timespec rhs)
|
||||||
|
{
|
||||||
|
struct timespec ts_delta;
|
||||||
|
set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec,
|
||||||
|
lhs.tv_nsec + rhs.tv_nsec);
|
||||||
|
return ts_delta;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sub = lhs - rhs, in normalized form
|
* sub = lhs - rhs, in normalized form
|
||||||
*/
|
*/
|
||||||
|
@ -97,8 +113,6 @@ static inline struct timespec timespec_sub(struct timespec lhs,
|
||||||
#define timespec_valid(ts) \
|
#define timespec_valid(ts) \
|
||||||
(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
|
(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
|
||||||
|
|
||||||
extern struct timespec xtime;
|
|
||||||
extern struct timespec wall_to_monotonic;
|
|
||||||
extern seqlock_t xtime_lock;
|
extern seqlock_t xtime_lock;
|
||||||
|
|
||||||
extern void read_persistent_clock(struct timespec *ts);
|
extern void read_persistent_clock(struct timespec *ts);
|
||||||
|
@ -110,7 +124,8 @@ extern int timekeeping_suspended;
|
||||||
|
|
||||||
unsigned long get_seconds(void);
|
unsigned long get_seconds(void);
|
||||||
struct timespec current_kernel_time(void);
|
struct timespec current_kernel_time(void);
|
||||||
struct timespec __current_kernel_time(void); /* does not hold xtime_lock */
|
struct timespec __current_kernel_time(void); /* does not take xtime_lock */
|
||||||
|
struct timespec __get_wall_to_monotonic(void); /* does not take xtime_lock */
|
||||||
struct timespec get_monotonic_coarse(void);
|
struct timespec get_monotonic_coarse(void);
|
||||||
|
|
||||||
#define CURRENT_TIME (current_kernel_time())
|
#define CURRENT_TIME (current_kernel_time())
|
||||||
|
|
|
@ -2548,6 +2548,7 @@ static void kdb_sysinfo(struct sysinfo *val)
|
||||||
*/
|
*/
|
||||||
static int kdb_summary(int argc, const char **argv)
|
static int kdb_summary(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
|
struct timespec now;
|
||||||
struct kdb_tm tm;
|
struct kdb_tm tm;
|
||||||
struct sysinfo val;
|
struct sysinfo val;
|
||||||
|
|
||||||
|
@ -2562,7 +2563,8 @@ static int kdb_summary(int argc, const char **argv)
|
||||||
kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
|
kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
|
||||||
kdb_printf("ccversion %s\n", __stringify(CCVERSION));
|
kdb_printf("ccversion %s\n", __stringify(CCVERSION));
|
||||||
|
|
||||||
kdb_gmtime(&xtime, &tm);
|
now = __current_kernel_time();
|
||||||
|
kdb_gmtime(&now, &tm);
|
||||||
kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d "
|
kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d "
|
||||||
"tz_minuteswest %d\n",
|
"tz_minuteswest %d\n",
|
||||||
1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
|
1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
|
||||||
|
|
|
@ -90,7 +90,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
|
||||||
do {
|
do {
|
||||||
seq = read_seqbegin(&xtime_lock);
|
seq = read_seqbegin(&xtime_lock);
|
||||||
xts = __current_kernel_time();
|
xts = __current_kernel_time();
|
||||||
tom = wall_to_monotonic;
|
tom = __get_wall_to_monotonic();
|
||||||
} while (read_seqretry(&xtime_lock, seq));
|
} while (read_seqretry(&xtime_lock, seq));
|
||||||
|
|
||||||
xtim = timespec_to_ktime(xts);
|
xtim = timespec_to_ktime(xts);
|
||||||
|
@ -608,7 +608,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
|
||||||
static void retrigger_next_event(void *arg)
|
static void retrigger_next_event(void *arg)
|
||||||
{
|
{
|
||||||
struct hrtimer_cpu_base *base;
|
struct hrtimer_cpu_base *base;
|
||||||
struct timespec realtime_offset;
|
struct timespec realtime_offset, wtm;
|
||||||
unsigned long seq;
|
unsigned long seq;
|
||||||
|
|
||||||
if (!hrtimer_hres_active())
|
if (!hrtimer_hres_active())
|
||||||
|
@ -616,10 +616,9 @@ static void retrigger_next_event(void *arg)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
seq = read_seqbegin(&xtime_lock);
|
seq = read_seqbegin(&xtime_lock);
|
||||||
set_normalized_timespec(&realtime_offset,
|
wtm = __get_wall_to_monotonic();
|
||||||
-wall_to_monotonic.tv_sec,
|
|
||||||
-wall_to_monotonic.tv_nsec);
|
|
||||||
} while (read_seqretry(&xtime_lock, seq));
|
} while (read_seqretry(&xtime_lock, seq));
|
||||||
|
set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec);
|
||||||
|
|
||||||
base = &__get_cpu_var(hrtimer_bases);
|
base = &__get_cpu_var(hrtimer_bases);
|
||||||
|
|
||||||
|
|
|
@ -300,22 +300,6 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(timespec_trunc);
|
EXPORT_SYMBOL(timespec_trunc);
|
||||||
|
|
||||||
#ifndef CONFIG_GENERIC_TIME
|
|
||||||
/*
|
|
||||||
* Simulate gettimeofday using do_gettimeofday which only allows a timeval
|
|
||||||
* and therefore only yields usec accuracy
|
|
||||||
*/
|
|
||||||
void getnstimeofday(struct timespec *tv)
|
|
||||||
{
|
|
||||||
struct timeval x;
|
|
||||||
|
|
||||||
do_gettimeofday(&x);
|
|
||||||
tv->tv_sec = x.tv_sec;
|
|
||||||
tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(getnstimeofday);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
||||||
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
||||||
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
||||||
|
|
|
@ -6,7 +6,7 @@ config TICK_ONESHOT
|
||||||
|
|
||||||
config NO_HZ
|
config NO_HZ
|
||||||
bool "Tickless System (Dynamic Ticks)"
|
bool "Tickless System (Dynamic Ticks)"
|
||||||
depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
|
depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
|
||||||
select TICK_ONESHOT
|
select TICK_ONESHOT
|
||||||
help
|
help
|
||||||
This option enables a tickless system: timer interrupts will
|
This option enables a tickless system: timer interrupts will
|
||||||
|
@ -15,7 +15,7 @@ config NO_HZ
|
||||||
|
|
||||||
config HIGH_RES_TIMERS
|
config HIGH_RES_TIMERS
|
||||||
bool "High Resolution Timer Support"
|
bool "High Resolution Timer Support"
|
||||||
depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
|
depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
|
||||||
select TICK_ONESHOT
|
select TICK_ONESHOT
|
||||||
help
|
help
|
||||||
This option enables high resolution timer support. If your
|
This option enables high resolution timer support. If your
|
||||||
|
|
|
@ -531,7 +531,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
|
||||||
return max_nsecs - (max_nsecs >> 5);
|
return max_nsecs - (max_nsecs >> 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_TIME
|
#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clocksource_select - Select the best clocksource available
|
* clocksource_select - Select the best clocksource available
|
||||||
|
@ -577,7 +577,7 @@ static void clocksource_select(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_GENERIC_TIME */
|
#else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
|
||||||
|
|
||||||
static inline void clocksource_select(void) { }
|
static inline void clocksource_select(void) { }
|
||||||
|
|
||||||
|
@ -638,6 +638,32 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||||
*/
|
*/
|
||||||
#define MAX_UPDATE_LENGTH 5 /* Seconds */
|
#define MAX_UPDATE_LENGTH 5 /* Seconds */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __clocksource_updatefreq_scale - Used update clocksource with new freq
|
||||||
|
* @t: clocksource to be registered
|
||||||
|
* @scale: Scale factor multiplied against freq to get clocksource hz
|
||||||
|
* @freq: clocksource frequency (cycles per second) divided by scale
|
||||||
|
*
|
||||||
|
* This should only be called from the clocksource->enable() method.
|
||||||
|
*
|
||||||
|
* This *SHOULD NOT* be called directly! Please use the
|
||||||
|
* clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions.
|
||||||
|
*/
|
||||||
|
void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Ideally we want to use some of the limits used in
|
||||||
|
* clocksource_max_deferment, to provide a more informed
|
||||||
|
* MAX_UPDATE_LENGTH. But for now this just gets the
|
||||||
|
* register interface working properly.
|
||||||
|
*/
|
||||||
|
clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
|
||||||
|
NSEC_PER_SEC/scale,
|
||||||
|
MAX_UPDATE_LENGTH*scale);
|
||||||
|
cs->max_idle_ns = clocksource_max_deferment(cs);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __clocksource_register_scale - Used to install new clocksources
|
* __clocksource_register_scale - Used to install new clocksources
|
||||||
* @t: clocksource to be registered
|
* @t: clocksource to be registered
|
||||||
|
@ -652,17 +678,10 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||||
int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/* Intialize mult/shift and max_idle_ns */
|
||||||
* Ideally we want to use some of the limits used in
|
__clocksource_updatefreq_scale(cs, scale, freq);
|
||||||
* clocksource_max_deferment, to provide a more informed
|
|
||||||
* MAX_UPDATE_LENGTH. But for now this just gets the
|
|
||||||
* register interface working properly.
|
|
||||||
*/
|
|
||||||
clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
|
|
||||||
NSEC_PER_SEC/scale,
|
|
||||||
MAX_UPDATE_LENGTH*scale);
|
|
||||||
cs->max_idle_ns = clocksource_max_deferment(cs);
|
|
||||||
|
|
||||||
|
/* Add clocksource to the clcoksource list */
|
||||||
mutex_lock(&clocksource_mutex);
|
mutex_lock(&clocksource_mutex);
|
||||||
clocksource_enqueue(cs);
|
clocksource_enqueue(cs);
|
||||||
clocksource_select();
|
clocksource_select();
|
||||||
|
|
|
@ -153,8 +153,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
|
||||||
* - wall_to_monotonic is no longer the boot time, getboottime must be
|
* - wall_to_monotonic is no longer the boot time, getboottime must be
|
||||||
* used instead.
|
* used instead.
|
||||||
*/
|
*/
|
||||||
struct timespec xtime __attribute__ ((aligned (16)));
|
static struct timespec xtime __attribute__ ((aligned (16)));
|
||||||
struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
|
static struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
|
||||||
static struct timespec total_sleep_time;
|
static struct timespec total_sleep_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -170,11 +170,10 @@ void timekeeping_leap_insert(int leapsecond)
|
||||||
{
|
{
|
||||||
xtime.tv_sec += leapsecond;
|
xtime.tv_sec += leapsecond;
|
||||||
wall_to_monotonic.tv_sec -= leapsecond;
|
wall_to_monotonic.tv_sec -= leapsecond;
|
||||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||||
|
timekeeper.mult);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_TIME
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* timekeeping_forward_now - update clock to the current time
|
* timekeeping_forward_now - update clock to the current time
|
||||||
*
|
*
|
||||||
|
@ -328,7 +327,8 @@ int do_settimeofday(struct timespec *tv)
|
||||||
timekeeper.ntp_error = 0;
|
timekeeper.ntp_error = 0;
|
||||||
ntp_clear();
|
ntp_clear();
|
||||||
|
|
||||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||||
|
timekeeper.mult);
|
||||||
|
|
||||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||||
|
|
||||||
|
@ -376,52 +376,6 @@ void timekeeping_notify(struct clocksource *clock)
|
||||||
tick_clock_notify();
|
tick_clock_notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* GENERIC_TIME */
|
|
||||||
|
|
||||||
static inline void timekeeping_forward_now(void) { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ktime_get - get the monotonic time in ktime_t format
|
|
||||||
*
|
|
||||||
* returns the time in ktime_t format
|
|
||||||
*/
|
|
||||||
ktime_t ktime_get(void)
|
|
||||||
{
|
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
ktime_get_ts(&now);
|
|
||||||
|
|
||||||
return timespec_to_ktime(now);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(ktime_get);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ktime_get_ts - get the monotonic clock in timespec format
|
|
||||||
* @ts: pointer to timespec variable
|
|
||||||
*
|
|
||||||
* The function calculates the monotonic clock from the realtime
|
|
||||||
* clock and the wall_to_monotonic offset and stores the result
|
|
||||||
* in normalized timespec format in the variable pointed to by @ts.
|
|
||||||
*/
|
|
||||||
void ktime_get_ts(struct timespec *ts)
|
|
||||||
{
|
|
||||||
struct timespec tomono;
|
|
||||||
unsigned long seq;
|
|
||||||
|
|
||||||
do {
|
|
||||||
seq = read_seqbegin(&xtime_lock);
|
|
||||||
getnstimeofday(ts);
|
|
||||||
tomono = wall_to_monotonic;
|
|
||||||
|
|
||||||
} while (read_seqretry(&xtime_lock, seq));
|
|
||||||
|
|
||||||
set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
|
|
||||||
ts->tv_nsec + tomono.tv_nsec);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(ktime_get_ts);
|
|
||||||
|
|
||||||
#endif /* !GENERIC_TIME */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ktime_get_real - get the real (wall-) time in ktime_t format
|
* ktime_get_real - get the real (wall-) time in ktime_t format
|
||||||
*
|
*
|
||||||
|
@ -579,9 +533,9 @@ static int timekeeping_resume(struct sys_device *dev)
|
||||||
|
|
||||||
if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
|
if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
|
||||||
ts = timespec_sub(ts, timekeeping_suspend_time);
|
ts = timespec_sub(ts, timekeeping_suspend_time);
|
||||||
xtime = timespec_add_safe(xtime, ts);
|
xtime = timespec_add(xtime, ts);
|
||||||
wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
|
wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
|
||||||
total_sleep_time = timespec_add_safe(total_sleep_time, ts);
|
total_sleep_time = timespec_add(total_sleep_time, ts);
|
||||||
}
|
}
|
||||||
/* re-base the last cycle value */
|
/* re-base the last cycle value */
|
||||||
timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
|
timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
|
||||||
|
@ -784,10 +738,11 @@ void update_wall_time(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clock = timekeeper.clock;
|
clock = timekeeper.clock;
|
||||||
#ifdef CONFIG_GENERIC_TIME
|
|
||||||
offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
|
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||||
#else
|
|
||||||
offset = timekeeper.cycle_interval;
|
offset = timekeeper.cycle_interval;
|
||||||
|
#else
|
||||||
|
offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
|
||||||
#endif
|
#endif
|
||||||
timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
|
timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
|
||||||
|
|
||||||
|
@ -856,7 +811,8 @@ void update_wall_time(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check to see if there is a new clocksource to use */
|
/* check to see if there is a new clocksource to use */
|
||||||
update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
|
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
|
||||||
|
timekeeper.mult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -887,7 +843,7 @@ EXPORT_SYMBOL_GPL(getboottime);
|
||||||
*/
|
*/
|
||||||
void monotonic_to_bootbased(struct timespec *ts)
|
void monotonic_to_bootbased(struct timespec *ts)
|
||||||
{
|
{
|
||||||
*ts = timespec_add_safe(*ts, total_sleep_time);
|
*ts = timespec_add(*ts, total_sleep_time);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
|
EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
|
||||||
|
|
||||||
|
@ -902,6 +858,11 @@ struct timespec __current_kernel_time(void)
|
||||||
return xtime;
|
return xtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct timespec __get_wall_to_monotonic(void)
|
||||||
|
{
|
||||||
|
return wall_to_monotonic;
|
||||||
|
}
|
||||||
|
|
||||||
struct timespec current_kernel_time(void)
|
struct timespec current_kernel_time(void)
|
||||||
{
|
{
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
|
|
@ -153,7 +153,7 @@ config IRQSOFF_TRACER
|
||||||
bool "Interrupts-off Latency Tracer"
|
bool "Interrupts-off Latency Tracer"
|
||||||
default n
|
default n
|
||||||
depends on TRACE_IRQFLAGS_SUPPORT
|
depends on TRACE_IRQFLAGS_SUPPORT
|
||||||
depends on GENERIC_TIME
|
depends on !ARCH_USES_GETTIMEOFFSET
|
||||||
select TRACE_IRQFLAGS
|
select TRACE_IRQFLAGS
|
||||||
select GENERIC_TRACER
|
select GENERIC_TRACER
|
||||||
select TRACER_MAX_TRACE
|
select TRACER_MAX_TRACE
|
||||||
|
@ -175,7 +175,7 @@ config IRQSOFF_TRACER
|
||||||
config PREEMPT_TRACER
|
config PREEMPT_TRACER
|
||||||
bool "Preemption-off Latency Tracer"
|
bool "Preemption-off Latency Tracer"
|
||||||
default n
|
default n
|
||||||
depends on GENERIC_TIME
|
depends on !ARCH_USES_GETTIMEOFFSET
|
||||||
depends on PREEMPT
|
depends on PREEMPT
|
||||||
select GENERIC_TRACER
|
select GENERIC_TRACER
|
||||||
select TRACER_MAX_TRACE
|
select TRACER_MAX_TRACE
|
||||||
|
|
Loading…
Reference in New Issue