aboutsummaryrefslogtreecommitdiff
path: root/kernel/sched/core.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2015-06-04 14:43:38 -0700
committerKevin Hilman <khilman@linaro.org>2015-06-04 14:43:38 -0700
commit94865bf8aa24aa359903de3c858a517243e20263 (patch)
tree950de82b3556dbab5a68a4f17aac8fb21af7c090 /kernel/sched/core.c
parent1a621b34f2a4bf8495bf801cd0024f063d561472 (diff)
parent474271f666ce974ee183057c022325b3833ecb39 (diff)
Merge tag 'v3.14.43-rt42-lno1' of git://git.linaro.org/people/anders.roxell/linux-rt into linux-linaro-lsk-v3.14-rtlsk-v3.14-15.06-rt
Linux 3.14.43-rt42 Changes since v3.14.39-rt37: - KVM: lapic: mark LAPIC timer handler as irqsafe - KVM: use simple waitqueue for vcpu->wq - hotplug: Use set_cpus_allowed_ptr() in sync_unplug_thread() - rt, nohz_full: fix nohz_full for PREEMPT_RT_FULL - kernel/irq_work: fix no_hz deadlock * tag 'v3.14.43-rt42-lno1' of git://git.linaro.org/people/anders.roxell/linux-rt: (360 commits) Linux 3.14.43-rt42 REBASE rt, nohz_full: fix nohz_full for PREEMPT_RT_FULL hotplug: Use set_cpus_allowed_ptr() in sync_unplug_thread() KVM: use simple waitqueue for vcpu->wq KVM: lapic: mark LAPIC timer handler as irqsafe kernel/irq_work: fix no_hz deadlock netpoll: guard the access to dev->npinfo with rcu_read_lock/unlock_bh() for CONFIG_PREEMPT_RT_FULL=y Revert "timers: do not raise softirq unconditionally" fs,btrfs: fix rt deadlock on extent_buffer->lock staging: Mark rtl8821ae as broken timers: Reduce future __run_timers() latency for first add to empty list timers: Reduce future __run_timers() latency for newly emptied list timers: Reduce __run_timers() latency for empty list timers: Track total number of timers in list fs/aio: simple simple work lockdep: selftest: fix warnings due to missing PREEMPT_RT conditionals thermal: Defer thermal wakups to threads locking: ww_mutex: fix ww_mutex vs self-deadlock Revert "rwsem-rt: Do not allow readers to nest" sunrpc: make svc_xprt_do_enqueue() use get_cpu_light() ...
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r--kernel/sched/core.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 883669d3e293..71c0bb1cdeb0 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -696,17 +696,34 @@ static inline bool got_nohz_idle_kick(void)
#endif /* CONFIG_NO_HZ_COMMON */
#ifdef CONFIG_NO_HZ_FULL
+
+static int ksoftirqd_running(void)
+{
+ struct task_struct *softirqd;
+
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL))
+ return 0;
+ softirqd = this_cpu_ksoftirqd();
+ if (softirqd && softirqd->on_rq)
+ return 1;
+ return 0;
+}
+
bool sched_can_stop_tick(void)
{
- struct rq *rq;
+ struct rq *rq;
- rq = this_rq();
+ rq = this_rq();
- /* Make sure rq->nr_running update is visible after the IPI */
- smp_rmb();
+ /* Make sure rq->nr_running update is visible after the IPI */
+ smp_rmb();
- /* More than one running task need preemption */
- if (rq->nr_running > 1)
+ /*
+ * More than one running task need preemption
+ *
+ * NOTE, RT: if ksoftirqd is awake, subtract it.
+ */
+ if (rq->nr_running - ksoftirqd_running() > 1)
return false;
return true;