Re: [GIT PULL] timer fix
The pull request you sent on Sun, 28 Jun 2020 20:39:25 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-2020-06-28 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/668f532da4808688f5162cec6a38875390e1a91d Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] timer fix
Linus, Please pull the latest timers/urgent git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-2020-06-28 # HEAD: f097eb38f71391ff2cf078788bad5a00eb3bd96a timekeeping: Fix kerneldoc system_device_crosststamp & al A single DocBook fix. Thanks, Ingo --> Kurt Kanzenbach (1): timekeeping: Fix kerneldoc system_device_crosststamp & al include/linux/timekeeping.h | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index b27e2ffa96c1..d5471d6fa778 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -222,9 +222,9 @@ extern bool timekeeping_rtc_skipresume(void); extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta); -/* +/** * struct system_time_snapshot - simultaneous raw/real time capture with - * counter value + * counter value * @cycles:Clocksource counter value to produce the system times * @real: Realtime system time * @raw: Monotonic raw system time @@ -239,9 +239,9 @@ struct system_time_snapshot { u8 cs_was_changed_seq; }; -/* +/** * struct system_device_crosststamp - system/device cross-timestamp - * (syncronized capture) + * (synchronized capture) * @device:Device time * @sys_realtime: Realtime simultaneous with device time * @sys_monoraw: Monotonic raw simultaneous with device time @@ -252,12 +252,12 @@ struct system_device_crosststamp { ktime_t sys_monoraw; }; -/* +/** * struct system_counterval_t - system counter value with the pointer to the - * corresponding clocksource + * corresponding clocksource * @cycles:System counter value * @cs:Clocksource corresponding to system counter value. Used by - * timekeeping code to verify comparibility of two cycle values + * timekeeping code to verify comparibility of two cycle values */ struct system_counterval_t { u64 cycles;
Re: [GIT PULL] timer fix
The pull request you sent on Thu, 3 Oct 2019 00:06:07 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/5021b9182ee805603e3b180220a929af7bd4b960 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: b9023b91dd020ad7e093baa5122b6968c48cc9e0 tick: broadcast-hrtimer: Fix a race in bc_set_next Fix a broadcast-timer handling race that can result in spuriously and indefinitely delayed hrtimers and even RCU stalls if the system is otherwise quiet. Thanks, Ingo --> Balasubramani Vivekanandan (1): tick: broadcast-hrtimer: Fix a race in bc_set_next kernel/time/tick-broadcast-hrtimer.c | 62 +--- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c index c1f5bb590b5e..b5a65e212df2 100644 --- a/kernel/time/tick-broadcast-hrtimer.c +++ b/kernel/time/tick-broadcast-hrtimer.c @@ -42,39 +42,39 @@ static int bc_shutdown(struct clock_event_device *evt) */ static int bc_set_next(ktime_t expires, struct clock_event_device *bc) { - int bc_moved; /* -* We try to cancel the timer first. If the callback is on -* flight on some other cpu then we let it handle it. If we -* were able to cancel the timer nothing can rearm it as we -* own broadcast_lock. +* This is called either from enter/exit idle code or from the +* broadcast handler. In all cases tick_broadcast_lock is held. * -* However we can also be called from the event handler of -* ce_broadcast_hrtimer itself when it expires. We cannot -* restart the timer because we are in the callback, but we -* can set the expiry time and let the callback return -* HRTIMER_RESTART. +* hrtimer_cancel() cannot be called here neither from the +* broadcast handler nor from the enter/exit idle code. The idle +* code can run into the problem described in bc_shutdown() and the +* broadcast handler cannot wait for itself to complete for obvious +* reasons. * -* Since we are in the idle loop at this point and because -* hrtimer_{start/cancel} functions call into tracing, -* calls to these functions must be bound within RCU_NONIDLE. +* Each caller tries to arm the hrtimer on its own CPU, but if the +* hrtimer callbback function is currently running, then +* hrtimer_start() cannot move it and the timer stays on the CPU on +* which it is assigned at the moment. +* +* As this can be called from idle code, the hrtimer_start() +* invocation has to be wrapped with RCU_NONIDLE() as +* hrtimer_start() can call into tracing. */ - RCU_NONIDLE( - { - bc_moved = hrtimer_try_to_cancel() >= 0; - if (bc_moved) { - hrtimer_start(, expires, - HRTIMER_MODE_ABS_PINNED_HARD); - } - } - ); - - if (bc_moved) { - /* Bind the "device" to the cpu */ - bc->bound_on = smp_processor_id(); - } else if (bc->bound_on == smp_processor_id()) { - hrtimer_set_expires(, expires); - } + RCU_NONIDLE( { + hrtimer_start(, expires, HRTIMER_MODE_ABS_PINNED_HARD); + /* +* The core tick broadcast mode expects bc->bound_on to be set +* correctly to prevent a CPU which has the broadcast hrtimer +* armed from going deep idle. +* +* As tick_broadcast_lock is held, nothing can change the cpu +* base which was just established in hrtimer_start() above. So +* the below access is safe even without holding the hrtimer +* base lock. +*/ + bc->bound_on = bctimer.base->cpu_base->cpu; + } ); return 0; } @@ -100,10 +100,6 @@ static enum hrtimer_restart bc_handler(struct hrtimer *t) { ce_broadcast_hrtimer.event_handler(_broadcast_hrtimer); - if (clockevent_state_oneshot(_broadcast_hrtimer)) - if (ce_broadcast_hrtimer.next_event != KTIME_MAX) - return HRTIMER_RESTART; - return HRTIMER_NORESTART; }
Re: [GIT PULL] timer fix
The pull request you sent on Thu, 26 Sep 2019 22:18:25 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/da05b5ea12c1e50b2988a63470d6b69434796f8b Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: e430d802d6a3aaf61bd3ed03d9404888a29b9bf9 timer: Read jiffies once when forwarding base clk Fixes a timer expiry bug that would cause spurious delay of timers. Thanks, Ingo --> Li RongQing (1): timer: Read jiffies once when forwarding base clk kernel/time/timer.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 0e315a2e77ae..4820823515e9 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1678,24 +1678,26 @@ void timer_clear_idle(void) static int collect_expired_timers(struct timer_base *base, struct hlist_head *heads) { + unsigned long now = READ_ONCE(jiffies); + /* * NOHZ optimization. After a long idle sleep we need to forward the * base to current jiffies. Avoid a loop by searching the bitfield for * the next expiring timer. */ - if ((long)(jiffies - base->clk) > 2) { + if ((long)(now - base->clk) > 2) { unsigned long next = __next_timer_interrupt(base); /* * If the next timer is ahead of time forward to current * jiffies, otherwise forward to the next expiry time: */ - if (time_after(next, jiffies)) { + if (time_after(next, now)) { /* * The call site will increment base->clk and then * terminate the expiry loop immediately. */ - base->clk = jiffies; + base->clk = now; return 0; } base->clk = next;
Re: [GIT PULL] timer fix
The pull request you sent on Fri, 12 Apr 2019 15:09:19 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/122c215bfae884f10a189e6754d9603a06b981c3 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 07d7e12091f4ab869cc6a4bb276399057e73b0b3 alarmtimer: Return correct remaining time Fix the alarm_timer_remaining() return value. Thanks, Ingo --> Andrei Vagin (1): alarmtimer: Return correct remaining time kernel/time/alarmtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 2c97e8c2d29f..0519a8805aab 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -594,7 +594,7 @@ static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now) { struct alarm *alarm = >it.alarm.alarmtimer; - return ktime_sub(now, alarm->node.expires); + return ktime_sub(alarm->node.expires, now); } /**
Re: [GIT pull] timer fix for 5.1
The pull request you sent on Sun, 10 Mar 2019 12:33:51 +0100: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/a15f6b923e1e1040edc79f222d5d229ea8097259 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT pull] timer fix for 5.1
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix to prevent a unmet dependencies warning in Kconfig. Thanks, tglx --> Arnd Bergmann (1): time: Make VIRT_CPU_ACCOUNTING_GEN depend on GENERIC_CLOCKEVENTS init/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig b/init/Kconfig index c9386a365eea..acbde4ef2395 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -382,6 +382,7 @@ config VIRT_CPU_ACCOUNTING_GEN bool "Full dynticks CPU time accounting" depends on HAVE_CONTEXT_TRACKING depends on HAVE_VIRT_CPU_ACCOUNTING_GEN + depends on GENERIC_CLOCKEVENTS select VIRT_CPU_ACCOUNTING select CONTEXT_TRACKING help
Re: [GIT PULL] timer fix
On Thu, 17 Jan 2019, Heiko Carstens wrote: > On Thu, Jan 17, 2019 at 10:51:02AM +0100, Ingo Molnar wrote: > > > > * Heiko Carstens wrote: > > > > > > - if (timr->it_requeue_pending == info->si_sys_private) { > > > > + if (timr->it_interval && timr->it_requeue_pending == > > > > info->si_sys_private) { > > > > timr->kclock->timer_rearm(timr); > > > > > > FWIW, with this patch the vanilla glibc 2.28 self tests > > > rt/tst-cputimer1, rt/tst-cputimer2, and rt/tst-cputimer3 > > > start to fail on s390: > ... > > > I haven't looked any further into this, just reporting.. otherwise the > > > test systems seem to be healthy. > > > > Could you please check whether the top commit in tip:timers/urgent fixes > > it: > > 93ad0fc088c5: posix-cpu-timers: Unbreak timer rearming > > Yes, the test cases don't fail anymore. Thanks! > > A general question: since I reported this already last year, was the > bug report not usable? I understand that x-mas holidays were in > between, just wondering if new "glibc test case" fails are worth to be > reported like I did. I was on a 3 weeks vacation and I tend to clean out my inbox when I return as it turned out in the past that playing catch up is hopeless. The important stuff comes back by itself :) Thanks, tglx
Re: [GIT PULL] timer fix
On Thu, Jan 17, 2019 at 10:51:02AM +0100, Ingo Molnar wrote: > > * Heiko Carstens wrote: > > > > - if (timr->it_requeue_pending == info->si_sys_private) { > > > + if (timr->it_interval && timr->it_requeue_pending == > > > info->si_sys_private) { > > > timr->kclock->timer_rearm(timr); > > > > FWIW, with this patch the vanilla glibc 2.28 self tests > > rt/tst-cputimer1, rt/tst-cputimer2, and rt/tst-cputimer3 > > start to fail on s390: ... > > I haven't looked any further into this, just reporting.. otherwise the > > test systems seem to be healthy. > > Could you please check whether the top commit in tip:timers/urgent fixes > it: > 93ad0fc088c5: posix-cpu-timers: Unbreak timer rearming Yes, the test cases don't fail anymore. Thanks! A general question: since I reported this already last year, was the bug report not usable? I understand that x-mas holidays were in between, just wondering if new "glibc test case" fails are worth to be reported like I did.
Re: [GIT PULL] timer fix
* Heiko Carstens wrote: > > - if (timr->it_requeue_pending == info->si_sys_private) { > > + if (timr->it_interval && timr->it_requeue_pending == > > info->si_sys_private) { > > timr->kclock->timer_rearm(timr); > > FWIW, with this patch the vanilla glibc 2.28 self tests > rt/tst-cputimer1, rt/tst-cputimer2, and rt/tst-cputimer3 > start to fail on s390: > > rt/tst-cputimer1.out: > clock_gettime returned timespec = { 0, 117181 } > clock_getres returned timespec = { 0, 1 } > Timed out: killed the child process > rt/tst-cputimer1.test-result: > FAIL: rt/tst-cputimer1 > original exit status 1 > > rt/tst-cputimer2.out: > clock_gettime returned timespec = { 0, 9686 } > clock_getres returned timespec = { 0, 1 } > Timed out: killed the child process > rt/tst-cputimer2.test-result: > FAIL: rt/tst-cputimer2 > original exit status 1 > > rt/tst-cputimer3.out: > clock_gettime returned timespec = { 0, 0 } > clock_getres returned timespec = { 0, 1 } > Timed out: killed the child process > rt/tst-cputimer3.test-result: > FAIL: rt/tst-cputimer3 > original exit status 1 > > I haven't looked any further into this, just reporting.. otherwise the > test systems seem to be healthy. Could you please check whether the top commit in tip:timers/urgent fixes it: 93ad0fc088c5: posix-cpu-timers: Unbreak timer rearming ? It's in tip:master as well and should show up in linux-next tomorrow. Thanks, Ingo
Re: [GIT PULL] timer fix
On Fri, Dec 21, 2018 at 01:34:53PM +0100, Ingo Molnar wrote: > Linus, > > Please pull the latest timers-urgent-for-linus git tree from: > >git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus > ># HEAD: 0e334db6bb4b1fd1e2d72c1f3d8f004313cd9f94 posix-timers: Fix > division by zero bug > > Fix a division by zero crash in the posix-timers code. > > Thanks, > > Ingo > > --> > Thomas Gleixner (1): > posix-timers: Fix division by zero bug > > > kernel/time/posix-timers.c | 5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c > index bd62b5eeb5a0..31f49ae80f43 100644 > --- a/kernel/time/posix-timers.c > +++ b/kernel/time/posix-timers.c > @@ -289,9 +289,6 @@ static void common_hrtimer_rearm(struct k_itimer *timr) > { > struct hrtimer *timer = >it.real.timer; > > - if (!timr->it_interval) > - return; > - > timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(), > timr->it_interval); > hrtimer_restart(timer); > @@ -317,7 +314,7 @@ void posixtimer_rearm(struct kernel_siginfo *info) > if (!timr) > return; > > - if (timr->it_requeue_pending == info->si_sys_private) { > + if (timr->it_interval && timr->it_requeue_pending == > info->si_sys_private) { > timr->kclock->timer_rearm(timr); FWIW, with this patch the vanilla glibc 2.28 self tests rt/tst-cputimer1, rt/tst-cputimer2, and rt/tst-cputimer3 start to fail on s390: rt/tst-cputimer1.out: clock_gettime returned timespec = { 0, 117181 } clock_getres returned timespec = { 0, 1 } Timed out: killed the child process rt/tst-cputimer1.test-result: FAIL: rt/tst-cputimer1 original exit status 1 rt/tst-cputimer2.out: clock_gettime returned timespec = { 0, 9686 } clock_getres returned timespec = { 0, 1 } Timed out: killed the child process rt/tst-cputimer2.test-result: FAIL: rt/tst-cputimer2 original exit status 1 rt/tst-cputimer3.out: clock_gettime returned timespec = { 0, 0 } clock_getres returned timespec = { 0, 1 } Timed out: killed the child process rt/tst-cputimer3.test-result: FAIL: rt/tst-cputimer3 original exit status 1 I haven't looked any further into this, just reporting.. otherwise the test systems seem to be healthy.
Re: [GIT PULL] timer fix
The pull request you sent on Fri, 21 Dec 2018 13:34:53 +0100: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > timers-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/e572fa0e840154d33a69622af030dda551eee606 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 0e334db6bb4b1fd1e2d72c1f3d8f004313cd9f94 posix-timers: Fix division by zero bug Fix a division by zero crash in the posix-timers code. Thanks, Ingo --> Thomas Gleixner (1): posix-timers: Fix division by zero bug kernel/time/posix-timers.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bd62b5eeb5a0..31f49ae80f43 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -289,9 +289,6 @@ static void common_hrtimer_rearm(struct k_itimer *timr) { struct hrtimer *timer = >it.real.timer; - if (!timr->it_interval) - return; - timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(), timr->it_interval); hrtimer_restart(timer); @@ -317,7 +314,7 @@ void posixtimer_rearm(struct kernel_siginfo *info) if (!timr) return; - if (timr->it_requeue_pending == info->si_sys_private) { + if (timr->it_interval && timr->it_requeue_pending == info->si_sys_private) { timr->kclock->timer_rearm(timr); timr->it_active = 1;
[GIT pull] timer fix for 4.17
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Address the for_each_cpu() oddity on UP kernels in the tick broadcast code which causes boot failures because the CPU0 bit is always reported as set independent of the cpumask content. Thanks, tglx --> Dexuan Cui (1): tick/broadcast: Use for_each_cpu() specially on UP kernels kernel/time/tick-broadcast.c | 8 1 file changed, 8 insertions(+) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index b398c2ea69b2..aa2094d5dd27 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -612,6 +612,14 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) now = ktime_get(); /* Find all expired events */ for_each_cpu(cpu, tick_broadcast_oneshot_mask) { + /* +* Required for !SMP because for_each_cpu() reports +* unconditionally CPU0 as set on UP kernels. +*/ + if (!IS_ENABLED(CONFIG_SMP) && + cpumask_empty(tick_broadcast_oneshot_mask)) + break; + td = _cpu(tick_cpu_device, cpu); if (td->evtdev->next_event <= now) { cpumask_set_cpu(cpu, tmpmask);
[GIT pull] timer fix for 4.17
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Address the for_each_cpu() oddity on UP kernels in the tick broadcast code which causes boot failures because the CPU0 bit is always reported as set independent of the cpumask content. Thanks, tglx --> Dexuan Cui (1): tick/broadcast: Use for_each_cpu() specially on UP kernels kernel/time/tick-broadcast.c | 8 1 file changed, 8 insertions(+) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index b398c2ea69b2..aa2094d5dd27 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -612,6 +612,14 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) now = ktime_get(); /* Find all expired events */ for_each_cpu(cpu, tick_broadcast_oneshot_mask) { + /* +* Required for !SMP because for_each_cpu() reports +* unconditionally CPU0 as set on UP kernels. +*/ + if (!IS_ENABLED(CONFIG_SMP) && + cpumask_empty(tick_broadcast_oneshot_mask)) + break; + td = _cpu(tick_cpu_device, cpu); if (td->evtdev->next_event <= now) { cpumask_set_cpu(cpu, tmpmask);
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 19b558db12f9f4e45a22012bae7b4783e62224da posix-timers: Protect posix clock array access against speculation Make posix clock ID usage Spectre-safe. Thanks, Ingo --> Thomas Gleixner (1): posix-timers: Protect posix clock array access against speculation kernel/time/posix-timers.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 75043046914e..10b7186d0638 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "timekeeping.h" #include "posix-timers.h" @@ -1346,11 +1347,15 @@ static const struct k_clock * const posix_clocks[] = { static const struct k_clock *clockid_to_kclock(const clockid_t id) { - if (id < 0) + clockid_t idx = id; + + if (id < 0) { return (id & CLOCKFD_MASK) == CLOCKFD ? _posix_dynamic : _posix_cpu; + } - if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id]) + if (id >= ARRAY_SIZE(posix_clocks)) return NULL; - return posix_clocks[id]; + + return posix_clocks[array_index_nospec(idx, ARRAY_SIZE(posix_clocks))]; }
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 19b558db12f9f4e45a22012bae7b4783e62224da posix-timers: Protect posix clock array access against speculation Make posix clock ID usage Spectre-safe. Thanks, Ingo --> Thomas Gleixner (1): posix-timers: Protect posix clock array access against speculation kernel/time/posix-timers.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 75043046914e..10b7186d0638 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "timekeeping.h" #include "posix-timers.h" @@ -1346,11 +1347,15 @@ static const struct k_clock * const posix_clocks[] = { static const struct k_clock *clockid_to_kclock(const clockid_t id) { - if (id < 0) + clockid_t idx = id; + + if (id < 0) { return (id & CLOCKFD_MASK) == CLOCKFD ? _posix_dynamic : _posix_cpu; + } - if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id]) + if (id >= ARRAY_SIZE(posix_clocks)) return NULL; - return posix_clocks[id]; + + return posix_clocks[array_index_nospec(idx, ARRAY_SIZE(posix_clocks))]; }
[GIT pull] timer fix for 4.16
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Just a single fix which adds a missing Kconfig dependency to avoid unmet dependency warnings. Thanks, tglx --> Masahiro Yamada (1): clocksource/atmel-st: Add 'depends on HAS_IOMEM' to fix unmet dependency drivers/clocksource/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b3b4ed9b6874..d2e5382821a4 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -386,6 +386,7 @@ config ATMEL_PIT config ATMEL_ST bool "Atmel ST timer support" if COMPILE_TEST + depends on HAS_IOMEM select TIMER_OF select MFD_SYSCON help
[GIT pull] timer fix for 4.16
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Just a single fix which adds a missing Kconfig dependency to avoid unmet dependency warnings. Thanks, tglx --> Masahiro Yamada (1): clocksource/atmel-st: Add 'depends on HAS_IOMEM' to fix unmet dependency drivers/clocksource/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b3b4ed9b6874..d2e5382821a4 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -386,6 +386,7 @@ config ATMEL_PIT config ATMEL_ST bool "Atmel ST timer support" if COMPILE_TEST + depends on HAS_IOMEM select TIMER_OF select MFD_SYSCON help
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a ~10 years old problem which causes high resolution timers to stop after a CPU unplug/plug cycle due to a stale flag in the per CPU hrtimer base struct. Paul McKenney was hunting this for about a year, but the heisenbug nature made it resistant against debug attempts for quite some time. Thanks, tglx --> Thomas Gleixner (1): hrtimer: Reset hrtimer cpu base proper on CPU hotplug kernel/time/hrtimer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index d32520840fde..aa9d2a2b1210 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -655,7 +655,9 @@ static void hrtimer_reprogram(struct hrtimer *timer, static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { base->expires_next = KTIME_MAX; + base->hang_detected = 0; base->hres_active = 0; + base->next_timer = NULL; } /* @@ -1589,6 +1591,7 @@ int hrtimers_prepare_cpu(unsigned int cpu) timerqueue_init_head(_base->clock_base[i].active); } + cpu_base->active_bases = 0; cpu_base->cpu = cpu; hrtimer_init_hres(cpu_base); return 0;
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a ~10 years old problem which causes high resolution timers to stop after a CPU unplug/plug cycle due to a stale flag in the per CPU hrtimer base struct. Paul McKenney was hunting this for about a year, but the heisenbug nature made it resistant against debug attempts for quite some time. Thanks, tglx --> Thomas Gleixner (1): hrtimer: Reset hrtimer cpu base proper on CPU hotplug kernel/time/hrtimer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index d32520840fde..aa9d2a2b1210 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -655,7 +655,9 @@ static void hrtimer_reprogram(struct hrtimer *timer, static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { base->expires_next = KTIME_MAX; + base->hang_detected = 0; base->hres_active = 0; + base->next_timer = NULL; } /* @@ -1589,6 +1591,7 @@ int hrtimers_prepare_cpu(unsigned int cpu) timerqueue_init_head(_base->clock_base[i].active); } + cpu_base->active_bases = 0; cpu_base->cpu = cpu; hrtimer_init_hres(cpu_base); return 0;
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A one-liner fix which prevents deferrable timers becoming stale when the system does not switch into NOHZ mode. Thanks, tglx --> Thomas Gleixner (1): timers: Unconditionally check deferrable base kernel/time/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 89a9e1b4264a..0bcf00e3ce48 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1696,7 +1696,7 @@ void run_local_timers(void) hrtimer_run_queues(); /* Raise the softirq only if required. */ if (time_before(jiffies, base->clk)) { - if (!IS_ENABLED(CONFIG_NO_HZ_COMMON) || !base->nohz_active) + if (!IS_ENABLED(CONFIG_NO_HZ_COMMON)) return; /* CPU is awake, so check the deferrable base. */ base++;
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A one-liner fix which prevents deferrable timers becoming stale when the system does not switch into NOHZ mode. Thanks, tglx --> Thomas Gleixner (1): timers: Unconditionally check deferrable base kernel/time/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 89a9e1b4264a..0bcf00e3ce48 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1696,7 +1696,7 @@ void run_local_timers(void) hrtimer_run_queues(); /* Raise the softirq only if required. */ if (time_before(jiffies, base->clk)) { - if (!IS_ENABLED(CONFIG_NO_HZ_COMMON) || !base->nohz_active) + if (!IS_ENABLED(CONFIG_NO_HZ_COMMON)) return; /* CPU is awake, so check the deferrable base. */ base++;
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix which prevents arbitrary sigev_notify values in posix-timers. Thanks, tglx --> Thomas Gleixner (1): posix-timer: Properly check sigevent->sigev_notify kernel/time/posix-timers.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 13d6881f908b..ec999f32c840 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -434,17 +434,22 @@ static struct pid *good_sigevent(sigevent_t * event) { struct task_struct *rtn = current->group_leader; - if ((event->sigev_notify & SIGEV_THREAD_ID ) && - (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || -!same_thread_group(rtn, current) || -(event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) + switch (event->sigev_notify) { + case SIGEV_SIGNAL | SIGEV_THREAD_ID: + rtn = find_task_by_vpid(event->sigev_notify_thread_id); + if (!rtn || !same_thread_group(rtn, current)) + return NULL; + /* FALLTHRU */ + case SIGEV_SIGNAL: + case SIGEV_THREAD: + if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) + return NULL; + /* FALLTHRU */ + case SIGEV_NONE: + return task_pid(rtn); + default: return NULL; - - if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && - ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) - return NULL; - - return task_pid(rtn); + } } static struct k_itimer * alloc_posix_timer(void) @@ -669,7 +674,7 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) struct timespec64 ts64; bool sig_none; - sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; + sig_none = timr->it_sigev_notify == SIGEV_NONE; iv = timr->it_interval; /* interval timer ? */ @@ -856,7 +861,7 @@ int common_timer_set(struct k_itimer *timr, int flags, timr->it_interval = timespec64_to_ktime(new_setting->it_interval); expires = timespec64_to_ktime(new_setting->it_value); - sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; + sigev_none = timr->it_sigev_notify == SIGEV_NONE; kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); timr->it_active = !sigev_none;
[GIT pull] timer fix for 4.15
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix which prevents arbitrary sigev_notify values in posix-timers. Thanks, tglx --> Thomas Gleixner (1): posix-timer: Properly check sigevent->sigev_notify kernel/time/posix-timers.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 13d6881f908b..ec999f32c840 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -434,17 +434,22 @@ static struct pid *good_sigevent(sigevent_t * event) { struct task_struct *rtn = current->group_leader; - if ((event->sigev_notify & SIGEV_THREAD_ID ) && - (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || -!same_thread_group(rtn, current) || -(event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) + switch (event->sigev_notify) { + case SIGEV_SIGNAL | SIGEV_THREAD_ID: + rtn = find_task_by_vpid(event->sigev_notify_thread_id); + if (!rtn || !same_thread_group(rtn, current)) + return NULL; + /* FALLTHRU */ + case SIGEV_SIGNAL: + case SIGEV_THREAD: + if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) + return NULL; + /* FALLTHRU */ + case SIGEV_NONE: + return task_pid(rtn); + default: return NULL; - - if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && - ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) - return NULL; - - return task_pid(rtn); + } } static struct k_itimer * alloc_posix_timer(void) @@ -669,7 +674,7 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) struct timespec64 ts64; bool sig_none; - sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; + sig_none = timr->it_sigev_notify == SIGEV_NONE; iv = timr->it_interval; /* interval timer ? */ @@ -856,7 +861,7 @@ int common_timer_set(struct k_itimer *timr, int flags, timr->it_interval = timespec64_to_ktime(new_setting->it_interval); expires = timespec64_to_ktime(new_setting->it_value); - sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE; + sigev_none = timr->it_sigev_notify == SIGEV_NONE; kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); timr->it_active = !sigev_none;
[GIT pull] timer fix for 4.14
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix to make the cs5535 clock event driver robust agaist spurious interrupt. Thanks, tglx --> David Kozub (1): clockevents/drivers/cs5535: Improve resilience to spurious interrupts drivers/clocksource/cs5535-clockevt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index a1df588343f2..1de8cac99a0e 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c @@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) /* Turn off the clock (and clear the event) */ disable_timer(cs5535_event_clock); - if (clockevent_state_shutdown(_clockevent)) + if (clockevent_state_detached(_clockevent) || + clockevent_state_shutdown(_clockevent)) return IRQ_HANDLED; /* Clear the counter */
[GIT pull] timer fix for 4.14
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix to make the cs5535 clock event driver robust agaist spurious interrupt. Thanks, tglx --> David Kozub (1): clockevents/drivers/cs5535: Improve resilience to spurious interrupts drivers/clocksource/cs5535-clockevt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index a1df588343f2..1de8cac99a0e 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c @@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) /* Turn off the clock (and clear the event) */ disable_timer(cs5535_event_clock); - if (clockevent_state_shutdown(_clockevent)) + if (clockevent_state_detached(_clockevent) || + clockevent_state_shutdown(_clockevent)) return IRQ_HANDLED; /* Clear the counter */
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 8fce3dc5c5d6f6301f67311fa79f333902b58cea clocksource/integrator: Fix section mismatch warning A clocksource driver section mismatch fix. Thanks, Ingo --> Arnd Bergmann (1): clocksource/integrator: Fix section mismatch warning drivers/clocksource/timer-integrator-ap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c index 2ff64d9d4fb3..62d24690ba02 100644 --- a/drivers/clocksource/timer-integrator-ap.c +++ b/drivers/clocksource/timer-integrator-ap.c @@ -36,8 +36,8 @@ static u64 notrace integrator_read_sched_clock(void) return -readl(sched_clk_base + TIMER_VALUE); } -static int integrator_clocksource_init(unsigned long inrate, - void __iomem *base) +static int __init integrator_clocksource_init(unsigned long inrate, + void __iomem *base) { u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; unsigned long rate = inrate;
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 8fce3dc5c5d6f6301f67311fa79f333902b58cea clocksource/integrator: Fix section mismatch warning A clocksource driver section mismatch fix. Thanks, Ingo --> Arnd Bergmann (1): clocksource/integrator: Fix section mismatch warning drivers/clocksource/timer-integrator-ap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c index 2ff64d9d4fb3..62d24690ba02 100644 --- a/drivers/clocksource/timer-integrator-ap.c +++ b/drivers/clocksource/timer-integrator-ap.c @@ -36,8 +36,8 @@ static u64 notrace integrator_read_sched_clock(void) return -readl(sched_clk_base + TIMER_VALUE); } -static int integrator_clocksource_init(unsigned long inrate, - void __iomem *base) +static int __init integrator_clocksource_init(unsigned long inrate, + void __iomem *base) { u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; unsigned long rate = inrate;
[GIT pull] timer fix for 4.13
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a thinko in the raw timekeeper update which causes clock MONOTONIC_RAW to run with erratically increased frequency. Thanks, tglx --> John Stultz (1): time: Fix ktime_get_raw() incorrect base accumulation kernel/time/timekeeping.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index cedafa008de5..7e7e61c00d61 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -637,9 +637,7 @@ static inline void tk_update_ktime_data(struct timekeeper *tk) tk->ktime_sec = seconds; /* Update the monotonic raw base */ - seconds = tk->raw_sec; - nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift); - tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); + tk->tkr_raw.base = ns_to_ktime(tk->raw_sec * NSEC_PER_SEC); } /* must hold timekeeper_lock */
[GIT pull] timer fix for 4.13
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a thinko in the raw timekeeper update which causes clock MONOTONIC_RAW to run with erratically increased frequency. Thanks, tglx --> John Stultz (1): time: Fix ktime_get_raw() incorrect base accumulation kernel/time/timekeeping.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index cedafa008de5..7e7e61c00d61 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -637,9 +637,7 @@ static inline void tk_update_ktime_data(struct timekeeper *tk) tk->ktime_sec = seconds; /* Update the monotonic raw base */ - seconds = tk->raw_sec; - nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift); - tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); + tk->tkr_raw.base = ns_to_ktime(tk->raw_sec * NSEC_PER_SEC); } /* must hold timekeeper_lock */
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2fe59f507a65dbd734b990a11ebc7488f6f87a24 timers: Fix excessive granularity of new timers after a nohz idle Fix a timer granularity handling race+bug, which would manifest itself by spuriously increasing timeouts of some timers (from 1 jiffy to ~500 jiffies in the worst case measured) in certain nohz states. Thanks, Ingo --> Nicholas Piggin (1): timers: Fix excessive granularity of new timers after a nohz idle kernel/time/timer.c | 50 +- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 8f5d1bf18854..f2674a056c26 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -203,6 +203,7 @@ struct timer_base { boolmigration_enabled; boolnohz_active; boolis_idle; + boolmust_forward_clk; DECLARE_BITMAP(pending_map, WHEEL_SIZE); struct hlist_head vectors[WHEEL_SIZE]; } cacheline_aligned; @@ -856,13 +857,19 @@ get_target_base(struct timer_base *base, unsigned tflags) static inline void forward_timer_base(struct timer_base *base) { - unsigned long jnow = READ_ONCE(jiffies); + unsigned long jnow; /* -* We only forward the base when it's idle and we have a delta between -* base clock and jiffies. +* We only forward the base when we are idle or have just come out of +* idle (must_forward_clk logic), and have a delta between base clock +* and jiffies. In the common case, run_timers will take care of it. */ - if (!base->is_idle || (long) (jnow - base->clk) < 2) + if (likely(!base->must_forward_clk)) + return; + + jnow = READ_ONCE(jiffies); + base->must_forward_clk = base->is_idle; + if ((long)(jnow - base->clk) < 2) return; /* @@ -938,6 +945,11 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * same array bucket then just return: */ if (timer_pending(timer)) { + /* +* The downside of this optimization is that it can result in +* larger granularity than you would get from adding a new +* timer with this expiry. +*/ if (timer->expires == expires) return 1; @@ -948,6 +960,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * dequeue/enqueue dance. */ base = lock_timer_base(timer, ); + forward_timer_base(base); clk = base->clk; idx = calc_wheel_index(expires, clk); @@ -964,6 +977,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) } } else { base = lock_timer_base(timer, ); + forward_timer_base(base); } ret = detach_if_pending(timer, base, false); @@ -991,12 +1005,10 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) raw_spin_lock(>lock); WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | base->cpu); + forward_timer_base(base); } } - /* Try to forward a stale timer base clock */ - forward_timer_base(base); - timer->expires = expires; /* * If 'idx' was calculated above and the base time did not advance @@ -1112,6 +1124,7 @@ void add_timer_on(struct timer_list *timer, int cpu) WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | cpu); } + forward_timer_base(base); debug_activate(timer, timer->expires); internal_add_timer(base, timer); @@ -1497,10 +1510,16 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) if (!is_max_delta) expires = basem + (u64)(nextevt - basej) * TICK_NSEC; /* -* If we expect to sleep more than a tick, mark the base idle: +* If we expect to sleep more than a tick, mark the base idle. +* Also the tick is stopped so any added timer must forward +* the base clk itself to keep granularity small. This idle +* logic is only maintained for the BASE_STD base, deferrable +* timers may still see large granularity skew (by design). */ - if ((expires - basem) > TICK_NSEC) + if ((expires - basem) > TICK_NSEC) { +
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2fe59f507a65dbd734b990a11ebc7488f6f87a24 timers: Fix excessive granularity of new timers after a nohz idle Fix a timer granularity handling race+bug, which would manifest itself by spuriously increasing timeouts of some timers (from 1 jiffy to ~500 jiffies in the worst case measured) in certain nohz states. Thanks, Ingo --> Nicholas Piggin (1): timers: Fix excessive granularity of new timers after a nohz idle kernel/time/timer.c | 50 +- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 8f5d1bf18854..f2674a056c26 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -203,6 +203,7 @@ struct timer_base { boolmigration_enabled; boolnohz_active; boolis_idle; + boolmust_forward_clk; DECLARE_BITMAP(pending_map, WHEEL_SIZE); struct hlist_head vectors[WHEEL_SIZE]; } cacheline_aligned; @@ -856,13 +857,19 @@ get_target_base(struct timer_base *base, unsigned tflags) static inline void forward_timer_base(struct timer_base *base) { - unsigned long jnow = READ_ONCE(jiffies); + unsigned long jnow; /* -* We only forward the base when it's idle and we have a delta between -* base clock and jiffies. +* We only forward the base when we are idle or have just come out of +* idle (must_forward_clk logic), and have a delta between base clock +* and jiffies. In the common case, run_timers will take care of it. */ - if (!base->is_idle || (long) (jnow - base->clk) < 2) + if (likely(!base->must_forward_clk)) + return; + + jnow = READ_ONCE(jiffies); + base->must_forward_clk = base->is_idle; + if ((long)(jnow - base->clk) < 2) return; /* @@ -938,6 +945,11 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * same array bucket then just return: */ if (timer_pending(timer)) { + /* +* The downside of this optimization is that it can result in +* larger granularity than you would get from adding a new +* timer with this expiry. +*/ if (timer->expires == expires) return 1; @@ -948,6 +960,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * dequeue/enqueue dance. */ base = lock_timer_base(timer, ); + forward_timer_base(base); clk = base->clk; idx = calc_wheel_index(expires, clk); @@ -964,6 +977,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) } } else { base = lock_timer_base(timer, ); + forward_timer_base(base); } ret = detach_if_pending(timer, base, false); @@ -991,12 +1005,10 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) raw_spin_lock(>lock); WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | base->cpu); + forward_timer_base(base); } } - /* Try to forward a stale timer base clock */ - forward_timer_base(base); - timer->expires = expires; /* * If 'idx' was calculated above and the base time did not advance @@ -1112,6 +1124,7 @@ void add_timer_on(struct timer_list *timer, int cpu) WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | cpu); } + forward_timer_base(base); debug_activate(timer, timer->expires); internal_add_timer(base, timer); @@ -1497,10 +1510,16 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) if (!is_max_delta) expires = basem + (u64)(nextevt - basej) * TICK_NSEC; /* -* If we expect to sleep more than a tick, mark the base idle: +* If we expect to sleep more than a tick, mark the base idle. +* Also the tick is stopped so any added timer must forward +* the base clk itself to keep granularity small. This idle +* logic is only maintained for the BASE_STD base, deferrable +* timers may still see large granularity skew (by design). */ - if ((expires - basem) > TICK_NSEC) + if ((expires - basem) > TICK_NSEC) { +
[GIT pull] timer fix for 4.13
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a multiplication overflow in the timer code on 32bit systems. Thanks, tglx --> Matija Glavinic Pecotic (1): timers: Fix overflow in get_next_timer_interrupt kernel/time/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 71ce3f4eead3..8f5d1bf18854 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1495,7 +1495,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) base->is_idle = false; } else { if (!is_max_delta) - expires = basem + (nextevt - basej) * TICK_NSEC; + expires = basem + (u64)(nextevt - basej) * TICK_NSEC; /* * If we expect to sleep more than a tick, mark the base idle: */
[GIT pull] timer fix for 4.13
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a multiplication overflow in the timer code on 32bit systems. Thanks, tglx --> Matija Glavinic Pecotic (1): timers: Fix overflow in get_next_timer_interrupt kernel/time/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 71ce3f4eead3..8f5d1bf18854 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1495,7 +1495,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) base->is_idle = false; } else { if (!is_max_delta) - expires = basem + (nextevt - basej) * TICK_NSEC; + expires = basem + (u64)(nextevt - basej) * TICK_NSEC; /* * If we expect to sleep more than a tick, mark the base idle: */
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 32f2fea6e77e64cd4045ec2d5deb879aada3b476 clocksource/drivers/timer-of: Handle of_irq_get_byname() result correctly A timer_irq_init() clocksource API robustness fix. Thanks, Ingo --> Sergei Shtylyov (1): clocksource/drivers/timer-of: Handle of_irq_get_byname() result correctly drivers/clocksource/timer-of.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c index f6e7491c873c..d509b500a7b5 100644 --- a/drivers/clocksource/timer-of.c +++ b/drivers/clocksource/timer-of.c @@ -41,8 +41,16 @@ static __init int timer_irq_init(struct device_node *np, struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); struct clock_event_device *clkevt = >clkevt; - of_irq->irq = of_irq->name ? of_irq_get_byname(np, of_irq->name): - irq_of_parse_and_map(np, of_irq->index); + if (of_irq->name) { + of_irq->irq = ret = of_irq_get_byname(np, of_irq->name); + if (ret < 0) { + pr_err("Failed to get interrupt %s for %s\n", + of_irq->name, np->full_name); + return ret; + } + } else { + of_irq->irq = irq_of_parse_and_map(np, of_irq->index); + } if (!of_irq->irq) { pr_err("Failed to map interrupt for %s\n", np->full_name); return -EINVAL;
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 32f2fea6e77e64cd4045ec2d5deb879aada3b476 clocksource/drivers/timer-of: Handle of_irq_get_byname() result correctly A timer_irq_init() clocksource API robustness fix. Thanks, Ingo --> Sergei Shtylyov (1): clocksource/drivers/timer-of: Handle of_irq_get_byname() result correctly drivers/clocksource/timer-of.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c index f6e7491c873c..d509b500a7b5 100644 --- a/drivers/clocksource/timer-of.c +++ b/drivers/clocksource/timer-of.c @@ -41,8 +41,16 @@ static __init int timer_irq_init(struct device_node *np, struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); struct clock_event_device *clkevt = >clkevt; - of_irq->irq = of_irq->name ? of_irq_get_byname(np, of_irq->name): - irq_of_parse_and_map(np, of_irq->index); + if (of_irq->name) { + of_irq->irq = ret = of_irq_get_byname(np, of_irq->name); + if (ret < 0) { + pr_err("Failed to get interrupt %s for %s\n", + of_irq->name, np->full_name); + return ret; + } + } else { + of_irq->irq = irq_of_parse_and_map(np, of_irq->index); + } if (!of_irq->irq) { pr_err("Failed to map interrupt for %s\n", np->full_name); return -EINVAL;
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: f63d947c1673930bfc5f2f9bd1073a02c179a890 clocksource/arm_arch_timer: Fix arch_timer_mem_find_best_frame() A single ARM Juno clocksource driver fix. Thanks, Ingo --> Sudeep Holla (1): clocksource/arm_arch_timer: Fix arch_timer_mem_find_best_frame() drivers/clocksource/arm_arch_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index a1fb918b8021..4bed671e490e 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1268,7 +1268,7 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem) pr_err("Unable to find a suitable frame in timer @ %pa\n", _mem->cntctlbase); - return frame; + return best_frame; } static int __init
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: f63d947c1673930bfc5f2f9bd1073a02c179a890 clocksource/arm_arch_timer: Fix arch_timer_mem_find_best_frame() A single ARM Juno clocksource driver fix. Thanks, Ingo --> Sudeep Holla (1): clocksource/arm_arch_timer: Fix arch_timer_mem_find_best_frame() drivers/clocksource/arm_arch_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index a1fb918b8021..4bed671e490e 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1268,7 +1268,7 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem) pr_err("Unable to find a suitable frame in timer @ %pa\n", _mem->cntctlbase); - return frame; + return best_frame; } static int __init
[GIT pull] timer fix for 4.11
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Just a simple revert of a new sched_clock implementation which turned out to be buggy. Thanks, tglx --> Romain Izard (1): Revert "clocksource/drivers/tcb_clksrc: Use 32 bit tcb as sched_clock" drivers/clocksource/tcb_clksrc.c | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 745844ee973e..d4ca9962a759 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -10,7 +10,6 @@ #include #include #include -#include /* @@ -57,14 +56,9 @@ static u64 tc_get_cycles(struct clocksource *cs) return (upper << 16) | lower; } -static u32 tc_get_cv32(void) -{ - return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); -} - static u64 tc_get_cycles32(struct clocksource *cs) { - return tc_get_cv32(); + return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); } static struct clocksource clksrc = { @@ -75,11 +69,6 @@ static struct clocksource clksrc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static u64 notrace tc_read_sched_clock(void) -{ - return tc_get_cv32(); -} - #ifdef CONFIG_GENERIC_CLOCKEVENTS struct tc_clkevt_device { @@ -350,9 +339,6 @@ static int __init tcb_clksrc_init(void) clksrc.read = tc_get_cycles32; /* setup ony channel 0 */ tcb_setup_single_chan(tc, best_divisor_idx); - - /* register sched_clock on chips with single 32 bit counter */ - sched_clock_register(tc_read_sched_clock, 32, divided_rate); } else { /* tclib will give us three clocks no matter what the * underlying platform supports.
[GIT pull] timer fix for 4.11
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Just a simple revert of a new sched_clock implementation which turned out to be buggy. Thanks, tglx --> Romain Izard (1): Revert "clocksource/drivers/tcb_clksrc: Use 32 bit tcb as sched_clock" drivers/clocksource/tcb_clksrc.c | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 745844ee973e..d4ca9962a759 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -10,7 +10,6 @@ #include #include #include -#include /* @@ -57,14 +56,9 @@ static u64 tc_get_cycles(struct clocksource *cs) return (upper << 16) | lower; } -static u32 tc_get_cv32(void) -{ - return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); -} - static u64 tc_get_cycles32(struct clocksource *cs) { - return tc_get_cv32(); + return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); } static struct clocksource clksrc = { @@ -75,11 +69,6 @@ static struct clocksource clksrc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static u64 notrace tc_read_sched_clock(void) -{ - return tc_get_cv32(); -} - #ifdef CONFIG_GENERIC_CLOCKEVENTS struct tc_clkevt_device { @@ -350,9 +339,6 @@ static int __init tcb_clksrc_init(void) clksrc.read = tc_get_cycles32; /* setup ony channel 0 */ tcb_setup_single_chan(tc, best_divisor_idx); - - /* register sched_clock on chips with single 32 bit counter */ - sched_clock_register(tc_read_sched_clock, 32, divided_rate); } else { /* tclib will give us three clocks no matter what the * underlying platform supports.
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: bc7c36eedb0c7004aa06c2afc3c5385adada8fa3 clocksource/exynos_mct: Clear interrupt when cpu is shut down Fix a crash in the ARM-Exynos clocksource driver, triggered by CPU hotplug operations. Thanks, Ingo --> Joonyoung Shim (1): clocksource/exynos_mct: Clear interrupt when cpu is shut down drivers/clocksource/exynos_mct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 4da1dc2278bd..670ff0f25b67 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -495,6 +495,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu) if (mct_int_type == MCT_INT_SPI) { if (evt->irq != -1) disable_irq_nosync(evt->irq); + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); } else { disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); }
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: bc7c36eedb0c7004aa06c2afc3c5385adada8fa3 clocksource/exynos_mct: Clear interrupt when cpu is shut down Fix a crash in the ARM-Exynos clocksource driver, triggered by CPU hotplug operations. Thanks, Ingo --> Joonyoung Shim (1): clocksource/exynos_mct: Clear interrupt when cpu is shut down drivers/clocksource/exynos_mct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 4da1dc2278bd..670ff0f25b67 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -495,6 +495,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu) if (mct_int_type == MCT_INT_SPI) { if (evt->irq != -1) disable_irq_nosync(evt->irq); + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); } else { disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); }
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: c9435f35ae64ee162555a82b6a3586b160093957 clocksource/drivers/moxart: Plug memory and mapping leaks ARM/MOXA SoC clocksource driver fixes. Thanks, Ingo --> Sudip Mukherjee (1): clocksource/drivers/moxart: Plug memory and mapping leaks drivers/clocksource/moxart_timer.c | 22 -- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index 2a8f4705c734..7f3430654fbd 100644 --- a/drivers/clocksource/moxart_timer.c +++ b/drivers/clocksource/moxart_timer.c @@ -161,19 +161,22 @@ static int __init moxart_timer_init(struct device_node *node) timer->base = of_iomap(node, 0); if (!timer->base) { pr_err("%s: of_iomap failed\n", node->full_name); - return -ENXIO; + ret = -ENXIO; + goto out_free; } irq = irq_of_parse_and_map(node, 0); if (irq <= 0) { pr_err("%s: irq_of_parse_and_map failed\n", node->full_name); - return -EINVAL; + ret = -EINVAL; + goto out_unmap; } clk = of_clk_get(node, 0); if (IS_ERR(clk)) { pr_err("%s: of_clk_get failed\n", node->full_name); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto out_unmap; } pclk = clk_get_rate(clk); @@ -186,7 +189,8 @@ static int __init moxart_timer_init(struct device_node *node) timer->t1_disable_val = ASPEED_TIMER1_DISABLE; } else { pr_err("%s: unknown platform\n", node->full_name); - return -EINVAL; + ret = -EINVAL; + goto out_unmap; } timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); @@ -208,14 +212,14 @@ static int __init moxart_timer_init(struct device_node *node) clocksource_mmio_readl_down); if (ret) { pr_err("%s: clocksource_mmio_init failed\n", node->full_name); - return ret; + goto out_unmap; } ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER, node->name, >clkevt); if (ret) { pr_err("%s: setup_irq failed\n", node->full_name); - return ret; + goto out_unmap; } /* Clear match registers */ @@ -241,6 +245,12 @@ static int __init moxart_timer_init(struct device_node *node) clockevents_config_and_register(>clkevt, pclk, 0x4, 0xfffe); return 0; + +out_unmap: + iounmap(timer->base); +out_free: + kfree(timer); + return ret; } CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: c9435f35ae64ee162555a82b6a3586b160093957 clocksource/drivers/moxart: Plug memory and mapping leaks ARM/MOXA SoC clocksource driver fixes. Thanks, Ingo --> Sudip Mukherjee (1): clocksource/drivers/moxart: Plug memory and mapping leaks drivers/clocksource/moxart_timer.c | 22 -- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index 2a8f4705c734..7f3430654fbd 100644 --- a/drivers/clocksource/moxart_timer.c +++ b/drivers/clocksource/moxart_timer.c @@ -161,19 +161,22 @@ static int __init moxart_timer_init(struct device_node *node) timer->base = of_iomap(node, 0); if (!timer->base) { pr_err("%s: of_iomap failed\n", node->full_name); - return -ENXIO; + ret = -ENXIO; + goto out_free; } irq = irq_of_parse_and_map(node, 0); if (irq <= 0) { pr_err("%s: irq_of_parse_and_map failed\n", node->full_name); - return -EINVAL; + ret = -EINVAL; + goto out_unmap; } clk = of_clk_get(node, 0); if (IS_ERR(clk)) { pr_err("%s: of_clk_get failed\n", node->full_name); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto out_unmap; } pclk = clk_get_rate(clk); @@ -186,7 +189,8 @@ static int __init moxart_timer_init(struct device_node *node) timer->t1_disable_val = ASPEED_TIMER1_DISABLE; } else { pr_err("%s: unknown platform\n", node->full_name); - return -EINVAL; + ret = -EINVAL; + goto out_unmap; } timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); @@ -208,14 +212,14 @@ static int __init moxart_timer_init(struct device_node *node) clocksource_mmio_readl_down); if (ret) { pr_err("%s: clocksource_mmio_init failed\n", node->full_name); - return ret; + goto out_unmap; } ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER, node->name, >clkevt); if (ret) { pr_err("%s: setup_irq failed\n", node->full_name); - return ret; + goto out_unmap; } /* Clear match registers */ @@ -241,6 +245,12 @@ static int __init moxart_timer_init(struct device_node *node) clockevents_config_and_register(>clkevt, pclk, 0x4, 0xfffe); return 0; + +out_unmap: + iounmap(timer->base); +out_free: + kfree(timer); + return ret; } CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
[GIT pull] timer fix for 4.10
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Prevent NULL pointer dereferencing in the tick broadcast code. Old bug, which got unearthed by the hotplug ordering problem. Thanks, tglx --> Thomas Gleixner (1): tick/broadcast: Prevent NULL pointer dereference kernel/time/tick-broadcast.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index f6aae7977824..d2a20e83ebae 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -871,6 +871,9 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { int cpu = smp_processor_id(); + if (!bc) + return; + /* Set it up only once ! */ if (bc->event_handler != tick_handle_oneshot_broadcast) { int was_periodic = clockevent_state_periodic(bc);
[GIT pull] timer fix for 4.10
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus Prevent NULL pointer dereferencing in the tick broadcast code. Old bug, which got unearthed by the hotplug ordering problem. Thanks, tglx --> Thomas Gleixner (1): tick/broadcast: Prevent NULL pointer dereference kernel/time/tick-broadcast.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index f6aae7977824..d2a20e83ebae 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -871,6 +871,9 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { int cpu = smp_processor_id(); + if (!bc) + return; + /* Set it up only once ! */ if (bc->event_handler != tick_handle_oneshot_broadcast) { int was_periodic = clockevent_state_periodic(bc);
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 54e23845e965898f65f76aba79fa9db76d830fa9 alarmtimer: Remove unused but set variable Remove an unused variable. Thanks, Ingo --> Tobias Klauser (1): alarmtimer: Remove unused but set variable kernel/time/alarmtimer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c3aad685bbc0..12dd190634ab 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -542,7 +542,6 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) static int alarm_timer_create(struct k_itimer *new_timer) { enum alarmtimer_type type; - struct alarm_base *base; if (!alarmtimer_get_rtcdev()) return -ENOTSUPP; @@ -551,7 +550,6 @@ static int alarm_timer_create(struct k_itimer *new_timer) return -EPERM; type = clock2alarm(new_timer->it_clock); - base = _bases[type]; alarm_init(_timer->it.alarm.alarmtimer, type, alarm_handle_timer); return 0; }
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 54e23845e965898f65f76aba79fa9db76d830fa9 alarmtimer: Remove unused but set variable Remove an unused variable. Thanks, Ingo --> Tobias Klauser (1): alarmtimer: Remove unused but set variable kernel/time/alarmtimer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c3aad685bbc0..12dd190634ab 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -542,7 +542,6 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) static int alarm_timer_create(struct k_itimer *new_timer) { enum alarmtimer_type type; - struct alarm_base *base; if (!alarmtimer_get_rtcdev()) return -ENOTSUPP; @@ -551,7 +550,6 @@ static int alarm_timer_create(struct k_itimer *new_timer) return -EPERM; type = clock2alarm(new_timer->it_clock); - base = _bases[type]; alarm_init(_timer->it.alarm.alarmtimer, type, alarm_handle_timer); return 0; }
[GIT pull] timer fix for 4.9
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a regression introduced in 4.8 which causes the trace/perf clock to return random nonsense if CONFIG_DEBUG_TIMEKEEPING is set. Thanks, tglx --> John Stultz (1): timekeeping: Fix __ktime_get_fast_ns() regression kernel/time/timekeeping.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e07fb093f819..37dec7e3db43 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -403,8 +403,11 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) tkr = tkf->base + (seq & 0x01); now = ktime_to_ns(tkr->base); - now += clocksource_delta(tkr->read(tkr->clock), -tkr->cycle_last, tkr->mask); + now += timekeeping_delta_to_ns(tkr, + clocksource_delta( + tkr->read(tkr->clock), + tkr->cycle_last, + tkr->mask)); } while (read_seqcount_retry(>seq, seq)); return now;
[GIT pull] timer fix for 4.9
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for a regression introduced in 4.8 which causes the trace/perf clock to return random nonsense if CONFIG_DEBUG_TIMEKEEPING is set. Thanks, tglx --> John Stultz (1): timekeeping: Fix __ktime_get_fast_ns() regression kernel/time/timekeeping.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e07fb093f819..37dec7e3db43 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -403,8 +403,11 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) tkr = tkf->base + (seq & 0x01); now = ktime_to_ns(tkr->base); - now += clocksource_delta(tkr->read(tkr->clock), -tkr->cycle_last, tkr->mask); + now += timekeeping_delta_to_ns(tkr, + clocksource_delta( + tkr->read(tkr->clock), + tkr->cycle_last, + tkr->mask)); } while (read_seqcount_retry(>seq, seq)); return now;
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2c13ce8f6b2f6fd9ba2f9261b1939fc0f62d1307 posix_cpu_timer: Exit early when process has been reaped A single fix for a posix CPU timers bug. Thanks, Ingo --> Alexey Dobriyan (1): posix_cpu_timer: Exit early when process has been reaped kernel/time/posix-cpu-timers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 1cafba860b08..39008d78927a 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -777,6 +777,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) timer->it.cpu.expires = 0; sample_to_timespec(timer->it_clock, timer->it.cpu.expires, >it_value); + return; } else { cpu_timer_sample_group(timer->it_clock, p, ); unlock_task_sighand(p, );
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2c13ce8f6b2f6fd9ba2f9261b1939fc0f62d1307 posix_cpu_timer: Exit early when process has been reaped A single fix for a posix CPU timers bug. Thanks, Ingo --> Alexey Dobriyan (1): posix_cpu_timer: Exit early when process has been reaped kernel/time/posix-cpu-timers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 1cafba860b08..39008d78927a 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -777,6 +777,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) timer->it.cpu.expires = 0; sample_to_timespec(timer->it_clock, timer->it.cpu.expires, >it_value); + return; } else { cpu_timer_sample_group(timer->it_clock, p, ); unlock_task_sighand(p, );
[GIT pull] timer fix for 4.7
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix for the error check wreckage we introduced in the merge window. Thanks, tglx --> John Stultz (1): time: Make settimeofday error checking work again include/linux/timekeeping.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 37dbacf84849..816b7543f81b 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -21,6 +21,9 @@ static inline int do_sys_settimeofday(const struct timespec *tv, struct timespec64 ts64; if (!tv) + return do_sys_settimeofday64(NULL, tz); + + if (!timespec_valid(tv)) return -EINVAL; ts64 = timespec_to_timespec64(*tv);
[GIT pull] timer fix for 4.7
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix for the error check wreckage we introduced in the merge window. Thanks, tglx --> John Stultz (1): time: Make settimeofday error checking work again include/linux/timekeeping.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 37dbacf84849..816b7543f81b 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -21,6 +21,9 @@ static inline int do_sys_settimeofday(const struct timespec *tv, struct timespec64 ts64; if (!tv) + return do_sys_settimeofday64(NULL, tz); + + if (!timespec_valid(tv)) return -EINVAL; ts64 = timespec_to_timespec64(*tv);
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 16eeed7e5558a3dcf30f75526a896b2632f299f9 clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test Fix a boot hang in the ARM based Tango SoC clocksource driver. Thanks, Ingo --> Daniel Lezcano (1): clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test drivers/clocksource/tango_xtal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c index 2bcecafdeaea..c407c47a3232 100644 --- a/drivers/clocksource/tango_xtal.c +++ b/drivers/clocksource/tango_xtal.c @@ -42,7 +42,7 @@ static void __init tango_clocksource_init(struct device_node *np) ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350, 32, clocksource_mmio_readl_up); - if (!ret) { + if (ret) { pr_err("%s: registration failed\n", np->full_name); return; }
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 16eeed7e5558a3dcf30f75526a896b2632f299f9 clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test Fix a boot hang in the ARM based Tango SoC clocksource driver. Thanks, Ingo --> Daniel Lezcano (1): clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test drivers/clocksource/tango_xtal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c index 2bcecafdeaea..c407c47a3232 100644 --- a/drivers/clocksource/tango_xtal.c +++ b/drivers/clocksource/tango_xtal.c @@ -42,7 +42,7 @@ static void __init tango_clocksource_init(struct device_node *np) ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350, 32, clocksource_mmio_readl_up); - if (!ret) { + if (ret) { pr_err("%s: registration failed\n", np->full_name); return; }
[GIT pull] timer fix for 4.3
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for the new hrtimer clock offset update mechanism to ensure that the boot time offset is respected. Thanks, tglx --> Thomas Gleixner (1): timekeeping: Increment clock_was_set_seq in timekeeping_init() kernel/time/timekeeping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3739ac6aa473..44d2cc0436f4 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1251,7 +1251,7 @@ void __init timekeeping_init(void) set_normalized_timespec64(, -boot.tv_sec, -boot.tv_nsec); tk_set_wall_to_mono(tk, tmp); - timekeeping_update(tk, TK_MIRROR); + timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); write_seqcount_end(_core.seq); raw_spin_unlock_irqrestore(_lock, flags); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] timer fix for 4.3
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single fix for the new hrtimer clock offset update mechanism to ensure that the boot time offset is respected. Thanks, tglx --> Thomas Gleixner (1): timekeeping: Increment clock_was_set_seq in timekeeping_init() kernel/time/timekeeping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3739ac6aa473..44d2cc0436f4 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1251,7 +1251,7 @@ void __init timekeeping_init(void) set_normalized_timespec64(, -boot.tv_sec, -boot.tv_nsec); tk_set_wall_to_mono(tk, tmp); - timekeeping_update(tk, TK_MIRROR); + timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); write_seqcount_end(_core.seq); raw_spin_unlock_irqrestore(_lock, flags); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 54d46b7fbcbd00fe4b20a27208e5909facc714e3 clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled A single clocksource driver suspend/resume fix. Thanks, Ingo --> Geert Uytterhoeven (1): clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled drivers/clocksource/sh_cmt.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index b8ff3c64cc45..c96de14036a0 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -661,6 +661,9 @@ static void sh_cmt_clocksource_suspend(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); + if (!ch->cs_enabled) + return; + sh_cmt_stop(ch, FLAG_CLOCKSOURCE); pm_genpd_syscore_poweroff(>cmt->pdev->dev); } @@ -669,6 +672,9 @@ static void sh_cmt_clocksource_resume(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); + if (!ch->cs_enabled) + return; + pm_genpd_syscore_poweron(>cmt->pdev->dev); sh_cmt_start(ch, FLAG_CLOCKSOURCE); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 54d46b7fbcbd00fe4b20a27208e5909facc714e3 clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled A single clocksource driver suspend/resume fix. Thanks, Ingo -- Geert Uytterhoeven (1): clockevents/drivers/sh_cmt: Only perform clocksource suspend/resume if enabled drivers/clocksource/sh_cmt.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index b8ff3c64cc45..c96de14036a0 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -661,6 +661,9 @@ static void sh_cmt_clocksource_suspend(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); + if (!ch-cs_enabled) + return; + sh_cmt_stop(ch, FLAG_CLOCKSOURCE); pm_genpd_syscore_poweroff(ch-cmt-pdev-dev); } @@ -669,6 +672,9 @@ static void sh_cmt_clocksource_resume(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); + if (!ch-cs_enabled) + return; + pm_genpd_syscore_poweron(ch-cmt-pdev-dev); sh_cmt_start(ch, FLAG_CLOCKSOURCE); } -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 0f44705175347ec96935d60b765b5d14ecc763bb tick: Move the export of tick_broadcast_oneshot_control to the proper place Fix for a misplaced export that can cause build failures in certain (rare) Kconfig situations. Thanks, Ingo --> Thomas Gleixner (1): tick: Move the export of tick_broadcast_oneshot_control to the proper place kernel/time/tick-broadcast.c | 1 - kernel/time/tick-common.c| 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 52b9e199b5ac..f6aae7977824 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -839,7 +839,6 @@ int __tick_broadcast_oneshot_control(enum tick_broadcast_state state) raw_spin_unlock(_broadcast_lock); return ret; } -EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control); /* * Reset the one shot broadcast for a cpu diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 55e13efff1ab..f8bf47571dda 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -363,6 +363,7 @@ int tick_broadcast_oneshot_control(enum tick_broadcast_state state) return __tick_broadcast_oneshot_control(state); } +EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control); #ifdef CONFIG_HOTPLUG_CPU /* -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 0f44705175347ec96935d60b765b5d14ecc763bb tick: Move the export of tick_broadcast_oneshot_control to the proper place Fix for a misplaced export that can cause build failures in certain (rare) Kconfig situations. Thanks, Ingo -- Thomas Gleixner (1): tick: Move the export of tick_broadcast_oneshot_control to the proper place kernel/time/tick-broadcast.c | 1 - kernel/time/tick-common.c| 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 52b9e199b5ac..f6aae7977824 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -839,7 +839,6 @@ int __tick_broadcast_oneshot_control(enum tick_broadcast_state state) raw_spin_unlock(tick_broadcast_lock); return ret; } -EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control); /* * Reset the one shot broadcast for a cpu diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 55e13efff1ab..f8bf47571dda 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -363,6 +363,7 @@ int tick_broadcast_oneshot_control(enum tick_broadcast_state state) return __tick_broadcast_oneshot_control(state); } +EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control); #ifdef CONFIG_HOTPLUG_CPU /* -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2d926c15d629a13914ce3e5f26354f6a0ac99e70 hrtimer: Fix incorrect tai offset calculation for non high-res timer systems A CLOCK_TAI early expiry fix. Thanks, Ingo --> John Stultz (1): hrtimer: Fix incorrect tai offset calculation for non high-res timer systems kernel/time/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 37e50aadd471..d8c724cda37b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -122,7 +122,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) mono = ktime_get_update_offsets_tick(_real, _boot, _tai); boot = ktime_add(mono, off_boot); xtim = ktime_add(mono, off_real); - tai = ktime_add(xtim, off_tai); + tai = ktime_add(mono, off_tai); base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 2d926c15d629a13914ce3e5f26354f6a0ac99e70 hrtimer: Fix incorrect tai offset calculation for non high-res timer systems A CLOCK_TAI early expiry fix. Thanks, Ingo -- John Stultz (1): hrtimer: Fix incorrect tai offset calculation for non high-res timer systems kernel/time/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 37e50aadd471..d8c724cda37b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -122,7 +122,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) mono = ktime_get_update_offsets_tick(off_real, off_boot, off_tai); boot = ktime_add(mono, off_boot); xtim = ktime_add(mono, off_real); - tai = ktime_add(xtim, off_tai); + tai = ktime_add(mono, off_tai); base-clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; base-clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: cab5e127eef040399902caa8e1510795583fa03a time: Revert to calling clock_was_set_delayed() while in irq context A late breaking fix from John. (The bug fixed has a hard lockup potential, but that was not observed, warnings were.) Thanks, Ingo --> John Stultz (1): time: Revert to calling clock_was_set_delayed() while in irq context kernel/time/timekeeping.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 0aa4ce8..5b40279 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1435,7 +1435,8 @@ void update_wall_time(void) out: raw_spin_unlock_irqrestore(_lock, flags); if (clock_set) - clock_was_set(); + /* Have to call _delayed version, since in irq context*/ + clock_was_set_delayed(); } /** -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: cab5e127eef040399902caa8e1510795583fa03a time: Revert to calling clock_was_set_delayed() while in irq context A late breaking fix from John. (The bug fixed has a hard lockup potential, but that was not observed, warnings were.) Thanks, Ingo -- John Stultz (1): time: Revert to calling clock_was_set_delayed() while in irq context kernel/time/timekeeping.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 0aa4ce8..5b40279 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1435,7 +1435,8 @@ void update_wall_time(void) out: raw_spin_unlock_irqrestore(timekeeper_lock, flags); if (clock_set) - clock_was_set(); + /* Have to call _delayed version, since in irq context*/ + clock_was_set_delayed(); } /** -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] timer fix for 3.14
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix: * Let the scheduler clock on Vybrid SoCs count forward. Thanks, tglx --> Stefan Agner (1): clocksource: vf_pit_timer: use complement for sched_clock reading drivers/clocksource/vf_pit_timer.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c index 02821b0..a918bc4 100644 --- a/drivers/clocksource/vf_pit_timer.c +++ b/drivers/clocksource/vf_pit_timer.c @@ -54,7 +54,7 @@ static inline void pit_irq_acknowledge(void) static u64 pit_read_sched_clock(void) { - return __raw_readl(clksrc_base + PITCVAL); + return ~__raw_readl(clksrc_base + PITCVAL); } static int __init pit_clocksource_init(unsigned long rate) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] timer fix for 3.14
Linus, please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus A single bugfix: * Let the scheduler clock on Vybrid SoCs count forward. Thanks, tglx -- Stefan Agner (1): clocksource: vf_pit_timer: use complement for sched_clock reading drivers/clocksource/vf_pit_timer.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c index 02821b0..a918bc4 100644 --- a/drivers/clocksource/vf_pit_timer.c +++ b/drivers/clocksource/vf_pit_timer.c @@ -54,7 +54,7 @@ static inline void pit_irq_acknowledge(void) static u64 pit_read_sched_clock(void) { - return __raw_readl(clksrc_base + PITCVAL); + return ~__raw_readl(clksrc_base + PITCVAL); } static int __init pit_clocksource_init(unsigned long rate) -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: e59da0aedb573a347fa501fa63d3ff5055aa1bc7 Merge branch 'clockevents/3.13-fixes' of git://git.linaro.org/people/daniel.lezcano/linux into timers/urgent It contains a crash fix for the ARM Cadence TTC clock driver. Thanks, Ingo --> Soren Brinkmann (1): clocksource: cadence_ttc: Fix mutex taken inside interrupt context drivers/clocksource/cadence_ttc_timer.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index b2bb3a4b..a92350b 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c @@ -67,11 +67,13 @@ * struct ttc_timer - This definition defines local timer structure * * @base_addr: Base address of timer + * @freq: Timer input clock frequency * @clk: Associated clock source * @clk_rate_change_nb Notifier block for clock rate changes */ struct ttc_timer { void __iomem *base_addr; + unsigned long freq; struct clk *clk; struct notifier_block clk_rate_change_nb; }; @@ -196,9 +198,8 @@ static void ttc_set_mode(enum clock_event_mode mode, switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - ttc_set_interval(timer, - DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk), - PRESCALE * HZ)); + ttc_set_interval(timer, DIV_ROUND_CLOSEST(ttce->ttc.freq, + PRESCALE * HZ)); break; case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_UNUSED: @@ -273,6 +274,8 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) return; } + ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); + ttccs->ttc.clk_rate_change_nb.notifier_call = ttc_rate_change_clocksource_cb; ttccs->ttc.clk_rate_change_nb.next = NULL; @@ -298,16 +301,14 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) __raw_writel(CNT_CNTRL_RESET, ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); - err = clocksource_register_hz(>cs, - clk_get_rate(ttccs->ttc.clk) / PRESCALE); + err = clocksource_register_hz(>cs, ttccs->ttc.freq / PRESCALE); if (WARN_ON(err)) { kfree(ttccs); return; } ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; - setup_sched_clock(ttc_sched_clock_read, 16, - clk_get_rate(ttccs->ttc.clk) / PRESCALE); + setup_sched_clock(ttc_sched_clock_read, 16, ttccs->ttc.freq / PRESCALE); } static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, @@ -334,6 +335,9 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, ndata->new_rate / PRESCALE); local_irq_restore(flags); + /* update cached frequency */ + ttc->freq = ndata->new_rate; + /* fall through */ } case PRE_RATE_CHANGE: @@ -367,6 +371,7 @@ static void __init ttc_setup_clockevent(struct clk *clk, if (clk_notifier_register(ttcce->ttc.clk, >ttc.clk_rate_change_nb)) pr_warn("Unable to register clock notifier.\n"); + ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); ttcce->ttc.base_addr = base; ttcce->ce.name = "ttc_clockevent"; @@ -396,7 +401,7 @@ static void __init ttc_setup_clockevent(struct clk *clk, } clockevents_config_and_register(>ce, - clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe); + ttcce->ttc.freq / PRESCALE, 1, 0xfffe); } /** -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: e59da0aedb573a347fa501fa63d3ff5055aa1bc7 Merge branch 'clockevents/3.13-fixes' of git://git.linaro.org/people/daniel.lezcano/linux into timers/urgent It contains a crash fix for the ARM Cadence TTC clock driver. Thanks, Ingo -- Soren Brinkmann (1): clocksource: cadence_ttc: Fix mutex taken inside interrupt context drivers/clocksource/cadence_ttc_timer.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index b2bb3a4b..a92350b 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c @@ -67,11 +67,13 @@ * struct ttc_timer - This definition defines local timer structure * * @base_addr: Base address of timer + * @freq: Timer input clock frequency * @clk: Associated clock source * @clk_rate_change_nb Notifier block for clock rate changes */ struct ttc_timer { void __iomem *base_addr; + unsigned long freq; struct clk *clk; struct notifier_block clk_rate_change_nb; }; @@ -196,9 +198,8 @@ static void ttc_set_mode(enum clock_event_mode mode, switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - ttc_set_interval(timer, - DIV_ROUND_CLOSEST(clk_get_rate(ttce-ttc.clk), - PRESCALE * HZ)); + ttc_set_interval(timer, DIV_ROUND_CLOSEST(ttce-ttc.freq, + PRESCALE * HZ)); break; case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_UNUSED: @@ -273,6 +274,8 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) return; } + ttccs-ttc.freq = clk_get_rate(ttccs-ttc.clk); + ttccs-ttc.clk_rate_change_nb.notifier_call = ttc_rate_change_clocksource_cb; ttccs-ttc.clk_rate_change_nb.next = NULL; @@ -298,16 +301,14 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) __raw_writel(CNT_CNTRL_RESET, ttccs-ttc.base_addr + TTC_CNT_CNTRL_OFFSET); - err = clocksource_register_hz(ttccs-cs, - clk_get_rate(ttccs-ttc.clk) / PRESCALE); + err = clocksource_register_hz(ttccs-cs, ttccs-ttc.freq / PRESCALE); if (WARN_ON(err)) { kfree(ttccs); return; } ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; - setup_sched_clock(ttc_sched_clock_read, 16, - clk_get_rate(ttccs-ttc.clk) / PRESCALE); + setup_sched_clock(ttc_sched_clock_read, 16, ttccs-ttc.freq / PRESCALE); } static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, @@ -334,6 +335,9 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, ndata-new_rate / PRESCALE); local_irq_restore(flags); + /* update cached frequency */ + ttc-freq = ndata-new_rate; + /* fall through */ } case PRE_RATE_CHANGE: @@ -367,6 +371,7 @@ static void __init ttc_setup_clockevent(struct clk *clk, if (clk_notifier_register(ttcce-ttc.clk, ttcce-ttc.clk_rate_change_nb)) pr_warn(Unable to register clock notifier.\n); + ttcce-ttc.freq = clk_get_rate(ttcce-ttc.clk); ttcce-ttc.base_addr = base; ttcce-ce.name = ttc_clockevent; @@ -396,7 +401,7 @@ static void __init ttc_setup_clockevent(struct clk *clk, } clockevents_config_and_register(ttcce-ce, - clk_get_rate(ttcce-ttc.clk) / PRESCALE, 1, 0xfffe); + ttcce-ttc.freq / PRESCALE, 1, 0xfffe); } /** -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 97b9410643475d6557d2517c2aff9fd2221141a9 clockevents: Sanitize ticks to nsec conversion This tree contains a clockevents regression fix for certain ARM subarchitectures. Thanks, Ingo --> Thomas Gleixner (1): clockevents: Sanitize ticks to nsec conversion kernel/time/clockevents.c | 65 --- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 38959c8..662c579 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -33,29 +33,64 @@ struct ce_unbind { int res; }; -/** - * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds - * @latch: value to convert - * @evt: pointer to clock event device descriptor - * - * Math helper, returns latch value converted to nanoseconds (bound checked) - */ -u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) +static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt, + bool ismax) { u64 clc = (u64) latch << evt->shift; + u64 rnd; if (unlikely(!evt->mult)) { evt->mult = 1; WARN_ON(1); } + rnd = (u64) evt->mult - 1; + + /* +* Upper bound sanity check. If the backwards conversion is +* not equal latch, we know that the above shift overflowed. +*/ + if ((clc >> evt->shift) != (u64)latch) + clc = ~0ULL; + + /* +* Scaled math oddities: +* +* For mult <= (1 << shift) we can safely add mult - 1 to +* prevent integer rounding loss. So the backwards conversion +* from nsec to device ticks will be correct. +* +* For mult > (1 << shift), i.e. device frequency is > 1GHz we +* need to be careful. Adding mult - 1 will result in a value +* which when converted back to device ticks can be larger +* than latch by up to (mult - 1) >> shift. For the min_delta +* calculation we still want to apply this in order to stay +* above the minimum device ticks limit. For the upper limit +* we would end up with a latch value larger than the upper +* limit of the device, so we omit the add to stay below the +* device upper boundary. +* +* Also omit the add if it would overflow the u64 boundary. +*/ + if ((~0ULL - clc > rnd) && + (!ismax || evt->mult <= (1U << evt->shift))) + clc += rnd; do_div(clc, evt->mult); - if (clc < 1000) - clc = 1000; - if (clc > KTIME_MAX) - clc = KTIME_MAX; - return clc; + /* Deltas less than 1usec are pointless noise */ + return clc > 1000 ? clc : 1000; +} + +/** + * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds + * @latch: value to convert + * @evt: pointer to clock event device descriptor + * + * Math helper, returns latch value converted to nanoseconds (bound checked) + */ +u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) +{ + return cev_delta2ns(latch, evt, false); } EXPORT_SYMBOL_GPL(clockevent_delta2ns); @@ -380,8 +415,8 @@ void clockevents_config(struct clock_event_device *dev, u32 freq) sec = 600; clockevents_calc_mult_shift(dev, freq, sec); - dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); - dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); + dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); + dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); } /** -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus # HEAD: 97b9410643475d6557d2517c2aff9fd2221141a9 clockevents: Sanitize ticks to nsec conversion This tree contains a clockevents regression fix for certain ARM subarchitectures. Thanks, Ingo -- Thomas Gleixner (1): clockevents: Sanitize ticks to nsec conversion kernel/time/clockevents.c | 65 --- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 38959c8..662c579 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -33,29 +33,64 @@ struct ce_unbind { int res; }; -/** - * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds - * @latch: value to convert - * @evt: pointer to clock event device descriptor - * - * Math helper, returns latch value converted to nanoseconds (bound checked) - */ -u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) +static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt, + bool ismax) { u64 clc = (u64) latch evt-shift; + u64 rnd; if (unlikely(!evt-mult)) { evt-mult = 1; WARN_ON(1); } + rnd = (u64) evt-mult - 1; + + /* +* Upper bound sanity check. If the backwards conversion is +* not equal latch, we know that the above shift overflowed. +*/ + if ((clc evt-shift) != (u64)latch) + clc = ~0ULL; + + /* +* Scaled math oddities: +* +* For mult = (1 shift) we can safely add mult - 1 to +* prevent integer rounding loss. So the backwards conversion +* from nsec to device ticks will be correct. +* +* For mult (1 shift), i.e. device frequency is 1GHz we +* need to be careful. Adding mult - 1 will result in a value +* which when converted back to device ticks can be larger +* than latch by up to (mult - 1) shift. For the min_delta +* calculation we still want to apply this in order to stay +* above the minimum device ticks limit. For the upper limit +* we would end up with a latch value larger than the upper +* limit of the device, so we omit the add to stay below the +* device upper boundary. +* +* Also omit the add if it would overflow the u64 boundary. +*/ + if ((~0ULL - clc rnd) + (!ismax || evt-mult = (1U evt-shift))) + clc += rnd; do_div(clc, evt-mult); - if (clc 1000) - clc = 1000; - if (clc KTIME_MAX) - clc = KTIME_MAX; - return clc; + /* Deltas less than 1usec are pointless noise */ + return clc 1000 ? clc : 1000; +} + +/** + * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds + * @latch: value to convert + * @evt: pointer to clock event device descriptor + * + * Math helper, returns latch value converted to nanoseconds (bound checked) + */ +u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) +{ + return cev_delta2ns(latch, evt, false); } EXPORT_SYMBOL_GPL(clockevent_delta2ns); @@ -380,8 +415,8 @@ void clockevents_config(struct clock_event_device *dev, u32 freq) sec = 600; clockevents_calc_mult_shift(dev, freq, sec); - dev-min_delta_ns = clockevent_delta2ns(dev-min_delta_ticks, dev); - dev-max_delta_ns = clockevent_delta2ns(dev-max_delta_ticks, dev); + dev-min_delta_ns = cev_delta2ns(dev-min_delta_ticks, dev, false); + dev-max_delta_ns = cev_delta2ns(dev-max_delta_ticks, dev, true); } /** -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus HEAD: 7bd36014460f793c19e7d6c94dab67b0afcfcb7f timekeeping: Fix HRTICK related deadlock from ntp lock changes An NTP related lockup fix. Thanks, Ingo --> John Stultz (1): timekeeping: Fix HRTICK related deadlock from ntp lock changes include/linux/timex.h | 1 + kernel/time/ntp.c | 6 ++ kernel/time/timekeeping.c | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/timex.h b/include/linux/timex.h index b3726e6..dd3edd7 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -141,6 +141,7 @@ extern int do_adjtimex(struct timex *); extern void hardpps(const struct timespec *, const struct timespec *); int read_current_timer(unsigned long *timer_val); +void ntp_notify_cmos_timer(void); /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182ul diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 8f5b3b9..bb22151 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -516,13 +516,13 @@ static void sync_cmos_clock(struct work_struct *work) schedule_delayed_work(_cmos_work, timespec_to_jiffies()); } -static void notify_cmos_timer(void) +void ntp_notify_cmos_timer(void) { schedule_delayed_work(_cmos_work, 0); } #else -static inline void notify_cmos_timer(void) { } +void ntp_notify_cmos_timer(void) { } #endif @@ -687,8 +687,6 @@ int __do_adjtimex(struct timex *txc, struct timespec *ts, s32 *time_tai) if (!(time_status & STA_NANO)) txc->time.tv_usec /= NSEC_PER_USEC; - notify_cmos_timer(); - return result; } diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 48b9fff..947ba25 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1703,6 +1703,8 @@ int do_adjtimex(struct timex *txc) write_seqcount_end(_seq); raw_spin_unlock_irqrestore(_lock, flags); + ntp_notify_cmos_timer(); + return ret; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] timer fix
Linus, Please pull the latest timers-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus HEAD: 7bd36014460f793c19e7d6c94dab67b0afcfcb7f timekeeping: Fix HRTICK related deadlock from ntp lock changes An NTP related lockup fix. Thanks, Ingo -- John Stultz (1): timekeeping: Fix HRTICK related deadlock from ntp lock changes include/linux/timex.h | 1 + kernel/time/ntp.c | 6 ++ kernel/time/timekeeping.c | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/timex.h b/include/linux/timex.h index b3726e6..dd3edd7 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -141,6 +141,7 @@ extern int do_adjtimex(struct timex *); extern void hardpps(const struct timespec *, const struct timespec *); int read_current_timer(unsigned long *timer_val); +void ntp_notify_cmos_timer(void); /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182ul diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 8f5b3b9..bb22151 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -516,13 +516,13 @@ static void sync_cmos_clock(struct work_struct *work) schedule_delayed_work(sync_cmos_work, timespec_to_jiffies(next)); } -static void notify_cmos_timer(void) +void ntp_notify_cmos_timer(void) { schedule_delayed_work(sync_cmos_work, 0); } #else -static inline void notify_cmos_timer(void) { } +void ntp_notify_cmos_timer(void) { } #endif @@ -687,8 +687,6 @@ int __do_adjtimex(struct timex *txc, struct timespec *ts, s32 *time_tai) if (!(time_status STA_NANO)) txc-time.tv_usec /= NSEC_PER_USEC; - notify_cmos_timer(); - return result; } diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 48b9fff..947ba25 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1703,6 +1703,8 @@ int do_adjtimex(struct timex *txc) write_seqcount_end(timekeeper_seq); raw_spin_unlock_irqrestore(timekeeper_lock, flags); + ntp_notify_cmos_timer(); + return ret; } -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/