diff options
author | Yunhong Jiang <yunhong.jiang@intel.com> | 2016-07-22 17:10:32 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@172.30.200.206> | 2016-07-22 17:10:32 +0000 |
commit | d2c75f97c709800d8263d15512f566a38b1e3e87 (patch) | |
tree | b691890d250b0eb88d1a50dd773c5d7004bf1bd0 /kernel | |
parent | b6416a8454af895fbeb0c6d1de7c1959bb643e7a (diff) | |
parent | ef4e798bc8761c401451649ed17a52e3e1c638e8 (diff) |
Merge "Add the "timers: do not raise softirq unconditionally" temporarily"
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kernel/locking/rtmutex.c | 7 | ||||
-rw-r--r-- | kernel/kernel/time/timer.c | 30 |
2 files changed, 29 insertions, 8 deletions
diff --git a/kernel/kernel/locking/rtmutex.c b/kernel/kernel/locking/rtmutex.c index 66971005c..30777e813 100644 --- a/kernel/kernel/locking/rtmutex.c +++ b/kernel/kernel/locking/rtmutex.c @@ -2058,13 +2058,6 @@ EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); */ int __sched rt_mutex_trylock(struct rt_mutex *lock) { -#ifdef CONFIG_PREEMPT_RT_FULL - if (WARN_ON(in_irq() || in_nmi())) -#else - if (WARN_ON(in_irq() || in_nmi() || in_serving_softirq())) -#endif - return 0; - return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); } EXPORT_SYMBOL_GPL(rt_mutex_trylock); diff --git a/kernel/kernel/time/timer.c b/kernel/kernel/time/timer.c index fee8682c2..76a301b24 100644 --- a/kernel/kernel/time/timer.c +++ b/kernel/kernel/time/timer.c @@ -1509,8 +1509,36 @@ static void run_timer_softirq(struct softirq_action *h) */ void run_local_timers(void) { + struct tvec_base *base = this_cpu_ptr(&tvec_bases); + hrtimer_run_queues(); - raise_softirq(TIMER_SOFTIRQ); + /* + * We can access this lockless as we are in the timer + * interrupt. If there are no timers queued, nothing to do in + * the timer softirq. + */ +#ifdef CONFIG_PREEMPT_RT_FULL + if (irq_work_needs_cpu()) { + raise_softirq(TIMER_SOFTIRQ); + return; + } + if (!spin_do_trylock(&base->lock)) { + raise_softirq(TIMER_SOFTIRQ); + return; + } +#endif + if (!base->active_timers) + goto out; + + /* Check whether the next pending timer has expired */ + if (time_before_eq(base->next_timer, jiffies)) + raise_softirq(TIMER_SOFTIRQ); +out: +#ifdef CONFIG_PREEMPT_RT_FULL + rt_spin_unlock(&base->lock); +#endif + /* The ; ensures that gcc won't complain in the !RT case */ + ; } #ifdef __ARCH_WANT_SYS_ALARM |