From 9d6346311418d12e90cca9384e5fbbe2ffa18efb Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 28 Feb 2007 20:12:07 -0800 Subject: [PATCH] update timekeeping_is_continuous comment Signed-off-by: Daniel Walker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index cb1b86a9c52..d033313bf53 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -908,7 +908,7 @@ static inline void change_clocksource(void) { } #endif /** - * timeofday_is_continuous - check to see if timekeeping is free running + * timekeeping_is_continuous - check to see if timekeeping is free running */ int timekeeping_is_continuous(void) { -- cgit From 05fb6bf0b29552b64dc86f405a484de2514e0ac2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 28 Feb 2007 20:12:13 -0800 Subject: [PATCH] kernel-doc fixes for 2.6.20-git15 (non-drivers) Fix kernel-doc warnings in 2.6.20-git15 (lib/, mm/, kernel/, include/). Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index d033313bf53..6663a87f730 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -711,6 +711,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now, /** * next_timer_interrupt - return the jiffy of the next pending timer + * @now: current time (in jiffies) */ unsigned long get_next_timer_interrupt(unsigned long now) { -- cgit From e81ce1f7ecdaed2844c75313b09af791d44e6373 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 5 Mar 2007 00:30:51 -0800 Subject: [PATCH] timer/hrtimer: take per cpu locks in sane order Doing something like this on a two cpu system # echo 0 > /sys/devices/system/cpu/cpu0/online # echo 1 > /sys/devices/system/cpu/cpu0/online # echo 0 > /sys/devices/system/cpu/cpu1/online will give me this: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.21-rc2-g562aa1d4-dirty #7 ------------------------------------------------------- bash/1282 is trying to acquire lock: (&cpu_base->lock_key){.+..}, at: [<000000000005f17e>] hrtimer_cpu_notify+0xc6/0x240 but task is already holding lock: (&cpu_base->lock_key#2){.+..}, at: [<000000000005f174>] hrtimer_cpu_notify+0xbc/0x240 which lock already depends on the new lock. This happens because we have the following code in kernel/hrtimer.c: migrate_hrtimers(int cpu) [...] old_base = &per_cpu(hrtimer_bases, cpu); new_base = &get_cpu_var(hrtimer_bases); [...] spin_lock(&new_base->lock); spin_lock(&old_base->lock); Which means the spinlocks are taken in an order which depends on which cpu gets shut down from which other cpu. Therefore lockdep complains that there might be an ABBA deadlock. Since migrate_hrtimers() gets only called on cpu hotplug it's safe to assume that it isn't executed concurrently on a The same problem exists in kernel/timer.c: migrate_timers(). As pointed out by Christian Borntraeger one possible solution to avoid the locking order complaints would be to make sure that the locks are always taken in the same order. E.g. by taking the lock of the cpu with the lower number first. To achieve this we introduce two new spinlock functions double_spin_lock and double_spin_unlock which lock or unlock two locks in a given order. Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Roman Zippel Cc: John Stultz Cc: Christian Borntraeger Cc: Martin Schwidefsky Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index 6663a87f730..8ad384253ef 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1651,8 +1651,8 @@ static void __devinit migrate_timers(int cpu) new_base = get_cpu_var(tvec_bases); local_irq_disable(); - spin_lock(&new_base->lock); - spin_lock(&old_base->lock); + double_spin_lock(&new_base->lock, &old_base->lock, + smp_processor_id() < cpu); BUG_ON(old_base->running_timer); @@ -1665,8 +1665,8 @@ static void __devinit migrate_timers(int cpu) migrate_timer_list(new_base, old_base->tv5.vec + i); } - spin_unlock(&old_base->lock); - spin_unlock(&new_base->lock); + double_spin_unlock(&new_base->lock, &old_base->lock, + smp_processor_id() < cpu); local_irq_enable(); put_cpu_var(tvec_bases); } -- cgit From 6321dd60c76b2e12383bc06046288b15397ed3a0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 6 Mar 2007 08:25:42 +0100 Subject: [PATCH] Save/restore periodic tick information over suspend/resume The programming of periodic tick devices needs to be saved/restored across suspend/resume - otherwise we might end up with a system coming up that relies on getting a PIT (or HPET) interrupt, while those devices default to 'no interrupts' after powerup. (To confuse things it worked to a certain degree on some systems because the lapic gets initialized as a side-effect of SMP bootup.) This suspend / resume thing was dropped unintentionally during the last-minute -mm code reshuffling. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/timer.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index 8ad384253ef..ee0a2da4aab 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -997,6 +997,9 @@ static int timekeeping_resume(struct sys_device *dev) write_sequnlock_irqrestore(&xtime_lock, flags); touch_softlockup_watchdog(); + + clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); + /* Resume hrtimers */ clock_was_set(); @@ -1011,6 +1014,9 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state) timekeeping_suspended = 1; timekeeping_suspend_time = read_persistent_clock(); write_sequnlock_irqrestore(&xtime_lock, flags); + + clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); + return 0; } -- cgit From 90675a27fa3eb0e97f1d040b183cceb44316e669 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 6 Mar 2007 01:42:11 -0800 Subject: [PATCH] fix vsyscall settimeofday I've only seen this on x86_64. The vsyscall state only gets updated when a timer interrupts comes in. So if the time is set long before the next timer, there will be a period when a gettimeofday() won't reflect the correct time. I added an explicit update_vsyscall() during the settimeofday(), that way the vsyscall state doesn't get stale. Signed-off-by: Daniel Walker Cc: Thomas Gleixner Acked-by: Ingo Molnar Acked-by: John Stultz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index ee0a2da4aab..797cccb8643 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -862,6 +862,8 @@ int do_settimeofday(struct timespec *tv) clock->error = 0; ntp_clear(); + update_vsyscall(&xtime, clock); + write_sequnlock_irqrestore(&xtime_lock, flags); /* signal hrtimers about time change */ -- cgit From 9501b6cf5541f0d576d566a463f1e7d3eaaab4eb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 25 Mar 2007 14:31:17 +0200 Subject: [PATCH] dynticks: fix hrtimer rounding error in next_timer_interrupt The rework of next_timer_interrupt() fixed the timer wheel bugs, but invented a rounding error versus the next hrtimer event. This is caused by the conversion of the hrtimer internal representation to relative jiffies. This causes bug #8100: http://bugzilla.kernel.org/show_bug.cgi?id=8100 next_timer_interrupt() returns "now" in such a case and causes the code in tick_nohz_stop_sched_tick() to trigger the timer softirq, which is bogus as no timer is due for expiry. This results in an endless context switching between idle and ksoftirqd until a timer is due for expiry. Modify the hrtimer evaluation so that, it returns now + 1, when the conversion results in a delta < 1 jiffie. It's confirmed to resolve bug #8100 Reported-by: Emil Karlson Signed-off-by: Thomas Gleixner Signed-off-by: Linus Torvalds --- kernel/timer.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index 797cccb8643..440048acaea 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -695,15 +695,28 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now, { ktime_t hr_delta = hrtimer_get_next_event(); struct timespec tsdelta; + unsigned long delta; if (hr_delta.tv64 == KTIME_MAX) return expires; - if (hr_delta.tv64 <= TICK_NSEC) - return now; + /* + * Expired timer available, let it expire in the next tick + */ + if (hr_delta.tv64 <= 0) + return now + 1; tsdelta = ktime_to_timespec(hr_delta); - now += timespec_to_jiffies(&tsdelta); + delta = timespec_to_jiffies(&tsdelta); + /* + * Take rounding errors in to account and make sure, that it + * expires in the next tick. Otherwise we go into an endless + * ping pong due to tick_nohz_stop_sched_tick() retriggering + * the timer softirq + */ + if (delta < 1) + delta = 1; + now += delta; if (time_before(now, expires)) return now; return expires; -- cgit From 995f054f2a342f8505fed4f8395d12c0f5966414 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 7 Apr 2007 12:05:00 +0200 Subject: [PATCH] high-res timers: resume fix Soeren Sonnenburg reported that upon resume he is getting this backtrace: [] smp_apic_timer_interrupt+0x57/0x90 [] retrigger_next_event+0x0/0xb0 [] apic_timer_interrupt+0x28/0x30 [] retrigger_next_event+0x0/0xb0 [] __kfifo_put+0x8/0x90 [] on_each_cpu+0x35/0x60 [] clock_was_set+0x18/0x20 [] timekeeping_resume+0x7c/0xa0 [] __sysdev_resume+0x11/0x80 [] sysdev_resume+0x47/0x80 [] device_power_up+0x5/0x10 it turns out that on resume we mistakenly re-enable interrupts too early. Do the timer retrigger only on the current CPU. Signed-off-by: Ingo Molnar Acked-by: Thomas Gleixner Acked-by: Soeren Sonnenburg Signed-off-by: Linus Torvalds --- kernel/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index 440048acaea..dd6c2c1c561 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1016,7 +1016,7 @@ static int timekeeping_resume(struct sys_device *dev) clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); /* Resume hrtimers */ - clock_was_set(); + hres_timers_resume(); return 0; } -- cgit From e19dff1fdd99a25819af74cf0710e147fff4fd3a Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 26 Apr 2007 15:46:56 -0700 Subject: [AF_RXRPC]: Make it possible to merely try to cancel timers from a module Export try_to_del_timer_sync() for use by the AF_RXRPC module. Signed-off-by: David Howells Signed-off-by: David S. Miller --- kernel/timer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kernel/timer.c') diff --git a/kernel/timer.c b/kernel/timer.c index dd6c2c1c561..b22bd39740d 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -505,6 +505,8 @@ out: return ret; } +EXPORT_SYMBOL(try_to_del_timer_sync); + /** * del_timer_sync - deactivate a timer and wait for the handler to finish. * @timer: the timer to be deactivated -- cgit