timers for 2.6.40
Subsystems (5)
Linus,
Please pull the latest timers-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git timers-for-linus
Thanks,
tglx
------------------>
Andi Kleen (1):
clockevents: Move C3 stop test outside lock
Thomas Gleixner (10):
hrtimers: Prepare for cancel on clock was set timers
timerfd: Allow timers to be cancelled when clock was set
alarmtimer: Check return value of class_find_device()
alarmtimer: Drop device refcount after rtc_open() clockevents/source: Use u64 to make 32bit happy
MAINTAINERS: Add drivers/clocksource to TIMEKEEPING
timerfd: Manage cancelable timers in timerfd
hrtimers: Make struct hrtimer_cpu_base layout less stupid
hrtimers: Avoid touching inactive timer bases
hrtimers: Reorder clock bases
MAINTAINERS | 1 + fs/timerfd.c | 102 ++++++++++++++++++++++++-- include/linux/hrtimer.h | 33 ++++----- include/linux/thread_info.h | 2 +- include/linux/timerfd.h | 3 +- kernel/hrtimer.c | 162 ++++++++++++++++++++++-------------------- kernel/posix-cpu-timers.c | 4 +- kernel/posix-timers.c | 2 +- kernel/time/alarmtimer.c | 16 +++- kernel/time/clockevents.c | 2 +- kernel/time/clocksource.c | 2 +- kernel/time/tick-broadcast.c | 16 +++-- kernel/time/timekeeping.c | 17 ++++- 13 files changed, 242 insertions(+), 120 deletions(-)
MAINTAINERS +1 -0
@@ -5431,6 +5431,7 @@ F: include/linux/timex.h F: kernel/time/clocksource.c F: kernel/time/time*.c F: kernel/time/ntp.c +F: drivers/clocksource TLG2300 VIDEO4LINUX-2 DRIVER M: Huang Shijie <[email protected]>
fs/timerfd.c +95 -7
187 lines not on this page · raw message
include/linux/hrtimer.h +16 -17
@@ -143,19 +143,18 @@ struct hrtimer_sleeper {*/ struct hrtimer_clock_base {struct hrtimer_cpu_base *cpu_base; -clockid_t index; +int index; +clockid_t clockid;struct timerqueue_head active;ktime_t resolution;ktime_t (*get_time)(void );ktime_t softirq_time; -#ifdef CONFIG_HIGH_RES_TIMERS ktime_t offset; -#endif };enum hrtimer_base_type { -HRTIMER_BASE_REALTIME ,HRTIMER_BASE_MONOTONIC , +HRTIMER_BASE_REALTIME ,HRTIMER_BASE_BOOTTIME ,HRTIMER_MAX_CLOCK_BASES , };
@@ -164,7 +163,7 @@ enum hrtimer_base_type {* struct hrtimer_cpu_base - the per cpu clock bases * @lock: lock protecting the base and associated clock bases * and timers -* @clock_base: array of clock bases for this cpu +* @active_bases: Bitfield to mark bases with active timers * @expires_next: absolute time of the next event which was scheduled * via clock_set_next_event() * @hres_active: State of high resolution mode
@@ -173,10 +172,11 @@ enum hrtimer_base_type {* @nr_retries: Total number of hrtimer interrupt retries * @nr_hangs: Total number of hrtimer interrupt hangs * @max_hang_time: Maximum time spent in hrtimer_interrupt +* @clock_base: array of clock bases for this cpu */ struct hrtimer_cpu_base {raw_spinlock_t lock; -struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES ]; +unsigned long active_bases;#ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next;int hres_active;
@@ -186,6 +186,7 @@ struct hrtimer_cpu_base {unsigned long nr_hangs;ktime_t max_hang_time;#endif +struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES ]; };static inline void hrtimer_set_expires (struct hrtimer *timer,ktime_t time)
@@ -256,8 +257,6 @@ static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)#ifdef CONFIG_HIGH_RES_TIMERS struct clock_event_device ; -extern void clock_was_set (void ); -extern void hres_timers_resume (void );extern void hrtimer_interrupt (struct clock_event_device *dev);/*
@@ -291,16 +290,8 @@ extern void hrtimer_peek_ahead_timers(void);# define MONOTONIC_RES_NSEC LOW_RES_NSEC# define KTIME_MONOTONIC_RES KTIME_LOW_RES -/* -* clock_was_set() is a NOP for non- high-resolution systems. The -* time-sorted order guarantees that a timer does not expire early and -* is expired in the next softirq when the clock was advanced. -*/ -static inline void clock_was_set (void ) { }static inline void hrtimer_peek_ahead_timers (void ) { } -static inline void hres_timers_resume (void ) { } -/* * In non high resolution mode the time reference is taken from * the base softirq time variable.
@@ -316,10 +307,18 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) }#endif +extern void clock_was_set (void ); +#ifdef CONFIG_TIMERFD +extern void timerfd_clock_was_set (void ); +#else +static inline void timerfd_clock_was_set (void ) { } +#endif +extern void hrtimers_resume (void ); +extern ktime_t ktime_get (void );extern ktime_t ktime_get_real (void );extern ktime_t ktime_get_boottime (void ); - +extern ktime_t ktime_get_monotonic_offset (void ); DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
include/linux/thread_info.h +1 -1
@@ -29,7 +29,7 @@ struct restart_block { } futex;/* For nanosleep */ struct { -clockid_t index; +clockid_t clockid;struct timespec __user *rmtp;#ifdef CONFIG_COMPAT struct compat_timespec __user *compat_rmtp;
include/linux/timerfd.h +2 -1
@@ -19,6 +19,7 @@* shared O_* flags. */ #define TFD_TIMER_ABSTIME (1 << 0) +#define TFD_TIMER_CANCEL_ON_SET (1 << 1)#define TFD_CLOEXEC O_CLOEXEC#define TFD_NONBLOCK O_NONBLOCK
@@ -26,6 +27,6 @@/* Flags for timerfd_create. */ #define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS/* Flags for timerfd_settime. */ -#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME +#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)#endif /* _LINUX_TIMERFD_H */
kernel/hrtimer.c +85 -77
256 lines not on this page · raw message
kernel/posix-cpu-timers.c +2 -2
@@ -1514,7 +1514,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,return -EFAULT ; restart_block->fn = posix_cpu_nsleep_restart; - restart_block->nanosleep.index = which_clock; + restart_block->nanosleep.clockid = which_clock; restart_block->nanosleep.rmtp = rmtp; restart_block->nanosleep.expires =timespec_to_ns (rqtp); }
@@ -1523,7 +1523,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,static long posix_cpu_nsleep_restart (struct restart_block *restart_block) { -clockid_t which_clock = restart_block->nanosleep.index; +clockid_t which_clock = restart_block->nanosleep.clockid;struct timespec t;struct itimerspec it;int error;
kernel/posix-timers.c +1 -1
@@ -1056,7 +1056,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,*/ long clock_nanosleep_restart (struct restart_block *restart_block) { -clockid_t which_clock = restart_block->nanosleep.index; +clockid_t which_clock = restart_block->nanosleep.clockid;struct k_clock *kc =clockid_to_kclock (which_clock);if (WARN_ON_ONCE (!kc || !kc->nsleep_restart))
kernel/time/alarmtimer.c +12 -4
@@ -494,7 +494,7 @@ static int update_rmtp(ktime_t exp, enum alarmtimer_type type,*/ static long __sched alarm_timer_nsleep_restart (struct restart_block *restart) { -enum alarmtimer_type type = restart->nanosleep.index; +enum alarmtimer_type type = restart->nanosleep.clockid;ktime_t exp;struct timespec __user *rmtp;struct alarm alarm;
@@ -573,7 +573,7 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, restart = ¤t_thread_info ()->restart_block; restart->fn = alarm_timer_nsleep_restart; - restart->nanosleep.index = type; + restart->nanosleep.clockid = type; restart->nanosleep.expires = exp.tv64; restart->nanosleep.rmtp = rmtp; ret = -ERESTART_RESTARTBLOCK ;
@@ -669,12 +669,20 @@ static int __init has_wakealarm(struct device *dev, void *name_ptr)*/ static int __init alarmtimer_init_late (void ) { +struct device *dev;char *str;/* Find an rtc device and init the rtc_timer */ -class_find_device (rtc_class,NULL , &str, has_wakealarm); -if (str) + dev =class_find_device (rtc_class,NULL , &str, has_wakealarm); +/* If we have a device then str is valid. See has_wakealarm() */ +if (dev) { rtcdev =rtc_class_open (str); +/* +* Drop the reference we got in class_find_device, +* rtc_open takes its own. +*/ +put_device (dev); + }if (!rtcdev) {printk (KERN_WARNING "No RTC device found, ALARM timers will" " not wake from suspend" );
kernel/time/clockevents.c +1 -1
@@ -197,7 +197,7 @@ EXPORT_SYMBOL_GPL(clockevents_register_device);static void clockevents_config (struct clock_event_device *dev,u32 freq) { -unsigned long sec; +u64 sec;if (!(dev->features &CLOCK_EVT_FEAT_ONESHOT ))return ;
kernel/time/clocksource.c +1 -1
@@ -639,7 +639,7 @@ static void clocksource_enqueue(struct clocksource *cs)*/ void __clocksource_updatefreq_scale (struct clocksource *cs,u32 scale,u32 freq) { -unsigned long sec; +u64 sec;/* * Calc the maximum number of seconds which we can run before
kernel/time/tick-broadcast.c +9 -7
@@ -456,23 +456,27 @@ void tick_broadcast_oneshot_control(unsigned long reason)unsigned long flags;int cpu; -raw_spin_lock_irqsave (&tick_broadcast_lock, flags); -/* * Periodic mode does not care about the enter/exit of power * states */ if (tick_broadcast_device.mode ==TICKDEV_MODE_PERIODIC ) - goto out; +return ; - bc = tick_broadcast_device.evtdev; +/* +* We are called with preemtion disabled from the depth of the +* idle code, so we can't be moved away. +*/ cpu =smp_processor_id (); td = &per_cpu (tick_cpu_device, cpu); dev = td->evtdev;if (!(dev->features &CLOCK_EVT_FEAT_C3STOP )) - goto out; +return ; + + bc = tick_broadcast_device.evtdev; +raw_spin_lock_irqsave (&tick_broadcast_lock, flags);if (reason ==CLOCK_EVT_NOTIFY_BROADCAST_ENTER ) {if (!cpumask_test_cpu (cpu,tick_get_broadcast_oneshot_mask ())) {cpumask_set_cpu (cpu,tick_get_broadcast_oneshot_mask ());
@@ -489,8 +493,6 @@ void tick_broadcast_oneshot_control(unsigned long reason)tick_program_event (dev->next_event,1 ); } } - -out:raw_spin_unlock_irqrestore (&tick_broadcast_lock, flags); }
kernel/time/timekeeping.c +16 -1
@@ -680,7 +680,7 @@ static void timekeeping_resume(void)clockevents_notify (CLOCK_EVT_NOTIFY_RESUME ,NULL );/* Resume hrtimers */ -hres_timers_resume (); +hrtimers_resume (); }static int timekeeping_suspend (void )
@@ -1099,6 +1099,21 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, }/** +* ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format +*/ +ktime_t ktime_get_monotonic_offset (void ) +{ +unsigned long seq; +struct timespec wtom; + +do { + seq =read_seqbegin (&xtime_lock); + wtom = wall_to_monotonic; + }while (read_seqretry (&xtime_lock, seq)); +return timespec_to_ktime (wtom); +} + +/** * xtime_update() - advances the timekeeping infrastructure * @ticks: number of ticks, that have elapsed since the last call. *