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:
@@ -48,37 +48,6 @@
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/**
|
||||
* 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_real - get the real (wall-) time in ktime_t format
|
||||
*
|
||||
* returns the time in ktime_t format
|
||||
*/
|
||||
ktime_t ktime_get_real(void)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
getnstimeofday(&now);
|
||||
|
||||
return timespec_to_ktime(now);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ktime_get_real);
|
||||
|
||||
/*
|
||||
* The timer bases:
|
||||
*
|
||||
@@ -106,31 +75,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Get the coarse grained time at the softirq based on xtime and
|
||||
* wall_to_monotonic.
|
||||
@@ -1155,7 +1099,6 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
|
||||
clock_id = CLOCK_MONOTONIC;
|
||||
|
||||
timer->base = &cpu_base->clock_base[clock_id];
|
||||
INIT_LIST_HEAD(&timer->cb_entry);
|
||||
hrtimer_init_timer_hres(timer);
|
||||
|
||||
#ifdef CONFIG_TIMER_STATS
|
||||
|
||||
@@ -242,6 +242,25 @@ static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
|
||||
{
|
||||
*tp = current_kernel_time();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int posix_get_monotonic_coarse(clockid_t which_clock,
|
||||
struct timespec *tp)
|
||||
{
|
||||
*tp = get_monotonic_coarse();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
|
||||
{
|
||||
*tp = ktime_to_timespec(KTIME_LOW_RES);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Initialize everything, well, just everything in Posix clocks/timers ;)
|
||||
*/
|
||||
@@ -262,10 +281,26 @@ static __init int init_posix_timers(void)
|
||||
.timer_create = no_timer_create,
|
||||
.nsleep = no_nsleep,
|
||||
};
|
||||
struct k_clock clock_realtime_coarse = {
|
||||
.clock_getres = posix_get_coarse_res,
|
||||
.clock_get = posix_get_realtime_coarse,
|
||||
.clock_set = do_posix_clock_nosettime,
|
||||
.timer_create = no_timer_create,
|
||||
.nsleep = no_nsleep,
|
||||
};
|
||||
struct k_clock clock_monotonic_coarse = {
|
||||
.clock_getres = posix_get_coarse_res,
|
||||
.clock_get = posix_get_monotonic_coarse,
|
||||
.clock_set = do_posix_clock_nosettime,
|
||||
.timer_create = no_timer_create,
|
||||
.nsleep = no_nsleep,
|
||||
};
|
||||
|
||||
register_posix_clock(CLOCK_REALTIME, &clock_realtime);
|
||||
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
|
||||
register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
|
||||
register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
|
||||
register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
|
||||
|
||||
posix_timers_cache = kmem_cache_create("posix_timers_cache",
|
||||
sizeof (struct k_itimer), 0, SLAB_PANIC,
|
||||
|
||||
+8
-1
@@ -370,13 +370,20 @@ EXPORT_SYMBOL(mktime);
|
||||
* 0 <= tv_nsec < NSEC_PER_SEC
|
||||
* For negative values only the tv_sec field is negative !
|
||||
*/
|
||||
void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
|
||||
void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
|
||||
{
|
||||
while (nsec >= NSEC_PER_SEC) {
|
||||
/*
|
||||
* The following asm() prevents the compiler from
|
||||
* optimising this loop into a modulo operation. See
|
||||
* also __iter_div_u64_rem() in include/linux/time.h
|
||||
*/
|
||||
asm("" : "+rm"(nsec));
|
||||
nsec -= NSEC_PER_SEC;
|
||||
++sec;
|
||||
}
|
||||
while (nsec < 0) {
|
||||
asm("" : "+rm"(nsec));
|
||||
nsec += NSEC_PER_SEC;
|
||||
--sec;
|
||||
}
|
||||
|
||||
+312
-233
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,6 @@ struct clocksource clocksource_jiffies = {
|
||||
.read = jiffies_read,
|
||||
.mask = 0xffffffff, /*32bits*/
|
||||
.mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
|
||||
.mult_orig = NSEC_PER_JIFFY << JIFFIES_SHIFT,
|
||||
.shift = JIFFIES_SHIFT,
|
||||
};
|
||||
|
||||
@@ -71,3 +70,8 @@ static int __init init_jiffies_clocksource(void)
|
||||
}
|
||||
|
||||
core_initcall(init_jiffies_clocksource);
|
||||
|
||||
struct clocksource * __init __weak clocksource_default_clock(void)
|
||||
{
|
||||
return &clocksource_jiffies;
|
||||
}
|
||||
|
||||
+2
-5
@@ -194,8 +194,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
|
||||
case TIME_OK:
|
||||
break;
|
||||
case TIME_INS:
|
||||
xtime.tv_sec--;
|
||||
wall_to_monotonic.tv_sec++;
|
||||
timekeeping_leap_insert(-1);
|
||||
time_state = TIME_OOP;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: inserting leap second 23:59:60 UTC\n");
|
||||
@@ -203,9 +202,8 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
|
||||
res = HRTIMER_RESTART;
|
||||
break;
|
||||
case TIME_DEL:
|
||||
xtime.tv_sec++;
|
||||
timekeeping_leap_insert(1);
|
||||
time_tai--;
|
||||
wall_to_monotonic.tv_sec--;
|
||||
time_state = TIME_WAIT;
|
||||
printk(KERN_NOTICE
|
||||
"Clock: deleting leap second 23:59:59 UTC\n");
|
||||
@@ -219,7 +217,6 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
|
||||
time_state = TIME_OK;
|
||||
break;
|
||||
}
|
||||
update_vsyscall(&xtime, clock);
|
||||
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
|
||||
+408
-141
File diff suppressed because it is too large
Load Diff
+25
-3
@@ -72,6 +72,7 @@ struct tvec_base {
|
||||
spinlock_t lock;
|
||||
struct timer_list *running_timer;
|
||||
unsigned long timer_jiffies;
|
||||
unsigned long next_timer;
|
||||
struct tvec_root tv1;
|
||||
struct tvec tv2;
|
||||
struct tvec tv3;
|
||||
@@ -622,6 +623,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
|
||||
|
||||
if (timer_pending(timer)) {
|
||||
detach_timer(timer, 0);
|
||||
if (timer->expires == base->next_timer &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
base->next_timer = base->timer_jiffies;
|
||||
ret = 1;
|
||||
} else {
|
||||
if (pending_only)
|
||||
@@ -663,6 +667,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
|
||||
}
|
||||
|
||||
timer->expires = expires;
|
||||
if (time_before(timer->expires, base->next_timer) &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
base->next_timer = timer->expires;
|
||||
internal_add_timer(base, timer);
|
||||
|
||||
out_unlock:
|
||||
@@ -781,6 +788,9 @@ void add_timer_on(struct timer_list *timer, int cpu)
|
||||
spin_lock_irqsave(&base->lock, flags);
|
||||
timer_set_base(timer, base);
|
||||
debug_timer_activate(timer);
|
||||
if (time_before(timer->expires, base->next_timer) &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
base->next_timer = timer->expires;
|
||||
internal_add_timer(base, timer);
|
||||
/*
|
||||
* Check whether the other CPU is idle and needs to be
|
||||
@@ -817,6 +827,9 @@ int del_timer(struct timer_list *timer)
|
||||
base = lock_timer_base(timer, &flags);
|
||||
if (timer_pending(timer)) {
|
||||
detach_timer(timer, 1);
|
||||
if (timer->expires == base->next_timer &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
base->next_timer = base->timer_jiffies;
|
||||
ret = 1;
|
||||
}
|
||||
spin_unlock_irqrestore(&base->lock, flags);
|
||||
@@ -850,6 +863,9 @@ int try_to_del_timer_sync(struct timer_list *timer)
|
||||
ret = 0;
|
||||
if (timer_pending(timer)) {
|
||||
detach_timer(timer, 1);
|
||||
if (timer->expires == base->next_timer &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
base->next_timer = base->timer_jiffies;
|
||||
ret = 1;
|
||||
}
|
||||
out:
|
||||
@@ -1007,8 +1023,8 @@ static inline void __run_timers(struct tvec_base *base)
|
||||
#ifdef CONFIG_NO_HZ
|
||||
/*
|
||||
* Find out when the next timer event is due to happen. This
|
||||
* is used on S/390 to stop all activity when a cpus is idle.
|
||||
* This functions needs to be called disabled.
|
||||
* is used on S/390 to stop all activity when a CPU is idle.
|
||||
* This function needs to be called with interrupts disabled.
|
||||
*/
|
||||
static unsigned long __next_timer_interrupt(struct tvec_base *base)
|
||||
{
|
||||
@@ -1134,7 +1150,9 @@ unsigned long get_next_timer_interrupt(unsigned long now)
|
||||
unsigned long expires;
|
||||
|
||||
spin_lock(&base->lock);
|
||||
expires = __next_timer_interrupt(base);
|
||||
if (time_before_eq(base->next_timer, base->timer_jiffies))
|
||||
base->next_timer = __next_timer_interrupt(base);
|
||||
expires = base->next_timer;
|
||||
spin_unlock(&base->lock);
|
||||
|
||||
if (time_before_eq(expires, now))
|
||||
@@ -1522,6 +1540,7 @@ static int __cpuinit init_timers_cpu(int cpu)
|
||||
INIT_LIST_HEAD(base->tv1.vec + j);
|
||||
|
||||
base->timer_jiffies = jiffies;
|
||||
base->next_timer = base->timer_jiffies;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1534,6 +1553,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea
|
||||
timer = list_first_entry(head, struct timer_list, entry);
|
||||
detach_timer(timer, 0);
|
||||
timer_set_base(timer, new_base);
|
||||
if (time_before(timer->expires, new_base->next_timer) &&
|
||||
!tbase_get_deferrable(timer->base))
|
||||
new_base->next_timer = timer->expires;
|
||||
internal_add_timer(new_base, timer);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user