You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (34 commits) time: Prevent 32 bit overflow with set_normalized_timespec() clocksource: Delay clocksource down rating to late boot clocksource: clocksource_select must be called with mutex locked clocksource: Resolve cpu hotplug dead lock with TSC unstable, fix crash timers: Drop a function prototype clocksource: Resolve cpu hotplug dead lock with TSC unstable timer.c: Fix S/390 comments timekeeping: Fix invalid getboottime() value timekeeping: Fix up read_persistent_clock() breakage on sh timekeeping: Increase granularity of read_persistent_clock(), build fix time: Introduce CLOCK_REALTIME_COARSE x86: Do not unregister PIT clocksource on PIT oneshot setup/shutdown clocksource: Avoid clocksource watchdog circular locking dependency clocksource: Protect the watchdog rating changes with clocksource_mutex clocksource: Call clocksource_change_rating() outside of watchdog_lock timekeeping: Introduce read_boot_clock timekeeping: Increase granularity of read_persistent_clock() timekeeping: Update clocksource with stop_machine timekeeping: Add timekeeper read_clock helper functions timekeeping: Move NTP adjusted clock multiplier to struct timekeeper ... Fix trivial conflict due to MIPS lemote -> loongson renaming.
This commit is contained in:
@@ -253,11 +253,8 @@ static struct clocksource clocksource_32k = {
|
||||
*/
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
unsigned long long ret;
|
||||
|
||||
ret = (unsigned long long)clocksource_32k.read(&clocksource_32k);
|
||||
ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
|
||||
return ret;
|
||||
return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
|
||||
clocksource_32k.mult, clocksource_32k.shift);
|
||||
}
|
||||
|
||||
static int __init omap_init_clocksource_32k(void)
|
||||
|
||||
@@ -72,9 +72,10 @@ static unsigned long read_rtc_mmss(void)
|
||||
return mktime(year, mon, day, hour, min, sec);
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
return read_rtc_mmss();
|
||||
ts->tv_sec = read_rtc_mmss();
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int update_persistent_clock(struct timespec now)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <asm/dec/ioasic.h>
|
||||
#include <asm/dec/machtype.h>
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
unsigned int year, mon, day, hour, min, sec, real_year;
|
||||
unsigned long flags;
|
||||
@@ -53,7 +53,8 @@ unsigned long read_persistent_clock(void)
|
||||
|
||||
year += real_year - 72 + 2000;
|
||||
|
||||
return mktime(year, mon, day, hour, min, sec);
|
||||
ts->tv_sec = mktime(year, mon, day, hour, min, sec);
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -135,7 +135,7 @@ static void rtc_end_op(void)
|
||||
lasat_ndelay(1000);
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
unsigned long word;
|
||||
unsigned long flags;
|
||||
@@ -147,7 +147,8 @@ unsigned long read_persistent_clock(void)
|
||||
rtc_end_op();
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
return word;
|
||||
ts->tv_sec = word;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int rtc_mips_set_mmss(unsigned long time)
|
||||
|
||||
@@ -92,10 +92,12 @@ static int rtctmp;
|
||||
int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct timespec ts;
|
||||
int r;
|
||||
|
||||
if (!write) {
|
||||
rtctmp = read_persistent_clock();
|
||||
read_persistent_clock(&ts);
|
||||
rtctmp = ts.tv_sec;
|
||||
/* check for time < 0 and set to 0 */
|
||||
if (rtctmp < 0)
|
||||
rtctmp = 0;
|
||||
@@ -134,9 +136,11 @@ int sysctl_lasat_rtc(ctl_table *table,
|
||||
void *oldval, size_t *oldlenp,
|
||||
void *newval, size_t newlen)
|
||||
{
|
||||
struct timespec ts;
|
||||
int r;
|
||||
|
||||
rtctmp = read_persistent_clock();
|
||||
read_persistent_clock(&ts);
|
||||
rtctmp = ts.tv_sec;
|
||||
if (rtctmp < 0)
|
||||
rtctmp = 0;
|
||||
r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
|
||||
|
||||
@@ -21,7 +21,8 @@ void __init plat_time_init(void)
|
||||
mips_hpt_frequency = cpu_clock_freq / 2;
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
return mc146818_get_cmos_time();
|
||||
ts->tv_sec = return mc146818_get_cmos_time();
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
@@ -100,9 +100,10 @@ static unsigned int __init estimate_cpu_frequency(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
return mc146818_get_cmos_time();
|
||||
ts->tv_sec = mc146818_get_cmos_time();
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
static void __init plat_perf_setup(void)
|
||||
|
||||
@@ -70,7 +70,7 @@ void __init bus_error_init(void)
|
||||
}
|
||||
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
unsigned int year, month, day, hour, min, sec;
|
||||
unsigned long flags;
|
||||
@@ -92,7 +92,8 @@ unsigned long read_persistent_clock(void)
|
||||
m48t37_base->control = 0x00;
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
return mktime(year, month, day, hour, min, sec);
|
||||
ts->tv_sec = mktime(year, month, day, hour, min, sec);
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int rtc_mips_set_time(unsigned long tim)
|
||||
|
||||
@@ -87,19 +87,26 @@ enum swarm_rtc_type {
|
||||
|
||||
enum swarm_rtc_type swarm_rtc_type;
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
unsigned long sec;
|
||||
|
||||
switch (swarm_rtc_type) {
|
||||
case RTC_XICOR:
|
||||
return xicor_get_time();
|
||||
sec = xicor_get_time();
|
||||
break;
|
||||
|
||||
case RTC_M4LT81:
|
||||
return m41t81_get_time();
|
||||
sec = m41t81_get_time();
|
||||
break;
|
||||
|
||||
case RTC_NONE:
|
||||
default:
|
||||
return mktime(2000, 1, 1, 0, 0, 0);
|
||||
sec = mktime(2000, 1, 1, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
ts->tv_sec = sec;
|
||||
tv->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int rtc_mips_set_time(unsigned long sec)
|
||||
|
||||
@@ -182,7 +182,8 @@ void __init plat_time_init(void)
|
||||
setup_pit_timer();
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
return -1;
|
||||
ts->tv_sec = -1;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
@@ -774,11 +774,12 @@ int update_persistent_clock(struct timespec now)
|
||||
return ppc_md.set_rtc_time(&tm);
|
||||
}
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
struct rtc_time tm;
|
||||
static int first = 1;
|
||||
|
||||
ts->tv_nsec = 0;
|
||||
/* XXX this is a litle fragile but will work okay in the short term */
|
||||
if (first) {
|
||||
first = 0;
|
||||
@@ -786,14 +787,18 @@ unsigned long read_persistent_clock(void)
|
||||
timezone_offset = ppc_md.time_init();
|
||||
|
||||
/* get_boot_time() isn't guaranteed to be safe to call late */
|
||||
if (ppc_md.get_boot_time)
|
||||
return ppc_md.get_boot_time() -timezone_offset;
|
||||
if (ppc_md.get_boot_time) {
|
||||
ts->tv_sec = ppc_md.get_boot_time() - timezone_offset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!ppc_md.get_rtc_time) {
|
||||
ts->tv_sec = 0;
|
||||
return;
|
||||
}
|
||||
if (!ppc_md.get_rtc_time)
|
||||
return 0;
|
||||
ppc_md.get_rtc_time(&tm);
|
||||
return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
|
||||
/* clocksource code */
|
||||
|
||||
+10
-28
@@ -184,12 +184,14 @@ static void timing_alert_interrupt(__u16 code)
|
||||
static void etr_reset(void);
|
||||
static void stp_reset(void);
|
||||
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
struct timespec ts;
|
||||
tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, ts);
|
||||
}
|
||||
|
||||
tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts);
|
||||
return ts.tv_sec;
|
||||
void read_boot_clock(struct timespec *ts)
|
||||
{
|
||||
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts);
|
||||
}
|
||||
|
||||
static cycle_t read_tod_clock(struct clocksource *cs)
|
||||
@@ -207,6 +209,10 @@ static struct clocksource clocksource_tod = {
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
struct clocksource * __init clocksource_default_clock(void)
|
||||
{
|
||||
return &clocksource_tod;
|
||||
}
|
||||
|
||||
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
|
||||
{
|
||||
@@ -244,10 +250,6 @@ void update_vsyscall_tz(void)
|
||||
*/
|
||||
void __init time_init(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
unsigned long flags;
|
||||
cycle_t now;
|
||||
|
||||
/* Reset time synchronization interfaces. */
|
||||
etr_reset();
|
||||
stp_reset();
|
||||
@@ -263,26 +265,6 @@ void __init time_init(void)
|
||||
if (clocksource_register(&clocksource_tod) != 0)
|
||||
panic("Could not register TOD clock source");
|
||||
|
||||
/*
|
||||
* The TOD clock is an accurate clock. The xtime should be
|
||||
* initialized in a way that the difference between TOD and
|
||||
* xtime is reasonably small. Too bad that timekeeping_init
|
||||
* sets xtime.tv_nsec to zero. In addition the clock source
|
||||
* change from the jiffies clock source to the TOD clock
|
||||
* source add another error of up to 1/HZ second. The same
|
||||
* function sets wall_to_monotonic to a value that is too
|
||||
* small for /proc/uptime to be accurate.
|
||||
* Reset xtime and wall_to_monotonic to sane values.
|
||||
*/
|
||||
write_seqlock_irqsave(&xtime_lock, flags);
|
||||
now = get_clock();
|
||||
tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
|
||||
clocksource_tod.cycle_last = now;
|
||||
clocksource_tod.raw_time = xtime;
|
||||
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
|
||||
set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
/* Enable TOD clock interrupts on the boot cpu. */
|
||||
init_cpu_timer();
|
||||
|
||||
|
||||
@@ -39,11 +39,9 @@ void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
|
||||
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
|
||||
|
||||
#ifdef CONFIG_GENERIC_CMOS_UPDATE
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
struct timespec tv;
|
||||
rtc_sh_get_time(&tv);
|
||||
return tv.tv_sec;
|
||||
rtc_sh_get_time(ts);
|
||||
}
|
||||
|
||||
int update_persistent_clock(struct timespec now)
|
||||
|
||||
@@ -21,6 +21,7 @@ struct vsyscall_gtod_data {
|
||||
u32 shift;
|
||||
} clock;
|
||||
struct timespec wall_to_monotonic;
|
||||
struct timespec wall_time_coarse;
|
||||
};
|
||||
extern struct vsyscall_gtod_data __vsyscall_gtod_data
|
||||
__section_vsyscall_gtod_data;
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
DEFINE_SPINLOCK(i8253_lock);
|
||||
EXPORT_SYMBOL(i8253_lock);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static void pit_disable_clocksource(void);
|
||||
#else
|
||||
static inline void pit_disable_clocksource(void) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
* HPET replaces the PIT, when enabled. So we need to know, which of
|
||||
* the two timers is used
|
||||
@@ -57,12 +51,10 @@ static void init_pit_timer(enum clock_event_mode mode,
|
||||
outb_pit(0, PIT_CH0);
|
||||
outb_pit(0, PIT_CH0);
|
||||
}
|
||||
pit_disable_clocksource();
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* One shot setup */
|
||||
pit_disable_clocksource();
|
||||
outb_pit(0x38, PIT_MODE);
|
||||
break;
|
||||
|
||||
@@ -200,17 +192,6 @@ static struct clocksource pit_cs = {
|
||||
.shift = 20,
|
||||
};
|
||||
|
||||
static void pit_disable_clocksource(void)
|
||||
{
|
||||
/*
|
||||
* Use mult to check whether it is registered or not
|
||||
*/
|
||||
if (pit_cs.mult) {
|
||||
clocksource_unregister(&pit_cs);
|
||||
pit_cs.mult = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init init_pit_clocksource(void)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -178,7 +178,7 @@ static int set_rtc_mmss(unsigned long nowtime)
|
||||
}
|
||||
|
||||
/* not static: needed by APM */
|
||||
unsigned long read_persistent_clock(void)
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
{
|
||||
unsigned long retval, flags;
|
||||
|
||||
@@ -186,7 +186,8 @@ unsigned long read_persistent_clock(void)
|
||||
retval = get_wallclock();
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
return retval;
|
||||
ts->tv_sec = retval;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int update_persistent_clock(struct timespec now)
|
||||
|
||||
+11
-3
@@ -744,10 +744,16 @@ static cycle_t __vsyscall_fn vread_tsc(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void resume_tsc(void)
|
||||
{
|
||||
clocksource_tsc.cycle_last = 0;
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_tsc = {
|
||||
.name = "tsc",
|
||||
.rating = 300,
|
||||
.read = read_tsc,
|
||||
.resume = resume_tsc,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.shift = 22,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
|
||||
@@ -761,12 +767,14 @@ void mark_tsc_unstable(char *reason)
|
||||
{
|
||||
if (!tsc_unstable) {
|
||||
tsc_unstable = 1;
|
||||
printk("Marking TSC unstable due to %s\n", reason);
|
||||
printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
|
||||
/* Change only the rating, when not registered */
|
||||
if (clocksource_tsc.mult)
|
||||
clocksource_change_rating(&clocksource_tsc, 0);
|
||||
else
|
||||
clocksource_mark_unstable(&clocksource_tsc);
|
||||
else {
|
||||
clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
|
||||
clocksource_tsc.rating = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
|
||||
vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
|
||||
vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
|
||||
vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
|
||||
vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
|
||||
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,14 +86,47 @@ notrace static noinline int do_monotonic(struct timespec *ts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
notrace static noinline int do_realtime_coarse(struct timespec *ts)
|
||||
{
|
||||
unsigned long seq;
|
||||
do {
|
||||
seq = read_seqbegin(>od->lock);
|
||||
ts->tv_sec = gtod->wall_time_coarse.tv_sec;
|
||||
ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
|
||||
} while (unlikely(read_seqretry(>od->lock, seq)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
notrace static noinline int do_monotonic_coarse(struct timespec *ts)
|
||||
{
|
||||
unsigned long seq, ns, secs;
|
||||
do {
|
||||
seq = read_seqbegin(>od->lock);
|
||||
secs = gtod->wall_time_coarse.tv_sec;
|
||||
ns = gtod->wall_time_coarse.tv_nsec;
|
||||
secs += gtod->wall_to_monotonic.tv_sec;
|
||||
ns += gtod->wall_to_monotonic.tv_nsec;
|
||||
} while (unlikely(read_seqretry(>od->lock, seq)));
|
||||
vset_normalized_timespec(ts, secs, ns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
|
||||
{
|
||||
if (likely(gtod->sysctl_enabled && gtod->clock.vread))
|
||||
if (likely(gtod->sysctl_enabled))
|
||||
switch (clock) {
|
||||
case CLOCK_REALTIME:
|
||||
return do_realtime(ts);
|
||||
if (likely(gtod->clock.vread))
|
||||
return do_realtime(ts);
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
return do_monotonic(ts);
|
||||
if (likely(gtod->clock.vread))
|
||||
return do_monotonic(ts);
|
||||
break;
|
||||
case CLOCK_REALTIME_COARSE:
|
||||
return do_realtime_coarse(ts);
|
||||
case CLOCK_MONOTONIC_COARSE:
|
||||
return do_monotonic_coarse(ts);
|
||||
}
|
||||
return vdso_fallback_gettime(clock, ts);
|
||||
}
|
||||
|
||||
@@ -59,9 +59,8 @@ static struct irqaction timer_irqaction = {
|
||||
|
||||
void __init time_init(void)
|
||||
{
|
||||
xtime.tv_nsec = 0;
|
||||
xtime.tv_sec = read_persistent_clock();
|
||||
|
||||
/* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
|
||||
read_persistent_clock(&xtime);
|
||||
set_normalized_timespec(&wall_to_monotonic,
|
||||
-xtime.tv_sec, -xtime.tv_nsec);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user